| <!doctype html> |
| <meta charset="utf-8"> |
| <title>CSSTransformValue tests</title> |
| <link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#transformvalue-objects"> |
| <script src="../../resources/testharness.js"></script> |
| <script src="../../resources/testharnessreport.js"></script> |
| <script src="../resources/testhelper.js"></script> |
| <script src="../resources/comparisons.js"></script> |
| <script> |
| 'use strict'; |
| |
| const EPSILON = 1e-6; |
| |
| test(() => { |
| assert_throws(new TypeError(), () => new CSSTransformValue()); |
| assert_throws(new TypeError(), () => new CSSTransformValue([])); |
| }, 'Constructing a CSSTransformValue with no components throws TypeError'); |
| |
| test(() => { |
| const values = [ |
| new CSSScale(1, 1), |
| new CSSTranslation(CSS.px(1), CSS.px(1)), |
| new CSSRotation(CSS.deg(90)) |
| ]; |
| |
| const transform = new CSSTransformValue(values); |
| assert_style_value_array_equals(transform, values); |
| }, 'CSSTransformValue can be constructed with multiple transforms'); |
| |
| test(() => { |
| const transform = new CSSTransformValue([ |
| new CSSScale(1, 1), |
| new CSSTranslation(CSS.px(1), CSS.px(1), CSS.px(1)), |
| new CSSScale(1, 1) |
| ]); |
| assert_equals(transform.is2D, false); |
| }, 'CSSTransformValue.is2D is false when given mix of 2D and 3D transforms'); |
| |
| test(() => { |
| const transform = new CSSTransformValue([ |
| new CSSScale(1, 1), |
| new CSSTranslation(CSS.px(1), CSS.px(1)), |
| new CSSScale(1, 1) |
| ]); |
| assert_equals(transform.is2D, true); |
| }, 'CSSTransformValue.is2D is true when given only 2D transforms'); |
| |
| test(() => { |
| let transform = new CSSTransformValue([new CSSScale(1, 2)]); |
| assert_throws(new TypeError(), () => transform.is2D = false); |
| assert_equals(transform.is2D, true); |
| }, 'CSSTransformValue.is2D is readonly'); |
| |
| test(() => { |
| const transform = new CSSTransformValue([ |
| new CSSTranslation(CSS.px(1), CSS.px(2), CSS.px(3)) |
| ]); |
| const expectedMatrix = (new DOMMatrixReadOnly()).translate(1, 2, 3); |
| assert_matrix_approx_equals(transform.toMatrix(), expectedMatrix, 1e-8); |
| }, 'CSSTransformValue.toMatrix returns correct matrix for CSSTranslation'); |
| |
| test(() => { |
| const transform = new CSSTransformValue([ |
| new CSSRotation(CSS.number(1), CSS.number(2), CSS.number(3), CSS.deg(90)) |
| ]); |
| const expectedMatrix = (new DOMMatrixReadOnly()).rotateAxisAngle(1, 2, 3, 90); |
| assert_matrix_approx_equals(transform.toMatrix(), expectedMatrix, EPSILON); |
| }, 'CSSTransformValue.toMatrix returns correct matrix for CSSRotation'); |
| |
| test(() => { |
| const transform = new CSSTransformValue([ |
| new CSSScale(CSS.number(1), CSS.number(2), CSS.number(3)) |
| ]); |
| const expectedMatrix = (new DOMMatrixReadOnly()).scale(1, 2, 3); |
| assert_matrix_approx_equals(transform.toMatrix(), expectedMatrix, EPSILON); |
| }, 'CSSTransformValue.toMatrix returns correct matrix for CSSScale'); |
| |
| test(() => { |
| const alpha = 10; |
| const beta = 20; |
| const transform = new CSSTransformValue([ |
| new CSSSkew(CSS.rad(alpha), CSS.rad(beta)) |
| ]); |
| const expectedMatrix = new DOMMatrixReadOnly( |
| [1, Math.tan(beta), 0, 0, Math.tan(alpha), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); |
| assert_matrix_approx_equals(transform.toMatrix(), expectedMatrix, EPSILON); |
| }, 'CSSTransformValue.toMatrix returns correct matrix for CSSSkew'); |
| |
| test(() => { |
| const length = 10; |
| const transform = new CSSTransformValue([ |
| new CSSPerspective(CSS.px(length)) |
| ]); |
| const expectedMatrix = new DOMMatrixReadOnly( |
| [1, 0, 0, 0, |
| 0, 1, 0, 0, |
| 0, 0, 1, -1/length, |
| 0, 0, 0, 1]); |
| assert_matrix_approx_equals(transform.toMatrix(), expectedMatrix, EPSILON); |
| }, 'CSSTransformValue.toMatrix returns correct matrix for CSSPerspective'); |
| |
| test(() => { |
| const matrix = new DOMMatrixReadOnly( |
| [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]); |
| const transform = new CSSTransformValue([ |
| new CSSMatrixComponent(matrix) |
| ]); |
| assert_matrix_approx_equals(transform.toMatrix(), matrix, EPSILON); |
| }, 'CSSTransformValue.toMatrix returns correct matrix for CSSMatrixComponent'); |
| |
| test(() => { |
| const transformMatrix = new DOMMatrixReadOnly([1, 1, 1, 1, 1, 1]); |
| const transformArray = [ |
| new CSSScale(2, 2), |
| new CSSMatrixComponent(transformMatrix), |
| new CSSScale(5, 6) |
| ]; |
| |
| let expectedMatrix = new DOMMatrix(); |
| expectedMatrix.scaleSelf(2, 2); |
| expectedMatrix.multiplySelf(transformMatrix); |
| expectedMatrix.scaleSelf(5, 6); |
| |
| const transform = new CSSTransformValue(transformArray); |
| assert_matrix_approx_equals(transform.toMatrix(), expectedMatrix, EPSILON); |
| }, 'CSSTransformValue.toMatrix multiplies its component matrices'); |
| |
| test(() => { |
| const transformArray = [ |
| new CSSScale(2, 2), |
| new CSSMatrixComponent(new DOMMatrixReadOnly([1, 1, 1, 1, 1, 1])), |
| new CSSScale(5, 6) |
| ]; |
| |
| const transformValue = new CSSTransformValue(transformArray); |
| |
| const newTransformArray = [...transformValue]; |
| assert_style_value_array_equals([...transformValue], transformArray); |
| }, 'Can iterate through CSSTransformValue components'); |
| </script> |