mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-26 17:55:07 +02:00
LibWeb: Import some css-transforms interpolation tests
This commit is contained in:
committed by
Jelle Raaijmakers
parent
3c8546fbf2
commit
42292a9983
Notes:
github-actions[bot]
2026-01-13 08:37:47 +00:00
Author: https://github.com/tcl3 Commit: https://github.com/LadybirdBrowser/ladybird/commit/42292a99839 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/7448 Reviewed-by: https://github.com/gmta ✅
@@ -0,0 +1,208 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Transform list interpolation</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-transforms-1/#interpolation-of-transforms">
|
||||
<meta name="assert" content="Interpolation of transform function lists is performed as follows">
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<script src="../../../css/support/interpolation-testcommon.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
test_interpolation(
|
||||
{
|
||||
property: 'transform',
|
||||
from: 'none',
|
||||
to: 'none',
|
||||
},
|
||||
[{ at: 0.25, expect: 'none' }],
|
||||
'none -> none'
|
||||
);
|
||||
|
||||
test_interpolation(
|
||||
{
|
||||
property: 'transform',
|
||||
from: 'none',
|
||||
to: 'translate(200px) rotate(720deg)',
|
||||
},
|
||||
[{ at: 0.25, expect: 'translate(50px) rotate(180deg)' }],
|
||||
'none -> something'
|
||||
);
|
||||
|
||||
test_interpolation(
|
||||
{
|
||||
property: 'transform',
|
||||
from: 'translate(200px) rotate(720deg)',
|
||||
to: 'none',
|
||||
},
|
||||
[{ at: 0.25, expect: 'translate(150px) rotate(540deg)' }],
|
||||
'something -> none'
|
||||
);
|
||||
|
||||
test_interpolation(
|
||||
{
|
||||
property: 'transform',
|
||||
from: 'translate(100px)',
|
||||
to: 'translate(200px) rotate(720deg)',
|
||||
},
|
||||
[{ at: 0.25, expect: 'translate(125px) rotate(180deg)' }],
|
||||
'Mismatched lengths (from is shorter), common part matches'
|
||||
);
|
||||
|
||||
test_interpolation(
|
||||
{
|
||||
property: 'transform',
|
||||
from: 'translate(100px) rotate(720deg)',
|
||||
to: 'translate(200px)',
|
||||
},
|
||||
[{ at: 0.25, expect: 'translate(125px) rotate(540deg)' }],
|
||||
'Mismatched lengths (to is shorter), common part matches'
|
||||
);
|
||||
|
||||
test_interpolation(
|
||||
{
|
||||
property: 'transform',
|
||||
from: 'scale(2) rotate(360deg) translate(100px) matrix(1, 0, 0, 1, 100, 0) skew(0deg)',
|
||||
to: 'scale(3) rotate(1080deg) translate(200px) matrix(1, 0, 0, 1, 0, 200) skew(720deg)',
|
||||
},
|
||||
[
|
||||
{
|
||||
at: 0.25,
|
||||
expect: 'scale(2.25) rotate(540deg) translate(125px) matrix(1, 0, 0, 1, 75, 50) skew(180deg)',
|
||||
},
|
||||
],
|
||||
'Perfect match'
|
||||
);
|
||||
|
||||
test_interpolation(
|
||||
{
|
||||
property: 'transform',
|
||||
from: 'translateX(100px) scaleX(3) translate(500px) scale(2)',
|
||||
to: 'translateY(200px) scale(5) translateX(100px) scaleY(3)',
|
||||
},
|
||||
[{ at: 0.25, expect: 'translate(75px, 50px) scale(3.5, 2) translate(400px, 0px) scale(1.75, 2.25)' }],
|
||||
'Matches on primitives'
|
||||
);
|
||||
|
||||
test_interpolation(
|
||||
{
|
||||
property: 'transform',
|
||||
from: 'rotateX(90deg) translateX(100px)',
|
||||
to: 'rotate3d(50, 0, 0, 180deg) translateY(200px)',
|
||||
},
|
||||
[{ at: 0.25, expect: 'rotateX(112.5deg) translate(75px, 50px)' }],
|
||||
'Match on rotation vector'
|
||||
);
|
||||
|
||||
test_interpolation(
|
||||
{
|
||||
property: 'transform',
|
||||
from: 'rotateX(90deg) translateX(100px)',
|
||||
to: 'rotateY(0deg) translateY(200px)',
|
||||
},
|
||||
[{ at: 0.25, expect: 'rotateX(67.5deg) translate(75px, 50px)' }],
|
||||
'Match on rotation due to 0deg angle'
|
||||
);
|
||||
|
||||
test_interpolation(
|
||||
{
|
||||
property: 'transform',
|
||||
from: 'rotate3d(1, 1, 1, -60deg) translateX(100px)',
|
||||
to: 'rotate3d(2, 2, 2, 60deg) translateY(200px)',
|
||||
}, [{ at: 0.25, expect: 'rotate3d(1, 1, 1, -30deg) translate(75px, 50px)' }],
|
||||
'Match on rotation using collinear rotation axes'
|
||||
);
|
||||
|
||||
test_interpolation(
|
||||
{
|
||||
property: 'transform',
|
||||
from: 'rotate3d(1, 0, 0, 360deg) translateX(100px)',
|
||||
to: 'rotate3d(0, 1, 0, -720deg) translateY(200px)',
|
||||
}, [{ at: 0.25, expect: 'rotate3d(0, 0, 1, 0deg) translate(75px, 50px)' }],
|
||||
'Match on rotation with spherical interpolation'
|
||||
);
|
||||
|
||||
test_interpolation(
|
||||
{
|
||||
property: 'transform',
|
||||
from: 'rotate(0deg) translate(100px)',
|
||||
to: 'rotate(720deg) scale(2) translate(200px)',
|
||||
},
|
||||
[{ at: 0.25, expect: 'rotate(180deg) matrix(1.25, 0, 0, 1.25, 175, 0)' }],
|
||||
'Common prefix'
|
||||
);
|
||||
|
||||
test_interpolation(
|
||||
{
|
||||
property: 'transform',
|
||||
from: 'scale(2) rotate(0deg) translate(100px)',
|
||||
to: 'rotate(720deg) scale(2) translate(200px)',
|
||||
},
|
||||
[{ at: 0.25, expect: 'matrix(2, 0, 0, 2, 250, 0)' }],
|
||||
'Complete mismatch (except length)'
|
||||
);
|
||||
|
||||
test_interpolation(
|
||||
{
|
||||
property: 'transform',
|
||||
from: 'scale(2) rotate(0deg)',
|
||||
to: 'rotate(720deg) scale(2) translate(200px)',
|
||||
},
|
||||
[{ at: 0.25, expect: 'matrix(2, 0, 0, 2, 100, 0)' }],
|
||||
'Complete mismatch including length'
|
||||
);
|
||||
|
||||
test_interpolation(
|
||||
{
|
||||
property: 'transform',
|
||||
from: 'rotate(0deg) scaleX(1)',
|
||||
to: 'rotate(720deg) translateX(0px) scaleX(2)'
|
||||
},
|
||||
[{at: 0.25, expect: 'rotate(180deg) matrix(1.25, 0, 0, 1, 0, 0)'}],
|
||||
'Mismatched lengths (from is shorter), partial match'
|
||||
);
|
||||
|
||||
test_interpolation(
|
||||
{
|
||||
property: 'transform',
|
||||
from: 'rotate(720deg) translateX(0px) scaleX(2)',
|
||||
to: 'rotate(0deg) scaleX(1)'
|
||||
},
|
||||
[{at: 0.25, expect: 'rotate(540deg) matrix(1.75, 0, 0, 1, 0, 0)'}],
|
||||
'Mismatched lengths (to is shorter), partial match'
|
||||
);
|
||||
|
||||
test_interpolation(
|
||||
{
|
||||
property: 'transform',
|
||||
from: 'scaleX(-3) scaleY(2)',
|
||||
to: 'scaleY(-3) translateX(0px) scaleX(2)'
|
||||
},
|
||||
[{at: 0.25, expect: 'scale(-2, 0) matrix(1.25, 0, 0, 1.75, 0, 0)'}],
|
||||
'Mismatched lengths (from is shorter), partial match on primitive'
|
||||
);
|
||||
|
||||
test_interpolation(
|
||||
{
|
||||
property: 'transform',
|
||||
from: 'scaleY(-3) translateX(0px) scaleX(2)',
|
||||
to: 'scaleX(-3) scaleY(2)'
|
||||
},
|
||||
[{at: 0.25, expect: 'scale(0, -2) matrix(1.75, 0, 0, 1.25, 0, 0)'}],
|
||||
'Mismatched lengths (to is shorter), partial match on primitive'
|
||||
);
|
||||
|
||||
test_interpolation(
|
||||
{
|
||||
property: 'transform',
|
||||
from: 'scaleY(-3) translateX(0px)',
|
||||
to: 'scaleX(-3) scaleY(2)'
|
||||
},
|
||||
[{at: 0.25, expect: 'scale(0, -2) matrix(1, 0, 0, 1.25, 0, 0)'}],
|
||||
'Common prefix on primitive'
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,36 @@
|
||||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>Matrix interpolation</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#interpolation-of-3d-matrices">
|
||||
<meta name="assert" content="When interpolating between two matrices, each matrix is decomposed into the corresponding translation, rotation, scale, skew and (for a 3D matrix) perspective values">
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<script src="../../../css/support/interpolation-testcommon.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
// Test interpolation of quaternions when the dot product is -1.
|
||||
//
|
||||
// We need to be particularly careful not to use a rotate function with a zero
|
||||
// angle since the handling of zero angle rotations may change in future as per:
|
||||
//
|
||||
// https://github.com/w3c/csswg-drafts/issues/3236
|
||||
//
|
||||
// For rotateY(360deg) we should get a quaternion of:
|
||||
// [ 0, sin(2 * PI / 2), 0, cos(2 * PI / 2) ]
|
||||
// = [ 0, 0, 0, -1 ]
|
||||
//
|
||||
// For rotateX(720deg) we should get a quaternion of:
|
||||
// [ 0, 0, sin(4 * PI / 2), cos(4 * PI / 2) ]
|
||||
// = [ 0, 0, 0, 1 ]
|
||||
//
|
||||
// Dot product = 0 * 0 + 0 * 0 + 0 * 0 + 1 * -1 = -1
|
||||
test_interpolation(
|
||||
{
|
||||
property: 'transform',
|
||||
from: 'rotateY(360deg)',
|
||||
to: 'rotateX(720deg)',
|
||||
},
|
||||
[{ at: 0.5, expect: 'matrix(1, 0, 0, 1, 0, 0)' }]
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
@@ -0,0 +1,325 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="UTF-8">
|
||||
<title>transform interpolation</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-transforms/#transform-property">
|
||||
<meta name="assert" content="transform supports animation as a transform list">
|
||||
<meta name="timeout" content="long">
|
||||
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<script src="../../../css/support/interpolation-testcommon.js"></script>
|
||||
|
||||
<style>
|
||||
.target {
|
||||
color: white;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: black;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
}
|
||||
.expected {
|
||||
background-color: green;
|
||||
}
|
||||
.target > div {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
display: inline-block;
|
||||
background: orange;
|
||||
margin: 1px;
|
||||
}
|
||||
.test {
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<template id="target-template">
|
||||
<div></div>
|
||||
</template>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
|
||||
// The default comparison function calls normalizeValue, which rounds
|
||||
// everything to two decimal places, which isn't OK for the matrices
|
||||
// that result from large perspective values.
|
||||
const compareWithPerspective = (actual, expected) => {
|
||||
// TODO: This RegExp should be more precise to capture only what is a
|
||||
// valid float, and this code should be merged with other code doing
|
||||
// the same thing, e.g., RoundMatrix in
|
||||
// web-animations/animation-model/animation-types/property-list.js .
|
||||
const matrixRegExp = /^matrix3d\(((?:(?:[-0-9.e]+), ){15}(?:[-0-9.]+))\)$/;
|
||||
const actualMatch = actual.match(matrixRegExp);
|
||||
const expectedMatch = expected.match(matrixRegExp);
|
||||
assert_not_equals(actualMatch, null, `${actual} should be a matrix`);
|
||||
assert_not_equals(expectedMatch, null, `${expected} should be a matrix`);
|
||||
if (actualMatch === null || expectedMatch === null) {
|
||||
return;
|
||||
}
|
||||
const actualArray = actualMatch[1].split(", ").map(Number);
|
||||
const expectedArray = expectedMatch[1].split(", ").map(Number);
|
||||
assert_equals(actualArray.length, 16);
|
||||
assert_equals(expectedArray.length, 16);
|
||||
|
||||
if (actualArray.length != expectedArray.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i in actualArray) {
|
||||
const error = Math.abs((actualArray[i] - expectedArray[i])) /
|
||||
Math.max(1e-6,
|
||||
Math.min(Math.abs(expectedArray[i]),
|
||||
Math.abs(actualArray[i])));
|
||||
assert_less_than(error, 1e-5, `comparing (at index ${i} actual value "${actual}" [${actualArray[i]}] and expected value "${expected}" [${expectedArray[i]}]`);
|
||||
}
|
||||
};
|
||||
|
||||
// The spec at
|
||||
// https://drafts.csswg.org/css-transforms-2/#interpolation-of-transform-functions
|
||||
// requires that perspective be interpolated by decomposing the matrix
|
||||
// (which is trivial for perspective) and then interpolating the pieces.
|
||||
// The piece that's interpolated (the z part of the perspective array)
|
||||
// contains the negative reciprocal of the argument to perspective().
|
||||
const interpolatePerspective = (from, to, progress) => {
|
||||
return 1.0/((1.0 - progress) * (1.0/from) + progress * (1.0/to));
|
||||
};
|
||||
|
||||
// Perspective
|
||||
test_interpolation({
|
||||
property: 'transform',
|
||||
from: 'perspective(400px)',
|
||||
to: 'perspective(500px)',
|
||||
comparisonFunction: compareWithPerspective
|
||||
}, [
|
||||
{at: -1, expect: `perspective(${interpolatePerspective(400, 500, -1)}px)`},
|
||||
{at: 0, expect: `perspective(${interpolatePerspective(400, 500, 0)}px)`},
|
||||
{at: 0.25, expect: `perspective(${interpolatePerspective(400, 500, 0.25)}px)`},
|
||||
{at: 0.75, expect: `perspective(${interpolatePerspective(400, 500, 0.75)}px)`},
|
||||
{at: 1, expect: `perspective(${interpolatePerspective(400, 500, 1)}px)`},
|
||||
{at: 2, expect: `perspective(${interpolatePerspective(400, 500, 2)}px)`},
|
||||
]);
|
||||
test_interpolation({
|
||||
property: 'transform',
|
||||
from: 'skewX(10rad) perspective(400px)',
|
||||
to: 'skewX(20rad) perspective(500px)',
|
||||
comparisonFunction: compareWithPerspective
|
||||
}, [
|
||||
{at: -1, expect: `skewX(0rad) perspective(${interpolatePerspective(400, 500, -1)}px)`},
|
||||
{at: 0, expect: `skewX(10rad) perspective(${interpolatePerspective(400, 500, 0)}px)`},
|
||||
{at: 0.25, expect: `skewX(12.5rad) perspective(${interpolatePerspective(400, 500, 0.25)}px)`},
|
||||
{at: 0.75, expect: `skewX(17.5rad) perspective(${interpolatePerspective(400, 500, 0.75)}px)`},
|
||||
{at: 1, expect: `skewX(20rad) perspective(${interpolatePerspective(400, 500, 1)}px)`},
|
||||
{at: 2, expect: `skewX(30rad) perspective(${interpolatePerspective(400, 500, 2)}px)`},
|
||||
]);
|
||||
test_interpolation({
|
||||
property: 'transform',
|
||||
from: 'scaleZ(1) perspective(400px)',
|
||||
to: 'scaleZ(2) perspective(500px)',
|
||||
comparisonFunction: compareWithPerspective
|
||||
}, [
|
||||
{at: -1, expect: `scaleZ(0) perspective(${interpolatePerspective(400, 500, -1)}px)`},
|
||||
{at: 0, expect: `scaleZ(1.0) perspective(${interpolatePerspective(400, 500, 0)}px)`},
|
||||
{at: 0.25, expect: `scaleZ(1.25) perspective(${interpolatePerspective(400, 500, 0.25)}px)`},
|
||||
{at: 0.75, expect: `scaleZ(1.75) perspective(${interpolatePerspective(400, 500, 0.75)}px)`},
|
||||
{at: 1, expect: `scaleZ(2) perspective(${interpolatePerspective(400, 500, 1)}px)`},
|
||||
{at: 2, expect: `scaleZ(3) perspective(${interpolatePerspective(400, 500, 2)}px)`},
|
||||
]);
|
||||
// Test that the transform identity function for perspective is perspective(none)
|
||||
test_interpolation({
|
||||
property: 'transform',
|
||||
from: 'scaleZ(2)',
|
||||
to: 'scaleZ(2) perspective(500px)',
|
||||
comparisonFunction: compareWithPerspective
|
||||
}, [
|
||||
{at: -1, expect: `scaleZ(2)`},
|
||||
{at: 0, expect: `scaleZ(2)`},
|
||||
{at: 0.5, expect: `scaleZ(2) perspective(1000px)`},
|
||||
{at: 1, expect: `scaleZ(2) perspective(500px)`},
|
||||
{at: 2, expect: `scaleZ(2) perspective(250px)`},
|
||||
]);
|
||||
test_interpolation({
|
||||
property: 'transform',
|
||||
from: 'perspective(none)',
|
||||
to: 'perspective(500px)',
|
||||
}, [
|
||||
{at: -1, expect: `perspective(none)`},
|
||||
{at: 0, expect: `perspective(none)`},
|
||||
{at: 0.5, expect: `perspective(1000px)`},
|
||||
{at: 1, expect: `perspective(500px)`},
|
||||
{at: 2, expect: `perspective(250px)`},
|
||||
]);
|
||||
|
||||
// Rotate
|
||||
test_interpolation({
|
||||
property: 'transform',
|
||||
from: 'rotate(30deg)',
|
||||
to: 'rotate(330deg)'
|
||||
}, [
|
||||
{at: -1, expect: 'rotate(-270deg)'},
|
||||
{at: 0, expect: 'rotate(30deg)'},
|
||||
{at: 0.25, expect: 'rotate(105deg)'},
|
||||
{at: 0.75, expect: 'rotate(255deg)'},
|
||||
{at: 1, expect: 'rotate(330deg)'},
|
||||
{at: 2, expect: 'rotate(630deg)'},
|
||||
]);
|
||||
test_interpolation({
|
||||
property: 'transform',
|
||||
from: 'rotateX(0deg)',
|
||||
to: 'rotateX(700deg)'
|
||||
}, [
|
||||
{at: -1, expect: 'rotateX(-700deg)'},
|
||||
{at: 0, expect: 'rotateX(0deg)'},
|
||||
{at: 0.25, expect: 'rotateX(175deg)'},
|
||||
{at: 0.75, expect: 'rotateX(525deg)'},
|
||||
{at: 1, expect: 'rotateX(700deg)'},
|
||||
{at: 2, expect: 'rotateX(1400deg)'},
|
||||
]);
|
||||
test_interpolation({
|
||||
property: 'transform',
|
||||
from: 'rotateY(0deg)',
|
||||
to: 'rotateY(800deg)'
|
||||
}, [
|
||||
{at: -1, expect: 'rotateY(-800deg)'},
|
||||
{at: 0, expect: 'rotateY(0deg)'},
|
||||
{at: 0.25, expect: 'rotateY(200deg)'},
|
||||
{at: 0.75, expect: 'rotateY(600deg)'},
|
||||
{at: 1, expect: 'rotateY(800deg)'},
|
||||
{at: 2, expect: 'rotateY(1600deg)'},
|
||||
]);
|
||||
test_interpolation({
|
||||
property: 'transform',
|
||||
from: 'rotateZ(0deg)',
|
||||
to: 'rotateZ(900deg)'
|
||||
}, [
|
||||
{at: -1, expect: 'rotateZ(-900deg)'},
|
||||
{at: 0, expect: 'rotateZ(0deg)'},
|
||||
{at: 0.25, expect: 'rotateZ(225deg)'},
|
||||
{at: 0.75, expect: 'rotateZ(675deg)'},
|
||||
{at: 1, expect: 'rotateZ(900deg)'},
|
||||
{at: 2, expect: 'rotateZ(1800deg)'},
|
||||
]);
|
||||
// Interpolation is about a common axis if either endpoint has a rotation angle
|
||||
// of zero.
|
||||
test_interpolation({
|
||||
property: 'transform',
|
||||
from: 'rotateX(0deg)',
|
||||
to: 'rotateY(900deg)'
|
||||
}, [
|
||||
{at: -1, expect: 'rotateY(-900deg)'},
|
||||
{at: 0, expect: 'rotateY(0deg)'},
|
||||
{at: 0.25, expect: 'rotateY(225deg)'},
|
||||
{at: 0.75, expect: 'rotateY(675deg)'},
|
||||
{at: 1, expect: 'rotateY(900deg)'},
|
||||
{at: 2, expect: 'rotateY(1800deg)'},
|
||||
]);
|
||||
test_interpolation({
|
||||
property: 'transform',
|
||||
from: 'rotateY(900deg)',
|
||||
to: 'rotateZ(0deg)'
|
||||
}, [
|
||||
{at: -1, expect: 'rotateY(1800deg)'},
|
||||
{at: 0, expect: 'rotateY(900deg)'},
|
||||
{at: 0.25, expect: 'rotateY(675deg)'},
|
||||
{at: 0.75, expect: 'rotateY(225deg)'},
|
||||
{at: 1, expect: 'rotateY(0deg)'},
|
||||
{at: 2, expect: 'rotateY(-900deg)'},
|
||||
]);
|
||||
test_interpolation({
|
||||
property: 'transform',
|
||||
from: 'rotate3d(7, 8, 9, 100deg)',
|
||||
to: 'rotate3d(7, 8, 9, 260deg)'
|
||||
}, [
|
||||
{at: -1, expect: 'rotate3d(7, 8, 9, -60deg)'},
|
||||
{at: 0, expect: 'rotate3d(7, 8, 9, 100deg)'},
|
||||
{at: 0.25, expect: 'rotate3d(7, 8, 9, 140deg)'},
|
||||
{at: 0.75, expect: 'rotate3d(7, 8, 9, 220deg)'},
|
||||
{at: 1, expect: 'rotate3d(7, 8, 9, 260deg)'},
|
||||
{at: 2, expect: 'rotate3d(7, 8, 9, 420deg)'},
|
||||
]);
|
||||
test_interpolation({
|
||||
property: 'transform',
|
||||
from: 'rotate3d(7, 8, 9, 0deg)',
|
||||
to: 'rotate3d(7, 8, 9, 450deg)'
|
||||
}, [
|
||||
{at: -1, expect: 'rotate3d(7, 8, 9, -450deg)'},
|
||||
{at: 0, expect: 'rotate3d(7, 8, 9, 0deg)'},
|
||||
{at: 0.25, expect: 'rotate3d(7, 8, 9, 112.5deg)'},
|
||||
{at: 0.75, expect: 'rotate3d(7, 8, 9, 337.5deg)'},
|
||||
{at: 1, expect: 'rotate3d(7, 8, 9, 450deg)'},
|
||||
{at: 2, expect: 'rotate3d(7, 8, 9, 900deg)'},
|
||||
]);
|
||||
test_interpolation({
|
||||
property: 'transform',
|
||||
from: 'rotate3d(0, 1, 0, 0deg)',
|
||||
to: 'rotate3d(0, 1, 0, 450deg)'
|
||||
}, [
|
||||
{at: -1, expect: 'rotate3d(0, 1, 0, -450deg)'},
|
||||
{at: 0, expect: 'rotate3d(0, 1, 0, 0deg)'},
|
||||
{at: 0.25, expect: 'rotate3d(0, 1, 0, 112.5deg)'},
|
||||
{at: 0.75, expect: 'rotate3d(0, 1, 0, 337.5deg)'},
|
||||
{at: 1, expect: 'rotate3d(0, 1, 0, 450deg)'},
|
||||
{at: 2, expect: 'rotate3d(0, 1, 0, 900deg)'},
|
||||
]);
|
||||
// Rotation is about a common axis if the axes are colinear.
|
||||
test_interpolation({
|
||||
property: 'transform',
|
||||
from: 'rotate3d(0, 1, 0, 0deg)',
|
||||
to: 'rotate3d(0, 2, 0, 450deg)'
|
||||
}, [
|
||||
{at: -1, expect: 'rotate3d(0, 1, 0, -450deg)'},
|
||||
{at: 0, expect: 'rotate3d(0, 1, 0, 0deg)'},
|
||||
{at: 0.25, expect: 'rotate3d(0, 1, 0, 112.5deg)'},
|
||||
{at: 0.75, expect: 'rotate3d(0, 1, 0, 337.5deg)'},
|
||||
{at: 1, expect: 'rotate3d(0, 1, 0, 450deg)'},
|
||||
{at: 2, expect: 'rotate3d(0, 1, 0, 900deg)'},
|
||||
]);
|
||||
test_interpolation({
|
||||
property: 'transform',
|
||||
from: 'rotate3d(1, 1, 0, 90deg)',
|
||||
to: 'rotate3d(0, 1, 1, 180deg)'
|
||||
}, [
|
||||
{at: -1, expect: 'rotate3d(0.41, -0.41, -0.82, 120deg)'},
|
||||
{at: 0, expect: 'rotate3d(1, 1, 0, 90deg)'},
|
||||
{at: 0.25, expect: 'rotate3d(0.524083, 0.804261, 0.280178, 106.91deg)'},
|
||||
{at: 0.75, expect: 'rotate3d(0.163027, 0.774382, 0.611354, 153.99deg)'},
|
||||
{at: 1, expect: 'rotate3d(0, 1, 1, 180deg)'},
|
||||
{at: 2, expect: 'rotate3d(0.71, 0, -0.71, 90deg)'},
|
||||
]);
|
||||
test_interpolation({
|
||||
property: 'transform',
|
||||
from: 'none',
|
||||
to: 'rotate(90deg)'
|
||||
}, [
|
||||
{at: -1, expect: 'rotate(-90deg)'},
|
||||
{at: 0, expect: 'rotate(0deg)'},
|
||||
{at: 0.25, expect: 'rotate(22.5deg)'},
|
||||
{at: 0.75, expect: 'rotate(67.5deg)'},
|
||||
{at: 1, expect: 'rotate(90deg)'},
|
||||
{at: 2, expect: 'rotate(180deg)'},
|
||||
]);
|
||||
test_interpolation({
|
||||
property: 'transform',
|
||||
from: 'rotate(90deg)',
|
||||
to: 'none'
|
||||
}, [
|
||||
{at: -1, expect: 'rotate(180deg)'},
|
||||
{at: 0, expect: 'rotate(90deg)'},
|
||||
{at: 0.25, expect: 'rotate(67.5deg)'},
|
||||
{at: 0.75, expect: 'rotate(22.5deg)'},
|
||||
{at: 1, expect: 'rotate(0deg)'},
|
||||
{at: 2, expect: 'rotate(-90deg)'},
|
||||
]);
|
||||
test_interpolation({
|
||||
property: 'transform',
|
||||
from: 'rotateX(0deg) rotateY(0deg) rotateZ(0deg)',
|
||||
to: 'rotateX(700deg) rotateY(800deg) rotateZ(900deg)'
|
||||
}, [
|
||||
{at: -1, expect: 'rotateX(-700deg) rotateY(-800deg) rotateZ(-900deg)'},
|
||||
{at: 0, expect: 'rotateX(0deg) rotateY(0deg) rotateZ(0deg)'},
|
||||
{at: 0.25, expect: 'rotateX(175deg) rotateY(200deg) rotateZ(225deg)'},
|
||||
{at: 0.75, expect: 'rotateX(525deg) rotateY(600deg) rotateZ(675deg)'},
|
||||
{at: 1, expect: 'rotateX(700deg) rotateY(800deg) rotateZ(900deg)'},
|
||||
{at: 2, expect: 'rotateX(1400deg) rotateY(1600deg) rotateZ(1800deg)'},
|
||||
]);
|
||||
</script>
|
||||
Reference in New Issue
Block a user