- Delete old Vite+Svelte frontend - Initialize new SvelteKit project with TypeScript - Configure Tailwind CSS v4 + DaisyUI - Implement JWT authentication with auto-refresh - Create login page with form validation (Zod) - Add protected route guards - Update Docker configuration for single-stage build - Add E2E tests with Playwright (6/11 passing) - Fix Svelte 5 reactivity with $state() runes Known issues: - 5 E2E tests failing (timing/async issues) - Token refresh implementation needs debugging - Validation error display timing
1376 lines
55 KiB
JavaScript
1376 lines
55 KiB
JavaScript
import DOMPoint from '../DOMPoint.js';
|
|
import * as PropertySymbol from '../../PropertySymbol.js';
|
|
const DEFAULT_MATRIX_JSON = {
|
|
a: 1,
|
|
b: 0,
|
|
c: 0,
|
|
d: 1,
|
|
e: 0,
|
|
f: 0,
|
|
m11: 1,
|
|
m12: 0,
|
|
m13: 0,
|
|
m14: 0,
|
|
m21: 0,
|
|
m22: 1,
|
|
m23: 0,
|
|
m24: 0,
|
|
m31: 0,
|
|
m32: 0,
|
|
m33: 1,
|
|
m34: 0,
|
|
m41: 0,
|
|
m42: 0,
|
|
m43: 0,
|
|
m44: 1,
|
|
is2D: true,
|
|
isIdentity: true
|
|
};
|
|
const TRANSFORM_REGEXP = /([a-zA-Z0-9]+)\(([^)]+)\)/gm;
|
|
const TRANSFORM_PARAMETER_SPLIT_REGEXP = /[\s,]+/;
|
|
/**
|
|
* DOM Matrix.
|
|
*
|
|
* Based on:
|
|
* - https://github.com/trusktr/geometry-interfaces
|
|
* - https://github.com/thednp/dommatrix/tree/master
|
|
* - https://github.com/jarek-foksa/geometry-polyfill/blob/master/geometry-polyfill.js
|
|
* - https://github.com/Automattic/node-canvas/blob/master/lib/DOMMatrix.js
|
|
*
|
|
*
|
|
* 3D Matrix:
|
|
* _________________________
|
|
* | m11 | m21 | m31 | m41 |
|
|
* | m12 | m22 | m32 | m42 |
|
|
* | m13 | m23 | m33 | m43 |
|
|
* | m14 | m24 | m34 | m44 |
|
|
* -------------------------̣
|
|
*
|
|
* 2D Matrix:
|
|
* _________________________
|
|
* | m11 | m21 | 0 | m41 |
|
|
* | m12 | m22 | 0 | m42 |
|
|
* | 0 | 0 | 1 | 0 |
|
|
* | 0 | 0 | 0 | 1 |
|
|
* -------------------------
|
|
*
|
|
*
|
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrixReadOnly
|
|
*/
|
|
export default class DOMMatrixReadOnly {
|
|
[PropertySymbol.m11] = 1;
|
|
[PropertySymbol.m12] = 0;
|
|
[PropertySymbol.m13] = 0;
|
|
[PropertySymbol.m14] = 0;
|
|
[PropertySymbol.m21] = 0;
|
|
[PropertySymbol.m22] = 1;
|
|
[PropertySymbol.m23] = 0;
|
|
[PropertySymbol.m24] = 0;
|
|
[PropertySymbol.m31] = 0;
|
|
[PropertySymbol.m32] = 0;
|
|
[PropertySymbol.m33] = 1;
|
|
[PropertySymbol.m34] = 0;
|
|
[PropertySymbol.m41] = 0;
|
|
[PropertySymbol.m42] = 0;
|
|
[PropertySymbol.m43] = 0;
|
|
[PropertySymbol.m44] = 1;
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @param init Init parameter.
|
|
*/
|
|
constructor(init) {
|
|
if (init) {
|
|
this[PropertySymbol.setMatrixValue](init);
|
|
}
|
|
}
|
|
/**
|
|
* Returns the `a` value of the matrix.
|
|
*/
|
|
get a() {
|
|
return this[PropertySymbol.m11];
|
|
}
|
|
/**
|
|
* Returns the `b` value of the matrix.
|
|
*/
|
|
get b() {
|
|
return this[PropertySymbol.m12];
|
|
}
|
|
/**
|
|
* Returns the `c` value of the matrix.
|
|
*/
|
|
get c() {
|
|
return this[PropertySymbol.m21];
|
|
}
|
|
/**
|
|
* Returns the `d` value of the matrix.
|
|
*/
|
|
get d() {
|
|
return this[PropertySymbol.m22];
|
|
}
|
|
/**
|
|
* Returns the `e` value of the matrix.
|
|
*/
|
|
get e() {
|
|
return this[PropertySymbol.m41];
|
|
}
|
|
/**
|
|
* Returns the `f` value of the matrix.
|
|
*/
|
|
get f() {
|
|
return this[PropertySymbol.m42];
|
|
}
|
|
/**
|
|
* Returns the `m11` value of the matrix.
|
|
*/
|
|
get m11() {
|
|
return this[PropertySymbol.m11];
|
|
}
|
|
/**
|
|
* Returns the `m12` value of the matrix.
|
|
*/
|
|
get m12() {
|
|
return this[PropertySymbol.m12];
|
|
}
|
|
/**
|
|
* Returns the `m13` value of the matrix.
|
|
*/
|
|
get m13() {
|
|
return this[PropertySymbol.m13];
|
|
}
|
|
/**
|
|
* Returns the `m14` value of the matrix.
|
|
*/
|
|
get m14() {
|
|
return this[PropertySymbol.m14];
|
|
}
|
|
/**
|
|
* Returns the `m21` value of the matrix.
|
|
*/
|
|
get m21() {
|
|
return this[PropertySymbol.m21];
|
|
}
|
|
/**
|
|
* Returns the `m22` value of the matrix.
|
|
*/
|
|
get m22() {
|
|
return this[PropertySymbol.m22];
|
|
}
|
|
/**
|
|
* Returns the `m23` value of the matrix.
|
|
*/
|
|
get m23() {
|
|
return this[PropertySymbol.m23];
|
|
}
|
|
/**
|
|
* Returns the `m24` value of the matrix.
|
|
*/
|
|
get m24() {
|
|
return this[PropertySymbol.m24];
|
|
}
|
|
/**
|
|
* Returns the `m31` value of the matrix.
|
|
*/
|
|
get m31() {
|
|
return this[PropertySymbol.m31];
|
|
}
|
|
/**
|
|
* Returns the `m32` value of the matrix.
|
|
*/
|
|
get m32() {
|
|
return this[PropertySymbol.m32];
|
|
}
|
|
/**
|
|
* Returns the `m33` value of the matrix.
|
|
*/
|
|
get m33() {
|
|
return this[PropertySymbol.m33];
|
|
}
|
|
/**
|
|
* Returns the `m34` value of the matrix.
|
|
*/
|
|
get m34() {
|
|
return this[PropertySymbol.m34];
|
|
}
|
|
/**
|
|
* Returns the `m41` value of the matrix.
|
|
*/
|
|
get m41() {
|
|
return this[PropertySymbol.m41];
|
|
}
|
|
/**
|
|
* Returns the `m42` value of the matrix.
|
|
*/
|
|
get m42() {
|
|
return this[PropertySymbol.m42];
|
|
}
|
|
/**
|
|
* Returns the `m43` value of the matrix.
|
|
*/
|
|
get m43() {
|
|
return this[PropertySymbol.m43];
|
|
}
|
|
/**
|
|
* Returns the `m44` value of the matrix.
|
|
*/
|
|
get m44() {
|
|
return this[PropertySymbol.m44];
|
|
}
|
|
/**
|
|
* A `Boolean` whose value is `true` if the matrix is the identity matrix.
|
|
*
|
|
* The identity matrix is one in which every value is 0 except those on the main diagonal from top-left to bottom-right corner (in other words, where the offsets in each direction are equal).
|
|
*
|
|
* @returns "true" if the matrix is the identity matrix.
|
|
*/
|
|
get isIdentity() {
|
|
return (this[PropertySymbol.m11] === 1 &&
|
|
this[PropertySymbol.m12] === 0 &&
|
|
this[PropertySymbol.m13] === 0 &&
|
|
this[PropertySymbol.m14] === 0 &&
|
|
this[PropertySymbol.m21] === 0 &&
|
|
this[PropertySymbol.m22] === 1 &&
|
|
this[PropertySymbol.m23] === 0 &&
|
|
this[PropertySymbol.m24] === 0 &&
|
|
this[PropertySymbol.m31] === 0 &&
|
|
this[PropertySymbol.m32] === 0 &&
|
|
this[PropertySymbol.m33] === 1 &&
|
|
this[PropertySymbol.m34] === 0 &&
|
|
this[PropertySymbol.m41] === 0 &&
|
|
this[PropertySymbol.m42] === 0 &&
|
|
this[PropertySymbol.m43] === 0 &&
|
|
this[PropertySymbol.m44] === 1);
|
|
}
|
|
/**
|
|
* A `Boolean` flag whose value is `true` if the matrix is a 2D matrix and `false` if the matrix is 3D.
|
|
*
|
|
* @returns "true" if the matrix is a 2D matrix.
|
|
*/
|
|
get is2D() {
|
|
return (this[PropertySymbol.m31] === 0 &&
|
|
this[PropertySymbol.m32] === 0 &&
|
|
this[PropertySymbol.m33] === 1 &&
|
|
this[PropertySymbol.m34] === 0 &&
|
|
this[PropertySymbol.m43] === 0 &&
|
|
this[PropertySymbol.m44] === 1);
|
|
}
|
|
/**
|
|
* Returns a *Float32Array* containing elements which comprise the matrix.
|
|
*
|
|
* The method can return either the 16 elements or the 6 elements depending on the value of the `is2D` parameter.
|
|
*
|
|
* @param [is2D] Set to `true` to return a 2D matrix.
|
|
* @returns An *Array* representation of the matrix.
|
|
*/
|
|
toFloat32Array(is2D) {
|
|
return Float32Array.from(this[PropertySymbol.toArray](is2D));
|
|
}
|
|
/**
|
|
* Returns a *Float64Array* containing elements which comprise the matrix.
|
|
*
|
|
* The method can return either the 16 elements or the 6 elements depending on the value of the `is2D` parameter.
|
|
*
|
|
* @param [is2D] Set to `true` to return a 2D matrix.
|
|
* @returns An *Array* representation of the matrix
|
|
*/
|
|
toFloat64Array(is2D) {
|
|
return Float64Array.from(this[PropertySymbol.toArray](is2D));
|
|
}
|
|
/**
|
|
* Returns a string representation of the matrix in `CSS` matrix syntax, using the appropriate `CSS` matrix notation.
|
|
*
|
|
* Examples:
|
|
* - `matrix3d(m11, m12, m13, m14, m21, ...)`
|
|
* - `matrix(a, b, c, d, e, f)`
|
|
*
|
|
* @returns A string representation of the matrix.
|
|
*/
|
|
toString() {
|
|
const is2D = this.is2D;
|
|
const values = this[PropertySymbol.toArray](is2D).join(', ');
|
|
const type = is2D ? 'matrix' : 'matrix3d';
|
|
return `${type}(${values})`;
|
|
}
|
|
/**
|
|
* Returns an Object that can be serialized to a JSON string.
|
|
*
|
|
* The result can be used as a second parameter for the `fromMatrix` static method to load values into another matrix instance.
|
|
*
|
|
* @returns An *Object* with matrix values.
|
|
*/
|
|
toJSON() {
|
|
const { is2D, isIdentity } = this;
|
|
return {
|
|
m11: this[PropertySymbol.m11],
|
|
m12: this[PropertySymbol.m12],
|
|
m13: this[PropertySymbol.m13],
|
|
m14: this[PropertySymbol.m14],
|
|
m21: this[PropertySymbol.m21],
|
|
m22: this[PropertySymbol.m22],
|
|
m23: this[PropertySymbol.m23],
|
|
m24: this[PropertySymbol.m24],
|
|
m31: this[PropertySymbol.m31],
|
|
m32: this[PropertySymbol.m32],
|
|
m33: this[PropertySymbol.m33],
|
|
m34: this[PropertySymbol.m34],
|
|
m41: this[PropertySymbol.m41],
|
|
m42: this[PropertySymbol.m42],
|
|
m43: this[PropertySymbol.m43],
|
|
m44: this[PropertySymbol.m44],
|
|
a: this[PropertySymbol.m11],
|
|
b: this[PropertySymbol.m12],
|
|
c: this[PropertySymbol.m21],
|
|
d: this[PropertySymbol.m22],
|
|
e: this[PropertySymbol.m41],
|
|
f: this[PropertySymbol.m42],
|
|
is2D,
|
|
isIdentity
|
|
};
|
|
}
|
|
/**
|
|
* Returns a new DOMMatrix instance which is the result of this matrix multiplied by the passed matrix.
|
|
*
|
|
* @param secondMatrix DOMMatrix
|
|
* @returns A new DOMMatrix object.
|
|
*/
|
|
multiply(secondMatrix) {
|
|
const matrix = new this.constructor(this);
|
|
matrix[PropertySymbol.multiplySelf](secondMatrix);
|
|
return matrix;
|
|
}
|
|
/**
|
|
* Returns a new DOMMatrix instance which is this matrix post multiplied by a translation matrix containing the passed values.
|
|
*
|
|
* @param [x=0] X component of the translation value.
|
|
* @param [y=0] Y component of the translation value.
|
|
* @param [z=0] Z component of the translation value.
|
|
* @returns The resulted matrix
|
|
*/
|
|
translate(x = 0, y = 0, z = 0) {
|
|
const matrix = new this.constructor(this);
|
|
matrix[PropertySymbol.translateSelf](x, y, z);
|
|
return matrix;
|
|
}
|
|
/**
|
|
* Returns a new DOMMatrix instance which is this matrix post multiplied by a scale 2D matrix containing the passed values.
|
|
*
|
|
* @param [scaleX] X-Axis scale.
|
|
* @param [scaleY] Y-Axis scale.
|
|
* @param [scaleZ] Z-Axis scale.
|
|
* @param [originX] X-Axis scale.
|
|
* @param [originY] Y-Axis scale.
|
|
* @param [originZ] Z-Axis scale.
|
|
* @returns The resulted matrix
|
|
*/
|
|
scale(scaleX, scaleY, scaleZ = 1, originX = 0, originY = 0, originZ = 0) {
|
|
const matrix = new this.constructor(this);
|
|
matrix[PropertySymbol.scaleSelf](scaleX, scaleY, scaleZ, originX, originY, originZ);
|
|
return matrix;
|
|
}
|
|
/**
|
|
* Returns a new DOMMatrix instance which is this matrix post multiplied by a scale 3D matrix containing the passed values.
|
|
*
|
|
* @param [scale] The scale factor.
|
|
* @param [originX] X-Axis scale.
|
|
* @param [originY] Y-Axis scale.
|
|
* @param [originZ] Z-Axis scale.
|
|
* @returns The resulted matrix
|
|
*/
|
|
scale3d(scale = 1, originX = 0, originY = 0, originZ = 0) {
|
|
const matrix = new this.constructor(this);
|
|
matrix[PropertySymbol.scale3dSelf](scale, originX, originY, originZ);
|
|
return matrix;
|
|
}
|
|
/**
|
|
* Returns a new DOMMatrix instance which is this matrix post multiplied by a scale 3D matrix containing the passed values.
|
|
*
|
|
* @param [scaleX] X-Axis scale.
|
|
* @param [scaleY] Y-Axis scale.
|
|
* @returns The resulted matrix
|
|
*/
|
|
scaleNonUniform(scaleX = 1, scaleY = 1) {
|
|
const matrix = new this.constructor(this);
|
|
matrix[PropertySymbol.scaleNonUniformSelf](scaleX, scaleY);
|
|
return matrix;
|
|
}
|
|
/**
|
|
* Returns a new DOMMatrix instance which is this matrix post multiplied by a rotation matrix with the given axis and `angle`.
|
|
*
|
|
* @param [x] The X component of the axis vector.
|
|
* @param [y] The Y component of the axis vector.
|
|
* @param [z] The Z component of the axis vector.
|
|
* @param [angle] Angle of rotation about the axis vector, in degrees.
|
|
* @returns The resulted matrix
|
|
*/
|
|
rotateAxisAngle(x = 0, y = 0, z = 0, angle = 0) {
|
|
const matrix = new this.constructor(this);
|
|
matrix[PropertySymbol.rotateAxisAngleSelf](x, y, z, angle);
|
|
return matrix;
|
|
}
|
|
/**
|
|
* Returns a new DOMMatrix instance which is this matrix post multiplied by each of 3 rotation matrices about the major axes, first X, then Y, then Z.
|
|
*
|
|
* @param [x] X component of the rotation, or Z if Y and Z are null.
|
|
* @param [y] Y component of the rotation value.
|
|
* @param [z] Z component of the rotation value.
|
|
* @returns The resulted matrix
|
|
*/
|
|
rotate(x = 0, y, z) {
|
|
const matrix = new this.constructor(this);
|
|
matrix[PropertySymbol.rotateSelf](x, y, z);
|
|
return matrix;
|
|
}
|
|
/**
|
|
* Returns a new DOMMatrix instance which is this matrix post multiplied by a rotation matrix with the angle between the specified vector and (1, 0).
|
|
*
|
|
* @param [x] X-Axis skew.
|
|
* @param [y] Y-Axis skew.
|
|
*/
|
|
rotateFromVector(x = 0, y = 0) {
|
|
const matrix = new this.constructor(this);
|
|
matrix[PropertySymbol.rotateFromVectorSelf](x, y);
|
|
return matrix;
|
|
}
|
|
/**
|
|
* Returns a new DOMMatrix instance that specifies a skew transformation along X-Axis by the given angle.
|
|
*
|
|
* @param angle Angle amount in degrees to skew.
|
|
* @returns The resulted matrix
|
|
*/
|
|
skewX(angle) {
|
|
const matrix = new this.constructor(this);
|
|
matrix[PropertySymbol.skewXSelf](angle);
|
|
return matrix;
|
|
}
|
|
/**
|
|
* Returns a new DOMMatrix instance that specifies a skew transformation along Y-Axis by the given angle.
|
|
*
|
|
* @param angle Angle amount in degrees to skew.
|
|
* @returns The resulted matrix
|
|
*/
|
|
skewY(angle) {
|
|
const matrix = new this.constructor(this);
|
|
matrix[PropertySymbol.skewYSelf](angle);
|
|
return matrix;
|
|
}
|
|
/**
|
|
* Returns a new DOMMatrix instance which is this matrix flipped on X-axis.
|
|
*/
|
|
flipX() {
|
|
const matrix = new this.constructor(this);
|
|
matrix[PropertySymbol.flipXSelf]();
|
|
return matrix;
|
|
}
|
|
/**
|
|
* Returns a new DOMMatrix instance which is this matrix flipped on Y-axis.
|
|
*/
|
|
flipY() {
|
|
const matrix = new this.constructor(this);
|
|
matrix[PropertySymbol.flipYSelf]();
|
|
return matrix;
|
|
}
|
|
/**
|
|
* Returns a new DOMMatrix instance which is this matrix inversed.
|
|
*/
|
|
inverse() {
|
|
const matrix = new this.constructor(this);
|
|
matrix[PropertySymbol.invertSelf]();
|
|
return matrix;
|
|
}
|
|
/**
|
|
* Returns a new DOMPoint instance with the vector transformed using the matrix.
|
|
*
|
|
* @param domPoint DOM point compatible object.
|
|
* @returns A new DOMPoint object.
|
|
*/
|
|
transformPoint(domPoint) {
|
|
const xPoint = domPoint.x ?? 0;
|
|
const yPoint = domPoint.y ?? 0;
|
|
const zPoint = domPoint.z ?? 0;
|
|
const wPoint = domPoint.w ?? 1;
|
|
const x = this[PropertySymbol.m11] * xPoint +
|
|
this[PropertySymbol.m21] * yPoint +
|
|
this[PropertySymbol.m31] * zPoint +
|
|
this[PropertySymbol.m41] * wPoint;
|
|
const y = this[PropertySymbol.m12] * xPoint +
|
|
this[PropertySymbol.m22] * yPoint +
|
|
this[PropertySymbol.m32] * zPoint +
|
|
this[PropertySymbol.m42] * wPoint;
|
|
const z = this[PropertySymbol.m13] * xPoint +
|
|
this[PropertySymbol.m23] * yPoint +
|
|
this[PropertySymbol.m33] * zPoint +
|
|
this[PropertySymbol.m43] * wPoint;
|
|
const w = this[PropertySymbol.m14] * xPoint +
|
|
this[PropertySymbol.m24] * yPoint +
|
|
this[PropertySymbol.m34] * zPoint +
|
|
this[PropertySymbol.m44] * wPoint;
|
|
return new DOMPoint(x, y, z, w);
|
|
}
|
|
/**
|
|
* The `setMatrixValue` method replaces the existing matrix with one computed in the browser (e.g.`matrix(1,0.25,-0.25,1,0,0)`).
|
|
*
|
|
* @param source A `DOMMatrix`, `Float32Array`, `Float64Array`, `Array`, or DOMMatrix compatible object to set the matrix values from.
|
|
*/
|
|
[PropertySymbol.setMatrixValue](source) {
|
|
let matrix;
|
|
// String
|
|
if (typeof source === 'string' && source.length && source !== 'none') {
|
|
matrix = this.constructor[PropertySymbol.fromString](source);
|
|
}
|
|
// Array
|
|
else if (Array.isArray(source) ||
|
|
source instanceof Float64Array ||
|
|
source instanceof Float32Array) {
|
|
matrix = this.constructor[PropertySymbol.fromArray](source);
|
|
}
|
|
// DOMMatrixReadOnly or IDOMMatrixCompatibleObject
|
|
else if (typeof source === 'object') {
|
|
matrix = this.constructor.fromMatrix(source);
|
|
}
|
|
this[PropertySymbol.m11] = matrix[PropertySymbol.m11];
|
|
this[PropertySymbol.m12] = matrix[PropertySymbol.m12];
|
|
this[PropertySymbol.m13] = matrix[PropertySymbol.m13];
|
|
this[PropertySymbol.m14] = matrix[PropertySymbol.m14];
|
|
this[PropertySymbol.m21] = matrix[PropertySymbol.m21];
|
|
this[PropertySymbol.m22] = matrix[PropertySymbol.m22];
|
|
this[PropertySymbol.m23] = matrix[PropertySymbol.m23];
|
|
this[PropertySymbol.m24] = matrix[PropertySymbol.m24];
|
|
this[PropertySymbol.m31] = matrix[PropertySymbol.m31];
|
|
this[PropertySymbol.m32] = matrix[PropertySymbol.m32];
|
|
this[PropertySymbol.m33] = matrix[PropertySymbol.m33];
|
|
this[PropertySymbol.m34] = matrix[PropertySymbol.m34];
|
|
this[PropertySymbol.m41] = matrix[PropertySymbol.m41];
|
|
this[PropertySymbol.m42] = matrix[PropertySymbol.m42];
|
|
this[PropertySymbol.m43] = matrix[PropertySymbol.m43];
|
|
this[PropertySymbol.m44] = matrix[PropertySymbol.m44];
|
|
}
|
|
/**
|
|
* Applies a multiply operation to the current matrix.
|
|
*
|
|
* @param matrix Second matrix.
|
|
*/
|
|
[PropertySymbol.multiplySelf](matrix) {
|
|
if (!(matrix instanceof DOMMatrixReadOnly)) {
|
|
if (matrix?.m11 === undefined && matrix?.a !== undefined) {
|
|
matrix = Object.assign({}, DEFAULT_MATRIX_JSON, matrix);
|
|
matrix.m11 = matrix.a;
|
|
matrix.m12 = matrix.b;
|
|
matrix.m21 = matrix.c;
|
|
matrix.m22 = matrix.d;
|
|
matrix.m41 = matrix.e;
|
|
matrix.m42 = matrix.f;
|
|
}
|
|
else {
|
|
matrix = Object.assign({}, DEFAULT_MATRIX_JSON, matrix);
|
|
}
|
|
}
|
|
const m11 = this[PropertySymbol.m11] * matrix.m11 +
|
|
this[PropertySymbol.m21] * matrix.m12 +
|
|
this[PropertySymbol.m31] * matrix.m13 +
|
|
this[PropertySymbol.m41] * matrix.m14;
|
|
const m21 = this[PropertySymbol.m11] * matrix.m21 +
|
|
this[PropertySymbol.m21] * matrix.m22 +
|
|
this[PropertySymbol.m31] * matrix.m23 +
|
|
this[PropertySymbol.m41] * matrix.m24;
|
|
const m31 = this[PropertySymbol.m11] * matrix.m31 +
|
|
this[PropertySymbol.m21] * matrix.m32 +
|
|
this[PropertySymbol.m31] * matrix.m33 +
|
|
this[PropertySymbol.m41] * matrix.m34;
|
|
const m41 = this[PropertySymbol.m11] * matrix.m41 +
|
|
this[PropertySymbol.m21] * matrix.m42 +
|
|
this[PropertySymbol.m31] * matrix.m43 +
|
|
this[PropertySymbol.m41] * matrix.m44;
|
|
const m12 = this[PropertySymbol.m12] * matrix.m11 +
|
|
this[PropertySymbol.m22] * matrix.m12 +
|
|
this[PropertySymbol.m32] * matrix.m13 +
|
|
this[PropertySymbol.m42] * matrix.m14;
|
|
const m22 = this[PropertySymbol.m12] * matrix.m21 +
|
|
this[PropertySymbol.m22] * matrix.m22 +
|
|
this[PropertySymbol.m32] * matrix.m23 +
|
|
this[PropertySymbol.m42] * matrix.m24;
|
|
const m32 = this[PropertySymbol.m12] * matrix.m31 +
|
|
this[PropertySymbol.m22] * matrix.m32 +
|
|
this[PropertySymbol.m32] * matrix.m33 +
|
|
this[PropertySymbol.m42] * matrix.m34;
|
|
const m42 = this[PropertySymbol.m12] * matrix.m41 +
|
|
this[PropertySymbol.m22] * matrix.m42 +
|
|
this[PropertySymbol.m32] * matrix.m43 +
|
|
this[PropertySymbol.m42] * matrix.m44;
|
|
const m13 = this[PropertySymbol.m13] * matrix.m11 +
|
|
this[PropertySymbol.m23] * matrix.m12 +
|
|
this[PropertySymbol.m33] * matrix.m13 +
|
|
this[PropertySymbol.m43] * matrix.m14;
|
|
const m23 = this[PropertySymbol.m13] * matrix.m21 +
|
|
this[PropertySymbol.m23] * matrix.m22 +
|
|
this[PropertySymbol.m33] * matrix.m23 +
|
|
this[PropertySymbol.m43] * matrix.m24;
|
|
const m33 = this[PropertySymbol.m13] * matrix.m31 +
|
|
this[PropertySymbol.m23] * matrix.m32 +
|
|
this[PropertySymbol.m33] * matrix.m33 +
|
|
this[PropertySymbol.m43] * matrix.m34;
|
|
const m43 = this[PropertySymbol.m13] * matrix.m41 +
|
|
this[PropertySymbol.m23] * matrix.m42 +
|
|
this[PropertySymbol.m33] * matrix.m43 +
|
|
this[PropertySymbol.m43] * matrix.m44;
|
|
const m14 = this[PropertySymbol.m14] * matrix.m11 +
|
|
this[PropertySymbol.m24] * matrix.m12 +
|
|
this[PropertySymbol.m34] * matrix.m13 +
|
|
this[PropertySymbol.m44] * matrix.m14;
|
|
const m24 = this[PropertySymbol.m14] * matrix.m21 +
|
|
this[PropertySymbol.m24] * matrix.m22 +
|
|
this[PropertySymbol.m34] * matrix.m23 +
|
|
this[PropertySymbol.m44] * matrix.m24;
|
|
const m34 = this[PropertySymbol.m14] * matrix.m31 +
|
|
this[PropertySymbol.m24] * matrix.m32 +
|
|
this[PropertySymbol.m34] * matrix.m33 +
|
|
this[PropertySymbol.m44] * matrix.m34;
|
|
const m44 = this[PropertySymbol.m14] * matrix.m41 +
|
|
this[PropertySymbol.m24] * matrix.m42 +
|
|
this[PropertySymbol.m34] * matrix.m43 +
|
|
this[PropertySymbol.m44] * matrix.m44;
|
|
this[PropertySymbol.m11] = m11;
|
|
this[PropertySymbol.m12] = m12;
|
|
this[PropertySymbol.m13] = m13;
|
|
this[PropertySymbol.m14] = m14;
|
|
this[PropertySymbol.m21] = m21;
|
|
this[PropertySymbol.m22] = m22;
|
|
this[PropertySymbol.m23] = m23;
|
|
this[PropertySymbol.m24] = m24;
|
|
this[PropertySymbol.m31] = m31;
|
|
this[PropertySymbol.m32] = m32;
|
|
this[PropertySymbol.m33] = m33;
|
|
this[PropertySymbol.m34] = m34;
|
|
this[PropertySymbol.m41] = m41;
|
|
this[PropertySymbol.m42] = m42;
|
|
this[PropertySymbol.m43] = m43;
|
|
this[PropertySymbol.m44] = m44;
|
|
}
|
|
/**
|
|
* Applies translate to the matrix.
|
|
*
|
|
* This method is equivalent to the CSS `translate3d()` function.
|
|
*
|
|
* @see https://drafts.csswg.org/css-transforms-1/#TranslateDefined
|
|
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/translate3d
|
|
* @see https://www.w3.org/TR/css-transforms-1/#transform-functions
|
|
* @param [x] X-Axis position.
|
|
* @param [y] Y-Axis position.
|
|
* @param [z] Z-Axis position.
|
|
*/
|
|
[PropertySymbol.translateSelf](x = 0, y = 0, z = 0) {
|
|
// prettier-ignore
|
|
const translationMatrix = this.constructor[PropertySymbol.fromArray]([
|
|
1, 0, 0, 0,
|
|
0, 1, 0, 0,
|
|
0, 0, 1, 0,
|
|
x, y, z, 1,
|
|
]);
|
|
this[PropertySymbol.multiplySelf](translationMatrix);
|
|
}
|
|
/**
|
|
* Applies a scale to the matrix.
|
|
*
|
|
* This method is equivalent to the CSS `scale()` function.
|
|
*
|
|
* @see https://drafts.csswg.org/css-transforms-1/#ScaleDefined
|
|
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/scale
|
|
* @see https://www.w3.org/TR/css-transforms-1/#transform-functions
|
|
* @param [scaleX] X-Axis scale.
|
|
* @param [scaleY] Y-Axis scale.
|
|
* @param [scaleZ] Z-Axis scale.
|
|
* @param [originX] X-Axis scale.
|
|
* @param [originY] Y-Axis scale.
|
|
* @param [originZ] Z-Axis scale.
|
|
*/
|
|
[PropertySymbol.scaleSelf](scaleX, scaleY, scaleZ = 1, originX = 0, originY = 0, originZ = 0) {
|
|
// If scaleY is missing, set scaleY to the value of scaleX.
|
|
scaleX = scaleX === undefined ? 1 : Number(scaleX);
|
|
scaleY = scaleY === undefined ? scaleX : Number(scaleY);
|
|
if (originX !== 0 || originY !== 0 || originZ !== 0) {
|
|
this[PropertySymbol.translateSelf](originX, originY, originZ);
|
|
}
|
|
if (scaleX !== 1 || scaleY !== 1 || scaleZ !== 1) {
|
|
// prettier-ignore
|
|
this[PropertySymbol.multiplySelf](this.constructor[PropertySymbol.fromArray]([
|
|
scaleX, 0, 0, 0,
|
|
0, scaleY, 0, 0,
|
|
0, 0, scaleZ, 0,
|
|
0, 0, 0, 1,
|
|
]));
|
|
}
|
|
if (originX !== 0 || originY !== 0 || originZ !== 0) {
|
|
this[PropertySymbol.translateSelf](-originX, -originY, -originZ);
|
|
}
|
|
}
|
|
/**
|
|
* Applies a scale to the matrix.
|
|
*
|
|
* This method is equivalent to the CSS `scale()` function.
|
|
*
|
|
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/scale3d
|
|
* @see https://www.w3.org/TR/css-transforms-1/#transform-functions
|
|
* @param [scale] The scale factor.
|
|
* @param [originX] X-Axis scale.
|
|
* @param [originY] Y-Axis scale.
|
|
* @param [originZ] Z-Axis scale.
|
|
*/
|
|
[PropertySymbol.scale3dSelf](scale = 1, originX = 0, originY = 0, originZ = 0) {
|
|
if (originX !== 0 || originY !== 0 || originZ !== 0) {
|
|
this[PropertySymbol.translateSelf](originX, originY, originZ);
|
|
}
|
|
if (scale !== 1) {
|
|
// prettier-ignore
|
|
this[PropertySymbol.multiplySelf](this.constructor[PropertySymbol.fromArray]([
|
|
scale, 0, 0, 0,
|
|
0, scale, 0, 0,
|
|
0, 0, scale, 0,
|
|
0, 0, 0, 1,
|
|
]));
|
|
}
|
|
if (originX !== 0 || originY !== 0 || originZ !== 0) {
|
|
this[PropertySymbol.translateSelf](-originX, -originY, -originZ);
|
|
}
|
|
}
|
|
/**
|
|
* Applies a scale to the matrix.
|
|
*
|
|
* @see https://www.w3.org/TR/css-transforms-1/#transform-functions
|
|
* @param [scaleX] X-Axis scale.
|
|
* @param [scaleY] Y-Axis scale.
|
|
*/
|
|
[PropertySymbol.scaleNonUniformSelf](scaleX = 1, scaleY = 1) {
|
|
if (scaleX === 1 && scaleY === 1) {
|
|
return;
|
|
}
|
|
// prettier-ignore
|
|
this[PropertySymbol.multiplySelf](this.constructor[PropertySymbol.fromArray]([
|
|
scaleX, 0, 0, 0,
|
|
0, scaleY, 0, 0,
|
|
0, 0, 1, 0,
|
|
0, 0, 0, 1,
|
|
]));
|
|
}
|
|
/**
|
|
* Applies a rotation to the matrix.
|
|
*
|
|
* This method is equivalent to the CSS `rotate3d()` function.
|
|
*
|
|
* @see https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-rotateaxisangleself
|
|
* @see https://www.w3.org/TR/css-transforms-1/#transform-functions
|
|
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/rotate3d
|
|
* @param [x] X-Axis vector.
|
|
* @param [y] Y-Axis vector.
|
|
* @param [z] Z-Axis vector.
|
|
* @param [angle] Angle in degrees of the rotation.
|
|
*/
|
|
[PropertySymbol.rotateAxisAngleSelf](x = 0, y = 0, z = 0, angle = 0) {
|
|
x = Number(x);
|
|
y = Number(y);
|
|
z = Number(z);
|
|
angle = Number(angle);
|
|
if (isNaN(x) || isNaN(y) || isNaN(z) || isNaN(angle)) {
|
|
throw new TypeError(`Failed to execute 'rotateAxisAngleSelf' on 'DOMMatrix': The arguments must be numbers.`);
|
|
}
|
|
const length = Math.hypot(x, y, z);
|
|
if (length === 0) {
|
|
return;
|
|
}
|
|
if (length !== 1) {
|
|
x /= length;
|
|
y /= length;
|
|
z /= length;
|
|
}
|
|
// Degree to radian divided by 2
|
|
const alpha = -((angle * Math.PI) / 360);
|
|
const round = this.#round;
|
|
const sc = Math.sin(alpha) * Math.cos(alpha);
|
|
const sq = Math.sin(alpha) * Math.sin(alpha);
|
|
// We round it as the calculation is off by about 0.000000000000001, which causes the matrix to be different from the browser.
|
|
// The rounding doesn't solve the issue for all cases, it would be better to find a more accurate solution.
|
|
const m11 = round(1 - 2 * (y * y + z * z) * sq);
|
|
const m12 = round(2 * (x * y * sq + z * sc));
|
|
const m13 = round(2 * (x * z * sq - y * sc));
|
|
const m21 = round(2 * (x * y * sq - z * sc));
|
|
const m22 = round(1 - 2 * (x * x + z * z) * sq);
|
|
const m23 = round(2 * (y * z * sq + x * sc));
|
|
const m31 = round(2 * (x * z * sq + y * sc));
|
|
const m32 = round(2 * (y * z * sq - x * sc));
|
|
const m33 = round(1 - 2 * (x * x + y * y) * sq);
|
|
// prettier-ignore
|
|
const matrix = this.constructor[PropertySymbol.fromArray]([
|
|
m11, m21, m31, 0,
|
|
m12, m22, m32, 0,
|
|
m13, m23, m33, 0,
|
|
0, 0, 0, 1
|
|
]);
|
|
this[PropertySymbol.multiplySelf](matrix);
|
|
}
|
|
/**
|
|
* Applies a rotation to the matrix.
|
|
*
|
|
* @see http://en.wikipedia.org/wiki/Rotation_matrix
|
|
* @see https://www.w3.org/TR/css-transforms-1/#transform-functions
|
|
* @param [x] X-Axis rotation in degrees.
|
|
* @param [y] Y-Axis rotation in degrees.
|
|
* @param [z] Z-Axis rotation in degrees.
|
|
*/
|
|
[PropertySymbol.rotateSelf](x = 0, y, z) {
|
|
// If Y and Z are both missing, set Z to the value of X and set X and Y to 0.
|
|
if (y === undefined && z === undefined) {
|
|
z = x;
|
|
x = 0;
|
|
y = 0;
|
|
}
|
|
// If Y is still missing, set Y to 0.
|
|
if (y === undefined) {
|
|
y = 0;
|
|
}
|
|
// If Z is still missing, set Z to 0
|
|
if (z === undefined) {
|
|
z = 0;
|
|
}
|
|
x = Number(x);
|
|
y = Number(y);
|
|
z = Number(z);
|
|
if (isNaN(x) || isNaN(y) || isNaN(z)) {
|
|
throw new TypeError(`Failed to execute 'rotateSelf' on 'DOMMatrix': The arguments must be numbers.`);
|
|
}
|
|
if (z !== 0) {
|
|
this[PropertySymbol.rotateAxisAngleSelf](0, 0, 1, z);
|
|
}
|
|
if (y !== 0) {
|
|
this[PropertySymbol.rotateAxisAngleSelf](0, 1, 0, y);
|
|
}
|
|
if (x !== 0) {
|
|
this[PropertySymbol.rotateAxisAngleSelf](1, 0, 0, x);
|
|
}
|
|
}
|
|
/**
|
|
* Modifies the matrix by rotating it by the angle between the specified vector and (1, 0).
|
|
*
|
|
* @param x The X component of the axis vector.
|
|
* @param y The Y component of the axis vector.
|
|
*/
|
|
[PropertySymbol.rotateFromVectorSelf](x = 0, y = 0) {
|
|
if (x === 0 && y === 0) {
|
|
return;
|
|
}
|
|
this[PropertySymbol.rotateSelf]((Math.atan2(y, x) * 180) / Math.PI);
|
|
}
|
|
/**
|
|
* Applies a skew operation to the matrix on the X axis.
|
|
*
|
|
* This method is equivalent to the CSS `skewX()` function.
|
|
*
|
|
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/skewX
|
|
* @see https://www.w3.org/TR/css-transforms-1/#transform-functions
|
|
* @param angle Angle in degrees.
|
|
*/
|
|
[PropertySymbol.skewXSelf](angle) {
|
|
const matrix = Object.assign({}, DEFAULT_MATRIX_JSON);
|
|
const value = Math.tan((angle * Math.PI) / 180);
|
|
matrix.m21 = value;
|
|
matrix.c = value;
|
|
this[PropertySymbol.multiplySelf](matrix);
|
|
}
|
|
/**
|
|
* Applies a skew operation to the matrix on the Y axis.
|
|
*
|
|
* This method is equivalent to the CSS `skewY()` function.
|
|
*
|
|
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/skewY
|
|
* @see https://www.w3.org/TR/css-transforms-1/#transform-functions
|
|
* @param angle Angle in degrees.
|
|
*/
|
|
[PropertySymbol.skewYSelf](angle) {
|
|
const matrix = Object.assign({}, DEFAULT_MATRIX_JSON);
|
|
const value = Math.tan((angle * Math.PI) / 180);
|
|
matrix.m12 = value;
|
|
matrix.b = value;
|
|
this[PropertySymbol.multiplySelf](matrix);
|
|
}
|
|
/**
|
|
* Applies a flip operation to the matrix on the X axis.
|
|
*/
|
|
[PropertySymbol.flipXSelf]() {
|
|
// prettier-ignore
|
|
const matrix = this.constructor[PropertySymbol.fromArray]([
|
|
-1, 0, 0, 0,
|
|
0, 1, 0, 0,
|
|
0, 0, 1, 0,
|
|
0, 0, 0, 1
|
|
]);
|
|
this[PropertySymbol.multiplySelf](matrix);
|
|
}
|
|
/**
|
|
* Applies a flip operation to the matrix on the Y axis.
|
|
*/
|
|
[PropertySymbol.flipYSelf]() {
|
|
// prettier-ignore
|
|
const matrix = this.constructor[PropertySymbol.fromArray]([
|
|
1, 0, 0, 0,
|
|
0, -1, 0, 0,
|
|
0, 0, 1, 0,
|
|
0, 0, 0, 1
|
|
]);
|
|
this[PropertySymbol.multiplySelf](matrix);
|
|
}
|
|
/**
|
|
* Applies an inversion operation to the matrix.
|
|
*/
|
|
[PropertySymbol.invertSelf]() {
|
|
const m11 = this[PropertySymbol.m22] * this[PropertySymbol.m33] * this[PropertySymbol.m44] -
|
|
this[PropertySymbol.m22] * this[PropertySymbol.m34] * this[PropertySymbol.m43] -
|
|
this[PropertySymbol.m32] * this[PropertySymbol.m23] * this[PropertySymbol.m44] +
|
|
this[PropertySymbol.m32] * this[PropertySymbol.m24] * this[PropertySymbol.m43] +
|
|
this[PropertySymbol.m42] * this[PropertySymbol.m23] * this[PropertySymbol.m34] -
|
|
this[PropertySymbol.m42] * this[PropertySymbol.m24] * this[PropertySymbol.m33];
|
|
const m12 = -this[PropertySymbol.m12] * this[PropertySymbol.m33] * this[PropertySymbol.m44] +
|
|
this[PropertySymbol.m12] * this[PropertySymbol.m34] * this[PropertySymbol.m43] +
|
|
this[PropertySymbol.m32] * this[PropertySymbol.m13] * this[PropertySymbol.m44] -
|
|
this[PropertySymbol.m32] * this[PropertySymbol.m14] * this[PropertySymbol.m43] -
|
|
this[PropertySymbol.m42] * this[PropertySymbol.m13] * this[PropertySymbol.m34] +
|
|
this[PropertySymbol.m42] * this[PropertySymbol.m14] * this[PropertySymbol.m33];
|
|
const m13 = this[PropertySymbol.m12] * this[PropertySymbol.m23] * this[PropertySymbol.m44] -
|
|
this[PropertySymbol.m12] * this[PropertySymbol.m24] * this[PropertySymbol.m43] -
|
|
this[PropertySymbol.m22] * this[PropertySymbol.m13] * this[PropertySymbol.m44] +
|
|
this[PropertySymbol.m22] * this[PropertySymbol.m14] * this[PropertySymbol.m43] +
|
|
this[PropertySymbol.m42] * this[PropertySymbol.m13] * this[PropertySymbol.m24] -
|
|
this[PropertySymbol.m42] * this[PropertySymbol.m14] * this[PropertySymbol.m23];
|
|
const m14 = -this[PropertySymbol.m12] * this[PropertySymbol.m23] * this[PropertySymbol.m34] +
|
|
this[PropertySymbol.m12] * this[PropertySymbol.m24] * this[PropertySymbol.m33] +
|
|
this[PropertySymbol.m22] * this[PropertySymbol.m13] * this[PropertySymbol.m34] -
|
|
this[PropertySymbol.m22] * this[PropertySymbol.m14] * this[PropertySymbol.m33] -
|
|
this[PropertySymbol.m32] * this[PropertySymbol.m13] * this[PropertySymbol.m24] +
|
|
this[PropertySymbol.m32] * this[PropertySymbol.m14] * this[PropertySymbol.m23];
|
|
const det = this[PropertySymbol.m11] * m11 +
|
|
this[PropertySymbol.m21] * m12 +
|
|
this[PropertySymbol.m31] * m13 +
|
|
this[PropertySymbol.m41] * m14;
|
|
// If the current matrix is not invertible set all attributes to NaN and set is 2D to false.
|
|
if (det === 0) {
|
|
this[PropertySymbol.m11] = NaN;
|
|
this[PropertySymbol.m12] = NaN;
|
|
this[PropertySymbol.m13] = NaN;
|
|
this[PropertySymbol.m14] = NaN;
|
|
this[PropertySymbol.m21] = NaN;
|
|
this[PropertySymbol.m22] = NaN;
|
|
this[PropertySymbol.m23] = NaN;
|
|
this[PropertySymbol.m24] = NaN;
|
|
this[PropertySymbol.m31] = NaN;
|
|
this[PropertySymbol.m32] = NaN;
|
|
this[PropertySymbol.m33] = NaN;
|
|
this[PropertySymbol.m34] = NaN;
|
|
this[PropertySymbol.m41] = NaN;
|
|
this[PropertySymbol.m42] = NaN;
|
|
this[PropertySymbol.m43] = NaN;
|
|
this[PropertySymbol.m44] = NaN;
|
|
return;
|
|
}
|
|
const m21 = -this[PropertySymbol.m21] * this[PropertySymbol.m33] * this[PropertySymbol.m44] +
|
|
this[PropertySymbol.m21] * this[PropertySymbol.m34] * this[PropertySymbol.m43] +
|
|
this[PropertySymbol.m31] * this[PropertySymbol.m23] * this[PropertySymbol.m44] -
|
|
this[PropertySymbol.m31] * this[PropertySymbol.m24] * this[PropertySymbol.m43] -
|
|
this[PropertySymbol.m41] * this[PropertySymbol.m23] * this[PropertySymbol.m34] +
|
|
this[PropertySymbol.m41] * this[PropertySymbol.m24] * this[PropertySymbol.m33];
|
|
const m22 = this[PropertySymbol.m11] * this[PropertySymbol.m33] * this[PropertySymbol.m44] -
|
|
this[PropertySymbol.m11] * this[PropertySymbol.m34] * this[PropertySymbol.m43] -
|
|
this[PropertySymbol.m31] * this[PropertySymbol.m13] * this[PropertySymbol.m44] +
|
|
this[PropertySymbol.m31] * this[PropertySymbol.m14] * this[PropertySymbol.m43] +
|
|
this[PropertySymbol.m41] * this[PropertySymbol.m13] * this[PropertySymbol.m34] -
|
|
this[PropertySymbol.m41] * this[PropertySymbol.m14] * this[PropertySymbol.m33];
|
|
const m23 = -this[PropertySymbol.m11] * this[PropertySymbol.m23] * this[PropertySymbol.m44] +
|
|
this[PropertySymbol.m11] * this[PropertySymbol.m24] * this[PropertySymbol.m43] +
|
|
this[PropertySymbol.m21] * this[PropertySymbol.m13] * this[PropertySymbol.m44] -
|
|
this[PropertySymbol.m21] * this[PropertySymbol.m14] * this[PropertySymbol.m43] -
|
|
this[PropertySymbol.m41] * this[PropertySymbol.m13] * this[PropertySymbol.m24] +
|
|
this[PropertySymbol.m41] * this[PropertySymbol.m14] * this[PropertySymbol.m23];
|
|
const m24 = this[PropertySymbol.m11] * this[PropertySymbol.m23] * this[PropertySymbol.m34] -
|
|
this[PropertySymbol.m11] * this[PropertySymbol.m24] * this[PropertySymbol.m33] -
|
|
this[PropertySymbol.m21] * this[PropertySymbol.m13] * this[PropertySymbol.m34] +
|
|
this[PropertySymbol.m21] * this[PropertySymbol.m14] * this[PropertySymbol.m33] +
|
|
this[PropertySymbol.m31] * this[PropertySymbol.m13] * this[PropertySymbol.m24] -
|
|
this[PropertySymbol.m31] * this[PropertySymbol.m14] * this[PropertySymbol.m23];
|
|
const m31 = this[PropertySymbol.m21] * this[PropertySymbol.m32] * this[PropertySymbol.m44] -
|
|
this[PropertySymbol.m21] * this[PropertySymbol.m34] * this[PropertySymbol.m42] -
|
|
this[PropertySymbol.m31] * this[PropertySymbol.m22] * this[PropertySymbol.m44] +
|
|
this[PropertySymbol.m31] * this[PropertySymbol.m24] * this[PropertySymbol.m42] +
|
|
this[PropertySymbol.m41] * this[PropertySymbol.m22] * this[PropertySymbol.m34] -
|
|
this[PropertySymbol.m41] * this[PropertySymbol.m24] * this[PropertySymbol.m32];
|
|
const m32 = -this[PropertySymbol.m11] * this[PropertySymbol.m32] * this[PropertySymbol.m44] +
|
|
this[PropertySymbol.m11] * this[PropertySymbol.m34] * this[PropertySymbol.m42] +
|
|
this[PropertySymbol.m31] * this[PropertySymbol.m12] * this[PropertySymbol.m44] -
|
|
this[PropertySymbol.m31] * this[PropertySymbol.m14] * this[PropertySymbol.m42] -
|
|
this[PropertySymbol.m41] * this[PropertySymbol.m12] * this[PropertySymbol.m34] +
|
|
this[PropertySymbol.m41] * this[PropertySymbol.m14] * this[PropertySymbol.m32];
|
|
const m33 = this[PropertySymbol.m11] * this[PropertySymbol.m22] * this[PropertySymbol.m44] -
|
|
this[PropertySymbol.m11] * this[PropertySymbol.m24] * this[PropertySymbol.m42] -
|
|
this[PropertySymbol.m21] * this[PropertySymbol.m12] * this[PropertySymbol.m44] +
|
|
this[PropertySymbol.m21] * this[PropertySymbol.m14] * this[PropertySymbol.m42] +
|
|
this[PropertySymbol.m41] * this[PropertySymbol.m12] * this[PropertySymbol.m24] -
|
|
this[PropertySymbol.m41] * this[PropertySymbol.m14] * this[PropertySymbol.m22];
|
|
const m34 = -this[PropertySymbol.m11] * this[PropertySymbol.m22] * this[PropertySymbol.m34] +
|
|
this[PropertySymbol.m11] * this[PropertySymbol.m24] * this[PropertySymbol.m32] +
|
|
this[PropertySymbol.m21] * this[PropertySymbol.m12] * this[PropertySymbol.m34] -
|
|
this[PropertySymbol.m21] * this[PropertySymbol.m14] * this[PropertySymbol.m32] -
|
|
this[PropertySymbol.m31] * this[PropertySymbol.m12] * this[PropertySymbol.m24] +
|
|
this[PropertySymbol.m31] * this[PropertySymbol.m14] * this[PropertySymbol.m22];
|
|
const m41 = -this[PropertySymbol.m21] * this[PropertySymbol.m32] * this[PropertySymbol.m43] +
|
|
this[PropertySymbol.m21] * this[PropertySymbol.m33] * this[PropertySymbol.m42] +
|
|
this[PropertySymbol.m31] * this[PropertySymbol.m22] * this[PropertySymbol.m43] -
|
|
this[PropertySymbol.m31] * this[PropertySymbol.m23] * this[PropertySymbol.m42] -
|
|
this[PropertySymbol.m41] * this[PropertySymbol.m22] * this[PropertySymbol.m33] +
|
|
this[PropertySymbol.m41] * this[PropertySymbol.m23] * this[PropertySymbol.m32];
|
|
const m42 = this[PropertySymbol.m11] * this[PropertySymbol.m32] * this[PropertySymbol.m43] -
|
|
this[PropertySymbol.m11] * this[PropertySymbol.m33] * this[PropertySymbol.m42] -
|
|
this[PropertySymbol.m31] * this[PropertySymbol.m12] * this[PropertySymbol.m43] +
|
|
this[PropertySymbol.m31] * this[PropertySymbol.m13] * this[PropertySymbol.m42] +
|
|
this[PropertySymbol.m41] * this[PropertySymbol.m12] * this[PropertySymbol.m33] -
|
|
this[PropertySymbol.m41] * this[PropertySymbol.m13] * this[PropertySymbol.m32];
|
|
const m43 = -this[PropertySymbol.m11] * this[PropertySymbol.m22] * this[PropertySymbol.m43] +
|
|
this[PropertySymbol.m11] * this[PropertySymbol.m23] * this[PropertySymbol.m42] +
|
|
this[PropertySymbol.m21] * this[PropertySymbol.m12] * this[PropertySymbol.m43] -
|
|
this[PropertySymbol.m21] * this[PropertySymbol.m13] * this[PropertySymbol.m42] -
|
|
this[PropertySymbol.m41] * this[PropertySymbol.m12] * this[PropertySymbol.m23] +
|
|
this[PropertySymbol.m41] * this[PropertySymbol.m13] * this[PropertySymbol.m22];
|
|
const m44 = this[PropertySymbol.m11] * this[PropertySymbol.m22] * this[PropertySymbol.m33] -
|
|
this[PropertySymbol.m11] * this[PropertySymbol.m23] * this[PropertySymbol.m32] -
|
|
this[PropertySymbol.m21] * this[PropertySymbol.m12] * this[PropertySymbol.m33] +
|
|
this[PropertySymbol.m21] * this[PropertySymbol.m13] * this[PropertySymbol.m32] +
|
|
this[PropertySymbol.m31] * this[PropertySymbol.m12] * this[PropertySymbol.m23] -
|
|
this[PropertySymbol.m31] * this[PropertySymbol.m13] * this[PropertySymbol.m22];
|
|
this[PropertySymbol.m11] = m11 / det || 0;
|
|
this[PropertySymbol.m12] = m12 / det || 0;
|
|
this[PropertySymbol.m13] = m13 / det || 0;
|
|
this[PropertySymbol.m14] = m14 / det || 0;
|
|
this[PropertySymbol.m21] = m21 / det || 0;
|
|
this[PropertySymbol.m22] = m22 / det || 0;
|
|
this[PropertySymbol.m23] = m23 / det || 0;
|
|
this[PropertySymbol.m24] = m24 / det || 0;
|
|
this[PropertySymbol.m31] = m31 / det || 0;
|
|
this[PropertySymbol.m32] = m32 / det || 0;
|
|
this[PropertySymbol.m33] = m33 / det || 0;
|
|
this[PropertySymbol.m34] = m34 / det || 0;
|
|
this[PropertySymbol.m41] = m41 / det || 0;
|
|
this[PropertySymbol.m42] = m42 / det || 0;
|
|
this[PropertySymbol.m43] = m43 / det || 0;
|
|
this[PropertySymbol.m44] = m44 / det || 0;
|
|
}
|
|
/**
|
|
* Returns an *Array* containing elements which comprise the matrix.
|
|
*
|
|
* @param matrix Matrix to convert.
|
|
* @param [is2D] If the matrix is 2D.
|
|
* @returns Array representation of the matrix.
|
|
*/
|
|
[PropertySymbol.toArray](is2D = false) {
|
|
if (is2D) {
|
|
return [
|
|
this[PropertySymbol.m11],
|
|
this[PropertySymbol.m12],
|
|
this[PropertySymbol.m21],
|
|
this[PropertySymbol.m22],
|
|
this[PropertySymbol.m41],
|
|
this[PropertySymbol.m42]
|
|
];
|
|
}
|
|
return [
|
|
this[PropertySymbol.m11],
|
|
this[PropertySymbol.m12],
|
|
this[PropertySymbol.m13],
|
|
this[PropertySymbol.m14],
|
|
this[PropertySymbol.m21],
|
|
this[PropertySymbol.m22],
|
|
this[PropertySymbol.m23],
|
|
this[PropertySymbol.m24],
|
|
this[PropertySymbol.m31],
|
|
this[PropertySymbol.m32],
|
|
this[PropertySymbol.m33],
|
|
this[PropertySymbol.m34],
|
|
this[PropertySymbol.m41],
|
|
this[PropertySymbol.m42],
|
|
this[PropertySymbol.m43],
|
|
this[PropertySymbol.m44]
|
|
];
|
|
}
|
|
/**
|
|
* Rounds the value to the given number of decimals.
|
|
*
|
|
* @param value The value to round.
|
|
* @param [decimals] The number of decimals to round to.
|
|
*/
|
|
#round(value, decimals = 1e15) {
|
|
return Math.round(value * decimals) / decimals;
|
|
}
|
|
/**
|
|
* Returns a new `DOMMatrix` instance given an existing matrix.
|
|
*
|
|
* @param matrix Matrix.
|
|
*/
|
|
static fromMatrix(matrix) {
|
|
if (!(matrix instanceof DOMMatrixReadOnly)) {
|
|
if (matrix?.m11 === undefined && matrix?.a !== undefined) {
|
|
matrix = Object.assign({}, DEFAULT_MATRIX_JSON, matrix);
|
|
matrix.m11 = matrix.a;
|
|
matrix.m12 = matrix.b;
|
|
matrix.m21 = matrix.c;
|
|
matrix.m22 = matrix.d;
|
|
matrix.m41 = matrix.e;
|
|
matrix.m42 = matrix.f;
|
|
}
|
|
else {
|
|
matrix = Object.assign({}, DEFAULT_MATRIX_JSON, matrix);
|
|
}
|
|
}
|
|
return this[PropertySymbol.fromArray]([
|
|
matrix.m11,
|
|
matrix.m12,
|
|
matrix.m13,
|
|
matrix.m14,
|
|
matrix.m21,
|
|
matrix.m22,
|
|
matrix.m23,
|
|
matrix.m24,
|
|
matrix.m31,
|
|
matrix.m32,
|
|
matrix.m33,
|
|
matrix.m34,
|
|
matrix.m41,
|
|
matrix.m42,
|
|
matrix.m43,
|
|
matrix.m44
|
|
]);
|
|
}
|
|
/**
|
|
* Returns a new `DOMMatrix` instance given an array of 16/6 floating point values.
|
|
*
|
|
* @param array An `Array` to feed values from.
|
|
* @returns DOMMatrix instance.
|
|
*/
|
|
static fromFloat32Array(array) {
|
|
return this[PropertySymbol.fromArray](array);
|
|
}
|
|
/**
|
|
* Returns a new `DOMMatrix` instance given an array of 16/6 floating point values.
|
|
*
|
|
* @param array An `Array` to feed values from.
|
|
* @returns DOMMatrix instance.
|
|
*/
|
|
static fromFloat64Array(array) {
|
|
return this[PropertySymbol.fromArray](array);
|
|
}
|
|
/**
|
|
* Returns a new `DOMMatrix` instance given an array of 16/6 floating point values.
|
|
*
|
|
* Conditions:
|
|
* - If the array has six values, the result is a 2D matrix.
|
|
* - If the array has 16 values, the result is a 3D matrix.
|
|
* - Otherwise, a TypeError exception is thrown.
|
|
*
|
|
* @param array An `Array` to feed values from.
|
|
* @returns DOMMatrix instance.
|
|
*/
|
|
static [PropertySymbol.fromArray](array) {
|
|
if (!(array instanceof Float64Array || array instanceof Float32Array || Array.isArray(array)) ||
|
|
(array.length !== 6 && array.length !== 16)) {
|
|
throw TypeError(`Failed to execute 'fromArray' on '${this.name}': '${String(array)}' is not a compatible array.`);
|
|
}
|
|
const matrix = new this();
|
|
if (array.length === 16) {
|
|
const [m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44] = array;
|
|
matrix[PropertySymbol.m11] = m11;
|
|
matrix[PropertySymbol.m12] = m12;
|
|
matrix[PropertySymbol.m13] = m13;
|
|
matrix[PropertySymbol.m14] = m14;
|
|
matrix[PropertySymbol.m21] = m21;
|
|
matrix[PropertySymbol.m22] = m22;
|
|
matrix[PropertySymbol.m23] = m23;
|
|
matrix[PropertySymbol.m24] = m24;
|
|
matrix[PropertySymbol.m31] = m31;
|
|
matrix[PropertySymbol.m32] = m32;
|
|
matrix[PropertySymbol.m33] = m33;
|
|
matrix[PropertySymbol.m34] = m34;
|
|
matrix[PropertySymbol.m41] = m41;
|
|
matrix[PropertySymbol.m42] = m42;
|
|
matrix[PropertySymbol.m43] = m43;
|
|
matrix[PropertySymbol.m44] = m44;
|
|
}
|
|
else if (array.length === 6) {
|
|
const [m11, m12, m21, m22, m41, m42] = array;
|
|
matrix[PropertySymbol.m11] = m11;
|
|
matrix[PropertySymbol.m12] = m12;
|
|
matrix[PropertySymbol.m21] = m21;
|
|
matrix[PropertySymbol.m22] = m22;
|
|
matrix[PropertySymbol.m41] = m41;
|
|
matrix[PropertySymbol.m42] = m42;
|
|
}
|
|
return matrix;
|
|
}
|
|
/**
|
|
* Returns a new `DOMMatrix` instance from a DOM transform string.
|
|
*
|
|
* @param source valid CSS transform string syntax.
|
|
* @returns DOMMatrix instance.
|
|
*/
|
|
static [PropertySymbol.fromString](source) {
|
|
if (typeof source !== 'string') {
|
|
throw TypeError(`Failed to execute 'setMatrixValue' on '${this.name}': Expected '${String(source)}' to be a string.`);
|
|
}
|
|
const domMatrix = new this();
|
|
const regexp = new RegExp(TRANSFORM_REGEXP);
|
|
let match;
|
|
while ((match = regexp.exec(source))) {
|
|
const name = match[1];
|
|
const parameters = match[2].split(TRANSFORM_PARAMETER_SPLIT_REGEXP);
|
|
for (let i = 0, max = parameters.length; i < max; i++) {
|
|
parameters[i] = this[PropertySymbol.getLength](parameters[i]);
|
|
}
|
|
const [x, y, z, a] = parameters;
|
|
switch (name) {
|
|
case 'perspective':
|
|
if (!isNaN(x) && x !== 0 && y === undefined && z === undefined) {
|
|
domMatrix[PropertySymbol.m34] = -1 / x;
|
|
}
|
|
break;
|
|
case 'translate':
|
|
if (!isNaN(x) && z === undefined) {
|
|
domMatrix[PropertySymbol.translateSelf](x, y || 0, 0);
|
|
}
|
|
break;
|
|
case 'translate3d':
|
|
if (!isNaN(x) && !isNaN(y) && !isNaN(z)) {
|
|
domMatrix[PropertySymbol.translateSelf](x, y, z);
|
|
}
|
|
break;
|
|
case 'translateX':
|
|
if (!isNaN(x) && y === undefined && z === undefined) {
|
|
domMatrix[PropertySymbol.translateSelf](x);
|
|
}
|
|
break;
|
|
case 'translateY':
|
|
if (!isNaN(x) && y === undefined && z === undefined) {
|
|
domMatrix[PropertySymbol.translateSelf](0, x);
|
|
}
|
|
break;
|
|
case 'translateZ':
|
|
if (!isNaN(x) && y === undefined && z === undefined) {
|
|
domMatrix[PropertySymbol.translateSelf](0, 0, x);
|
|
}
|
|
break;
|
|
case 'matrix':
|
|
case 'matrix3d':
|
|
if (parameters.length === 6 || parameters.length === 16) {
|
|
domMatrix[PropertySymbol.setMatrixValue](this[PropertySymbol.fromArray](parameters));
|
|
}
|
|
break;
|
|
case 'rotate':
|
|
case 'rotateZ':
|
|
if (!isNaN(x) && y === undefined && z === undefined) {
|
|
domMatrix[PropertySymbol.rotateSelf](0, 0, x);
|
|
}
|
|
break;
|
|
case 'rotateX':
|
|
if (!isNaN(x) && y === undefined && z === undefined) {
|
|
domMatrix[PropertySymbol.rotateSelf](x, 0, 0);
|
|
}
|
|
break;
|
|
case 'rotateY':
|
|
if (!isNaN(x) && y === undefined && z === undefined) {
|
|
domMatrix[PropertySymbol.rotateSelf](0, x, 0);
|
|
}
|
|
case 'rotate3d':
|
|
if (!isNaN(x) && !isNaN(y) && !isNaN(z) && !isNaN(a)) {
|
|
domMatrix[PropertySymbol.rotateAxisAngleSelf](x, y, z, a);
|
|
}
|
|
break;
|
|
case 'scale':
|
|
if (!isNaN(x) && x !== 1 && z === undefined) {
|
|
domMatrix[PropertySymbol.scaleSelf](x, isNaN(y) ? x : y);
|
|
}
|
|
break;
|
|
case 'scale3d':
|
|
if (!isNaN(x) && !isNaN(y) && !isNaN(z)) {
|
|
domMatrix[PropertySymbol.scaleSelf](x, y, z);
|
|
}
|
|
break;
|
|
case 'scaleX':
|
|
if (!isNaN(x) && y === undefined && z === undefined) {
|
|
domMatrix[PropertySymbol.scaleSelf](x, 1, 1);
|
|
}
|
|
break;
|
|
case 'scaleY':
|
|
if (!isNaN(x) && y === undefined && z === undefined) {
|
|
domMatrix[PropertySymbol.scaleSelf](1, x, 1);
|
|
}
|
|
break;
|
|
case 'scaleZ':
|
|
if (!isNaN(x) && y === undefined && z === undefined) {
|
|
domMatrix[PropertySymbol.scaleSelf](1, 1, x);
|
|
}
|
|
break;
|
|
case 'skew':
|
|
if (!isNaN(x)) {
|
|
domMatrix[PropertySymbol.skewXSelf](x);
|
|
}
|
|
if (!isNaN(y)) {
|
|
domMatrix[PropertySymbol.skewYSelf](y);
|
|
}
|
|
break;
|
|
case 'skewX':
|
|
if (!isNaN(x) && y === undefined) {
|
|
domMatrix[PropertySymbol.skewXSelf](x);
|
|
}
|
|
break;
|
|
case 'skewY':
|
|
if (!isNaN(x) && y === undefined) {
|
|
domMatrix[PropertySymbol.skewYSelf](x);
|
|
}
|
|
break;
|
|
default:
|
|
throw TypeError(`Failed to execute 'setMatrixValue' on '${this.name}': Unknown transform function '${match[1]}'.`);
|
|
}
|
|
}
|
|
return domMatrix;
|
|
}
|
|
/**
|
|
* Returns length.
|
|
*
|
|
* @param length Length to convert.
|
|
* @returns Length.
|
|
*/
|
|
static [PropertySymbol.getLength](length) {
|
|
const value = parseFloat(length);
|
|
const unit = length.replace(value.toString(), '');
|
|
switch (unit) {
|
|
case 'rem':
|
|
case 'em':
|
|
case 'vw':
|
|
case 'vh':
|
|
case '%':
|
|
case 'vmin':
|
|
case 'vmax':
|
|
throw new SyntaxError(`Failed to construct '${this.name}': Lengths must be absolute, not relative`);
|
|
case 'rad':
|
|
return value * (180 / Math.PI);
|
|
case 'turn':
|
|
return value * 360;
|
|
case 'px':
|
|
return value;
|
|
case 'cm':
|
|
return value * 37.7812;
|
|
case 'mm':
|
|
return value * 3.7781;
|
|
case 'in':
|
|
return value * 96;
|
|
case 'pt':
|
|
return value * 1.3281;
|
|
case 'pc':
|
|
return value * 16;
|
|
case 'Q':
|
|
return value * 0.945;
|
|
default:
|
|
return value;
|
|
}
|
|
}
|
|
}
|
|
//# sourceMappingURL=DOMMatrixReadOnly.js.map
|