241 lines
10 KiB
HTML
241 lines
10 KiB
HTML
<!doctype html>
|
|
<meta charset=utf-8>
|
|
<script src="../testcommon.js"></script>
|
|
<body>
|
|
<script>
|
|
'use strict';
|
|
|
|
const pi = Math.PI;
|
|
const cos = Math.cos;
|
|
const sin = Math.sin;
|
|
const tan = Math.tan;
|
|
const sqrt = Math.sqrt;
|
|
|
|
// Help function for testing the computed offsets by the distance array.
|
|
function assert_animation_offsets(anim, dist) {
|
|
const epsilon = 0.00000001;
|
|
const frames = anim.effect.getKeyframes();
|
|
const cumDist = dist.reduce( (prev, curr) => {
|
|
prev.push(prev.length == 0 ? curr : curr + prev[prev.length - 1]);
|
|
return prev;
|
|
}, []);
|
|
|
|
const total = cumDist[cumDist.length - 1];
|
|
for (var i = 0; i < frames.length; ++i) {
|
|
assert_approx_equals(frames[i].computedOffset, cumDist[i] / total,
|
|
epsilon, 'computedOffset of frame ' + i);
|
|
}
|
|
}
|
|
|
|
function getAngleDist(rotate1, rotate2) {
|
|
function quaternion(axis, angle) {
|
|
var x = axis[0] * sin(angle/2.0);
|
|
var y = axis[1] * sin(angle/2.0);
|
|
var z = axis[2] * sin(angle/2.0);
|
|
var w = cos(angle/2.0);
|
|
return { 'x': x, 'y': y, 'z': z, 'w': w };
|
|
}
|
|
var q1 = quaternion(rotate1.axis, rotate1.angle);
|
|
var q2 = quaternion(rotate2.axis, rotate2.angle);
|
|
var dotProduct = q1.x * q2.x + q1.y * q2.y + q1.z * q2.z + q1.w * q2.w;
|
|
return 2.0 * Math.acos(dotProduct);
|
|
}
|
|
|
|
function createMatrix(elements, Is3D) {
|
|
return (Is3D ? "matrix3d" : "matrix") + "(" + elements.join() + ")";
|
|
}
|
|
|
|
test(function(t) {
|
|
var anim = addDiv(t).animate([ { transform: "none" },
|
|
{ transform: "translate(-20px)" },
|
|
{ transform: "translate(100px)" },
|
|
{ transform: "translate(50px)"} ],
|
|
{ spacing: "paced(transform)" });
|
|
assert_animation_offsets(anim, [ 0, 20, 120, 50 ]);
|
|
}, 'Test spacing on translate' );
|
|
|
|
test(function(t) {
|
|
var anim =
|
|
addDiv(t).animate([ { transform: "none" },
|
|
{ transform: "translate3d(-20px, 10px, 100px)" },
|
|
{ transform: "translate3d(100px, 200px, 50px)" },
|
|
{ transform: "translate(50px, -10px)"} ],
|
|
{ spacing: "paced(transform)" });
|
|
var dist = [ 0,
|
|
Math.sqrt(20 * 20 + 10 * 10 + 100 * 100),
|
|
Math.sqrt(120 * 120 + 190 * 190 + 50 * 50),
|
|
Math.sqrt(50 * 50 + 210 * 210 + 50 * 50) ];
|
|
assert_animation_offsets(anim, dist);
|
|
}, 'Test spacing on translate3d' );
|
|
|
|
test(function(t) {
|
|
var anim = addDiv(t).animate([ { transform: "scale(0.5)" },
|
|
{ transform: "scale(4.5)" },
|
|
{ transform: "scale(2.5)" },
|
|
{ transform: "none"} ],
|
|
{ spacing: "paced(transform)" });
|
|
assert_animation_offsets(anim, [ 0, 4.0, 2.0, 1.5 ]);
|
|
}, 'Test spacing on scale' );
|
|
|
|
test(function(t) {
|
|
var anim = addDiv(t).animate([ { transform: "scale(0.5, 0.5)" },
|
|
{ transform: "scale3d(4.5, 5.0, 2.5)" },
|
|
{ transform: "scale3d(2.5, 1.0, 2.0)" },
|
|
{ transform: "scale3d(1, 0.5, 1.0)"} ],
|
|
{ spacing:"paced(transform)" });
|
|
var dist = [ 0,
|
|
Math.sqrt(4.0 * 4.0 + 4.5 * 4.5 + 1.5 * 1.5),
|
|
Math.sqrt(2.0 * 2.0 + 4.0 * 4.0 + 0.5 * 0.5),
|
|
Math.sqrt(1.5 * 1.5 + 0.5 * 0.5 + 1.0 * 1.0) ];
|
|
assert_animation_offsets(anim, dist);
|
|
}, 'Test spacing on scale3d' );
|
|
|
|
test(function(t) {
|
|
var anim = addDiv(t).animate([ { transform: "rotate(60deg)" },
|
|
{ transform: "none" },
|
|
{ transform: "rotate(720deg)" },
|
|
{ transform: "rotate(-360deg)"} ],
|
|
{ spacing: "paced(transform)" });
|
|
assert_animation_offsets(anim, [ 0, 60, 720, 1080 ]);
|
|
}, 'Test spacing on rotate' );
|
|
|
|
test(function(t) {
|
|
var anim = addDiv(t).animate([ { transform: "rotate3d(1,0,0,60deg)" },
|
|
{ transform: "rotate3d(1,0,0,70deg)" },
|
|
{ transform: "rotate3d(0,0,1,-110deg)" },
|
|
{ transform: "rotate3d(1,0,0,219deg)"} ],
|
|
{ spacing: "paced(transform)" });
|
|
var dist = [ 0,
|
|
getAngleDist({ axis: [1,0,0], angle: 60 * pi / 180 },
|
|
{ axis: [1,0,0], angle: 70 * pi / 180 }),
|
|
getAngleDist({ axis: [0,1,0], angle: 70 * pi / 180 },
|
|
{ axis: [0,0,1], angle: -110 * pi / 180 }),
|
|
getAngleDist({ axis: [0,0,1], angle: -110 * pi / 180 },
|
|
{ axis: [1,0,0], angle: 219 * pi / 180 }) ];
|
|
assert_animation_offsets(anim, dist);
|
|
}, 'Test spacing on rotate3d' );
|
|
|
|
test(function(t) {
|
|
var anim = addDiv(t).animate([ { transform: "skew(60deg)" },
|
|
{ transform: "none" },
|
|
{ transform: "skew(-90deg)" },
|
|
{ transform: "skew(90deg)"} ],
|
|
{ spacing: "paced(transform)" });
|
|
assert_animation_offsets(anim, [ 0, 60, 90, 180 ]);
|
|
}, 'Test spacing on skew' );
|
|
|
|
test(function(t) {
|
|
var anim = addDiv(t).animate([ { transform: "skew(60deg, 30deg)" },
|
|
{ transform: "none" },
|
|
{ transform: "skew(-90deg, 60deg)" },
|
|
{ transform: "skew(90deg, 60deg)"} ],
|
|
{ spacing: "paced(transform)" });
|
|
var dist = [ 0,
|
|
sqrt(60 * 60 + 30 * 30),
|
|
sqrt(90 * 90 + 60 * 60),
|
|
sqrt(180 * 180 + 0) ];
|
|
assert_animation_offsets(anim, dist);
|
|
}, 'Test spacing on skew along both X and Y' );
|
|
|
|
test(function(t) {
|
|
// We calculate the distance of two perspective functions by converting them
|
|
// into two matrix3ds, and then do matrix decomposition to get two
|
|
// perspective vectors, so the equivalent perspective vectors are:
|
|
// perspective 1: (0, 0, -1/128, 1);
|
|
// perspective 2: (0, 0, -1/infinity = 0, 1);
|
|
// perspective 3: (0, 0, -1/1024, 1);
|
|
// perspective 4: (0, 0, -1/32, 1);
|
|
var anim = addDiv(t).animate([ { transform: "perspective(128px)" },
|
|
{ transform: "none" },
|
|
{ transform: "perspective(1024px)" },
|
|
{ transform: "perspective(32px)"} ],
|
|
{ spacing: "paced(transform)" });
|
|
assert_animation_offsets(anim,
|
|
[ 0, 1/128, 1/1024, 1/32 - 1/1024 ]);
|
|
}, 'Test spacing on perspective' );
|
|
|
|
test(function(t) {
|
|
var anim =
|
|
addDiv(t).animate([ { transform: "none" },
|
|
{ transform: "rotate(180deg) translate(0px)" },
|
|
{ transform: "rotate(180deg) translate(1000px)" },
|
|
{ transform: "rotate(360deg) translate(1000px)"} ],
|
|
{ spacing: "paced(transform)" });
|
|
var dist = [ 0,
|
|
sqrt(pi * pi + 0),
|
|
sqrt(1000 * 1000),
|
|
sqrt(pi * pi + 0) ];
|
|
assert_animation_offsets(anim, dist);
|
|
}, 'Test spacing on matched transform lists' );
|
|
|
|
test(function(t) {
|
|
// matrix1 => translate(100px, 50px), skewX(60deg).
|
|
// matrix2 => translate(1000px), rotate(180deg).
|
|
// matrix3 => translate(1000px), scale(1.5, 0.7).
|
|
const matrix1 = createMatrix([ 1, 0, tan(pi/4.0), 1, 100, 50 ]);
|
|
const matrix2 = createMatrix([ cos(pi), sin(pi),
|
|
-sin(pi), cos(pi),
|
|
1000, 0 ]);
|
|
const matrix3 = createMatrix([ 1.5, 0, 0, 0.7, 1000, 0 ]);
|
|
var anim = addDiv(t).animate([ { transform: "none" },
|
|
{ transform: matrix1 },
|
|
{ transform: matrix2 },
|
|
{ transform: matrix3 } ],
|
|
{ spacing: "paced(transform)" });
|
|
var dist = [ 0,
|
|
sqrt(100 * 100 + 50 * 50 + pi/4 * pi/4),
|
|
sqrt(900 * 900 + 50 * 50 + pi * pi + pi/4 * pi/4),
|
|
sqrt(pi * pi + 0.5 * 0.5 + 0.3 * 0.3) ];
|
|
assert_animation_offsets(anim, dist);
|
|
}, 'Test spacing on matrix' );
|
|
|
|
test(function(t) {
|
|
// matrix1 => translate3d(100px, 50px, -10px), skew(60deg).
|
|
// matrix2 => translate3d(1000px, 0, 0), rotate3d(1, 0, 0, 180deg).
|
|
// matrix3 => translate3d(1000px, 0, 0), scale3d(1.5, 0.7, 2.2).
|
|
const matrix1 = createMatrix([ 1, 0, 0, 0,
|
|
tan(pi/4.0), 1, 0, 0,
|
|
0, 0, 1, 0,
|
|
100, 50, -10, 1 ], true);
|
|
const matrix2 = createMatrix([ 1, 0, 0, 0,
|
|
0, cos(pi), sin(pi), 0,
|
|
0, -sin(pi), cos(pi), 0,
|
|
1000, 0, 0, 1 ], true);
|
|
const matrix3 = createMatrix([ 1.5, 0, 0, 0,
|
|
0, 0.7, 0, 0,
|
|
0, 0, 2.2, 0,
|
|
1000, 0, 0, 1 ], true);
|
|
var anim = addDiv(t).animate([ { transform: "none" },
|
|
{ transform: matrix1 },
|
|
{ transform: matrix2 },
|
|
{ transform: matrix3 } ],
|
|
{ spacing: "paced(transform)" });
|
|
var dist = [ 0,
|
|
sqrt(100 * 100 + 50 * 50 + 10 * 10 + pi/4 * pi/4),
|
|
sqrt(900 * 900 + 50 * 50 + 10 * 10 + pi/4 * pi/4 + pi * pi),
|
|
sqrt(0.5 * 0.5 + 0.3 * 0.3 + 1.2 * 1.2 + pi * pi) ];
|
|
assert_animation_offsets(anim, dist);
|
|
}, 'Test spacing on matrix3d' );
|
|
|
|
test(function(t) {
|
|
var anim =
|
|
addDiv(t).animate([ { transform: "none" },
|
|
{ transform: "translate(100px, 50px) skew(45deg)" },
|
|
{ transform: "translate(1000px) " +
|
|
"rotate3d(1, 0, 0, 180deg)" },
|
|
{ transform: "translate(1000px) " +
|
|
"scale3d(2.5, 0.5, 0.7)" } ],
|
|
{ spacing: "paced(transform)" });
|
|
|
|
var dist = [ 0,
|
|
sqrt(100 * 100 + 50 * 50 + pi/4 * pi/4),
|
|
sqrt(900 * 900 + 50 * 50 + pi/4 * pi/4 + pi * pi),
|
|
sqrt(1.5 * 1.5 + 0.5 * 0.5 + 0.3 * 0.3 + pi * pi) ];
|
|
assert_animation_offsets(anim, dist);
|
|
}, 'Test spacing on mismatched transform list' );
|
|
|
|
done();
|
|
|
|
</script>
|
|
</body>
|