diff options
Diffstat (limited to 'dom/animation/test/mozilla/test_distance_of_transform.html')
-rw-r--r-- | dom/animation/test/mozilla/test_distance_of_transform.html | 404 |
1 files changed, 404 insertions, 0 deletions
diff --git a/dom/animation/test/mozilla/test_distance_of_transform.html b/dom/animation/test/mozilla/test_distance_of_transform.html new file mode 100644 index 0000000000..96ff1eb66d --- /dev/null +++ b/dom/animation/test/mozilla/test_distance_of_transform.html @@ -0,0 +1,404 @@ +<!doctype html> +<meta charset=utf-8> +<script src='/resources/testharness.js'></script> +<script src='/resources/testharnessreport.js'></script> +<script src='../testcommon.js'></script> +<div id='log'></div> +<script type='text/javascript'> +'use strict'; + +// We don't have an official spec to define the distance between two transform +// lists, but we still need this for DevTools, so Gecko and Servo backend use +// the similar rules to define the distance. If there is a spec for it, we have +// to update this test file. + +const EPSILON = 0.00001; + +// |v| should be a unit vector (i.e. having length 1) +function getQuaternion(v, angle) { + return [ + v[0] * Math.sin(angle / 2.0), + v[1] * Math.sin(angle / 2.0), + v[2] * Math.sin(angle / 2.0), + Math.cos(angle / 2.0) + ]; +} + +function computeRotateDistance(q1, q2) { + const dot = q1.reduce((sum, e, i) => sum + e * q2[i], 0); + return Math.acos(Math.min(Math.max(dot, -1.0), 1.0)) * 2.0; +} + +function createMatrixFromArray(array) { + return (array.length === 16 ? 'matrix3d' : 'matrix') + `(${array.join()})`; +} + +function rotate3dToMatrix(x, y, z, radian) { + var sc = Math.sin(radian / 2) * Math.cos(radian / 2); + var sq = Math.sin(radian / 2) * Math.sin(radian / 2); + + // Normalize the vector. + var length = Math.sqrt(x*x + y*y + z*z); + x /= length; + y /= length; + z /= length; + + return [ + 1 - 2 * (y*y + z*z) * sq, + 2 * (x * y * sq + z * sc), + 2 * (x * z * sq - y * sc), + 0, + 2 * (x * y * sq - z * sc), + 1 - 2 * (x*x + z*z) * sq, + 2 * (y * z * sq + x * sc), + 0, + 2 * (x * z * sq + y * sc), + 2 * (y * z * sq - x * sc), + 1 - 2 * (x*x + y*y) * sq, + 0, + 0, + 0, + 0, + 1 + ]; +} + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'transform', 'none', 'none'); + assert_equals(dist, 0, 'distance of translate'); +}, 'Test distance of none and none'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'transform', 'translate(100px)', 'none'); + assert_equals(dist, 100, 'distance of translate'); +}, 'Test distance of translate function and none'); + +test(function(t) { + var target = addDiv(t); + var dist = + getDistance(target, 'transform', 'translate(100px)', 'translate(200px)'); + assert_equals(dist, 200 - 100, 'distance of translate'); +}, 'Test distance of translate functions'); + +test(function(t) { + var target = addDiv(t); + var dist = + getDistance(target, 'transform', 'translate3d(100px, 0, 50px)', 'none'); + assert_equals(dist, Math.sqrt(100 * 100 + 50 * 50), + 'distance of translate3d'); +}, 'Test distance of translate3d function and none'); + +test(function(t) { + var target = addDiv(t); + var dist = + getDistance(target, 'transform', + 'translate3d(100px, 0, 50px)', + 'translate3d(200px, 80px, 0)'); + assert_equals(dist, Math.sqrt(100 * 100 + 80 * 80 + 50 * 50), + 'distance of translate'); +}, 'Test distance of translate3d functions'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'transform', 'scale(1.5)', 'none'); + assert_equals(dist, Math.sqrt(0.5 * 0.5 + 0.5 * 0.5), 'distance of scale'); +}, 'Test distance of scale function and none'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'transform', 'scale(1.5)', 'scale(2.0)'); + assert_equals(dist, Math.sqrt(0.5 * 0.5 + 0.5 * 0.5), 'distance of scale'); +}, 'Test distance of scale functions'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'transform', + 'scale3d(1.5, 1.5, 1.5)', + 'none'); + assert_equals(dist, + Math.sqrt(0.5 * 0.5 + 0.5 * 0.5 + 0.5 * 0.5), + 'distance of scale3d'); +}, 'Test distance of scale3d function and none'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'transform', + 'scale3d(1.5, 1.5, 1.5)', + 'scale3d(2.0, 2.0, 1.0)'); + assert_equals(dist, + Math.sqrt(0.5 * 0.5 + 0.5 * 0.5 + 0.5 * 0.5), + 'distance of scale3d'); +}, 'Test distance of scale3d functions'); + +test(function(t) { + var target = addDiv(t); + var dist = + getDistance(target, 'transform', 'rotate(45deg)', 'rotate(90deg)'); + assert_approx_equals(dist, Math.PI / 2.0 - Math.PI / 4.0, EPSILON, 'distance of rotate'); +}, 'Test distance of rotate functions'); + +test(function(t) { + var target = addDiv(t); + var dist = + getDistance(target, 'transform', 'rotate(45deg)', 'none'); + assert_approx_equals(dist, Math.PI / 4.0, EPSILON, 'distance of rotate'); +}, 'Test distance of rotate function and none'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'transform', + 'rotate3d(0, 1, 0, 90deg)', + 'none'); + assert_approx_equals(dist, Math.PI / 2, EPSILON, 'distance of rotate3d'); +}, 'Test distance of rotate3d function and none'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'transform', + 'rotate3d(0, 0, 1, 90deg)', + 'rotate3d(1, 0, 0, 90deg)'); + let q1 = getQuaternion([0, 0, 1], Math.PI / 2.0); + let q2 = getQuaternion([1, 0, 0], Math.PI / 2.0); + assert_approx_equals(dist, computeRotateDistance(q1, q2), EPSILON, 'distance of rotate3d'); +}, 'Test distance of rotate3d functions'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'transform', + 'rotate3d(0, 0, 1, 90deg)', + 'rotate3d(0, 0, 0, 90deg)'); + assert_approx_equals(dist, Math.PI / 2, EPSILON, 'distance of rotate3d'); +}, 'Test distance of rotate3d functions whose direction vector cannot be ' + + 'normalized'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'transform', 'skew(1rad, 0.5rad)', 'none'); + assert_approx_equals(dist, Math.sqrt(1 * 1 + 0.5 * 0.5), EPSILON, 'distance of skew'); +}, 'Test distance of skew function and none'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'transform', + 'skew(1rad, 0.5rad)', + 'skew(-1rad, 0)'); + assert_approx_equals(dist, Math.sqrt(2 * 2 + 0.5 * 0.5), EPSILON, 'distance of skew'); +}, 'Test distance of skew functions'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'transform', + 'perspective(128px)', + 'none'); + assert_equals(dist, Infinity, 'distance of perspective'); +}, 'Test distance of perspective function and none'); + +test(function(t) { + var target = addDiv(t); + // perspective(0) is treated as perspective(inf) because perspective length + // should be greater than or equal to zero. + var dist = getDistance(target, 'transform', + 'perspective(128px)', + 'perspective(0)'); + assert_equals(dist, 128, 'distance of perspective'); +}, 'Test distance of perspective function and an invalid perspective'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'transform', + 'perspective(128px)', + 'perspective(1024px)'); + assert_equals(dist, 1024 - 128, 'distance of perspective'); +}, 'Test distance of perspective functions'); + +test(function(t) { + var target = addDiv(t); + var sin_30 = Math.sin(Math.PI / 6); + var cos_30 = Math.cos(Math.PI / 6); + // matrix => translate(100, 0) rotate(30deg). + var matrix = createMatrixFromArray([ cos_30, sin_30, + -sin_30, cos_30, + 100, 0 ]); + var dist = getDistance(target, 'transform', matrix, 'none'); + assert_approx_equals(dist, + Math.sqrt(100 * 100 + (Math.PI / 6) * (Math.PI / 6)), + EPSILON, + 'distance of matrix'); +}, 'Test distance of matrix function and none'); + +test(function(t) { + var target = addDiv(t); + var sin_30 = Math.sin(Math.PI / 6); + var cos_30 = Math.cos(Math.PI / 6); + // matrix1 => translate(100, 0) rotate(30deg). + var matrix1 = createMatrixFromArray([ cos_30, sin_30, + -sin_30, cos_30, + 100, 0 ]); + // matrix2 => translate(0, 100) scale(0.5). + var matrix2 = createMatrixFromArray([ 0.5, 0, 0, 0.5, 0, 100 ]); + var dist = getDistance(target, 'transform', matrix1, matrix2); + assert_approx_equals(dist, + Math.sqrt(100 * 100 + 100 * 100 + // translate + (Math.PI / 6) * (Math.PI / 6) + // rotate + 0.5 * 0.5 + 0.5 * 0.5), // scale + EPSILON, + 'distance of matrix'); +}, 'Test distance of matrix functions'); + +test(function(t) { + var target = addDiv(t); + var matrix = createMatrixFromArray(rotate3dToMatrix(0, 1, 0, Math.PI / 6)); + var dist = getDistance(target, 'transform', matrix, 'none'); + assert_approx_equals(dist, Math.PI / 6, EPSILON, 'distance of matrix3d'); +}, 'Test distance of matrix3d function and none'); + +test(function(t) { + var target = addDiv(t); + // matrix1 => rotate3d(0, 1, 0, 30deg). + var matrix1 = createMatrixFromArray(rotate3dToMatrix(0, 1, 0, Math.PI / 6)); + // matrix1 => translate3d(100, 0, 0) scale3d(0.5, 0.5, 0.5). + var matrix2 = createMatrixFromArray([ 0.5, 0, 0, 0, + 0, 0.5, 0, 0, + 0, 0, 0.5, 0, + 100, 0, 0, 1 ]); + var dist = getDistance(target, 'transform', matrix1, matrix2); + assert_approx_equals(dist, + Math.sqrt(100 * 100 + // translate + 0.5 * 0.5 * 3 + // scale + (Math.PI / 6) * (Math.PI / 6)), // rotate + EPSILON, + 'distance of matrix'); +}, 'Test distance of matrix3d functions'); + +test(function(t) { + var target = addDiv(t); + var cos_180 = Math.cos(Math.PI); + var sin_180 = Math.sin(Math.PI); + // matrix1 => translate3d(100px, 50px, -10px) skew(45deg). + var matrix1 = createMatrixFromArray([ 1, 0, 0, 0, + Math.tan(Math.PI/4.0), 1, 0, 0, + 0, 0, 1, 0, + 100, 50, -10, 1]); + // matrix2 => translate3d(1000px, 0, 0) rotate3d(1, 0, 0, 180deg). + var matrix2 = createMatrixFromArray([ 1, 0, 0, 0, + 0, cos_180, sin_180, 0, + 0, -sin_180, cos_180, 0, + 1000, 0, 0, 1 ]); + var dist = getDistance(target, 'transform', matrix1, matrix2); + assert_approx_equals(dist, + Math.sqrt(900 * 900 + 50 * 50 + 10 * 10 + // translate + Math.PI * Math.PI + // rotate + (Math.PI / 4) * (Math.PI / 4)), // skew angle + EPSILON, + 'distance of matrix'); +}, 'Test distance of matrix3d functions with skew factors'); + +test(function(t) { + var target = addDiv(t); + var dist = + getDistance(target, 'transform', + 'rotate(180deg) translate(1000px)', + 'rotate(360deg) translate(0px)'); + assert_approx_equals(dist, Math.sqrt(1000 * 1000 + Math.PI * Math.PI), EPSILON, + 'distance of transform lists'); +}, 'Test distance of transform lists'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'transform', + 'translate(100px) rotate(180deg)', + 'translate(50px) rotate(90deg) scale(5) skew(1rad)'); + assert_approx_equals(dist, + Math.sqrt(50 * 50 + + Math.PI / 2 * Math.PI / 2 + + 4 * 4 * 2 + + 1 * 1), + EPSILON, + 'distance of transform lists'); +}, 'Test distance of transform lists where one has extra items'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'transform', + 'translate(1000px) rotate3d(1, 0, 0, 180deg)', + 'translate(1000px) scale3d(2.5, 0.5, 1)'); + assert_equals(dist, Math.sqrt(Math.PI * Math.PI + 1.5 * 1.5 + 0.5 * 0.5), + 'distance of transform lists'); +}, 'Test distance of mismatched transform lists'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'transform', + 'translate(100px) skew(1rad)', + 'translate(1000px) rotate3d(0, 1, 0, -2rad)'); + assert_approx_equals(dist, + Math.sqrt(900 * 900 + 1 * 1 + 2 * 2), + EPSILON, + 'distance of transform lists'); +}, 'Test distance of mismatched transform lists with skew function'); + + +// Individual transforms +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'translate', '50px', 'none'); + assert_equals(dist, Math.sqrt(50 * 50), 'distance of 2D translate and none'); +}, 'Test distance of 2D translate property with none'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'translate', '10px 30px', '50px'); + assert_equals(dist, Math.sqrt(40 * 40 + 30 * 30), 'distance of 2D translate'); +}, 'Test distance of 2D translate property'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'translate', '10px 30px 50px', '50px'); + assert_equals(dist, Math.sqrt(40 * 40 + 30 * 30 + 50 * 50), + 'distance of 3D translate'); +}, 'Test distance of 3D translate property'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'scale', '2', 'none'); + assert_equals(dist, Math.sqrt(1 + 1), 'distance of 2D scale and none'); +}, 'Test distance of 2D scale property with none'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'scale', '3', '1 1'); + assert_equals(dist, Math.sqrt(2 * 2 + 2 * 2), 'distance of 2D scale'); +}, 'Test distance of 2D scale property'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'scale', '3 2 2', '1 1'); + assert_equals(dist, Math.sqrt(2 * 2 + 1 * 1 + 1 * 1), + 'distance of 3D scale'); +}, 'Test distance of 3D scale property'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'rotate', '180deg', 'none'); + assert_equals(dist, Math.PI, 'distance of 2D rotate and none'); +}, 'Test distance of 2D rotate property with none'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'rotate', '180deg', '90deg'); + assert_equals(dist, Math.PI / 2.0, 'distance of 2D rotate'); +}, 'Test distance of 2D rotate property'); + +test(function(t) { + var target = addDiv(t); + var dist = getDistance(target, 'rotate', 'z 90deg', 'x 90deg'); + let q1 = getQuaternion([0, 0, 1], Math.PI / 2.0); + let q2 = getQuaternion([1, 0, 0], Math.PI / 2.0); + assert_approx_equals(dist, computeRotateDistance(q1, q2), EPSILON, + 'distance of 3D rotate'); +}, 'Test distance of 3D rotate property'); + +</script> +</html> |