145 lines
3.4 KiB
JavaScript
145 lines
3.4 KiB
JavaScript
/**
|
|
* based on
|
|
* https://github.com/CreateJS/EaselJS/blob/631cdffb85eff9413dab43b4676f059b4232d291/src/easeljs/geom/Matrix2D.js
|
|
*/
|
|
const DEG_TO_RAD = Math.PI / 180;
|
|
export const identity = [1, 0, 0, 1, 0, 0];
|
|
let a = 1;
|
|
let b = 0;
|
|
let c = 0;
|
|
let d = 1;
|
|
let tx = 0;
|
|
let ty = 0;
|
|
let hasInitialState = true;
|
|
|
|
/**
|
|
* Represents an affine transformation matrix, and provides tools for concatenating transforms.
|
|
*
|
|
* This matrix can be visualized as:
|
|
*
|
|
* [ a c tx
|
|
* b d ty
|
|
* 0 0 1 ]
|
|
*
|
|
* Note the locations of b and c.
|
|
**/
|
|
|
|
/**
|
|
* Reset current matrix to an identity matrix.
|
|
* @method reset
|
|
**/
|
|
export function reset() {
|
|
if (hasInitialState) {
|
|
return;
|
|
}
|
|
a = d = 1;
|
|
b = c = tx = ty = 0;
|
|
hasInitialState = true;
|
|
}
|
|
|
|
/**
|
|
* Returns an array with current matrix values.
|
|
* @method toArray
|
|
* @return {Array} an array with current matrix values.
|
|
**/
|
|
export function toArray() {
|
|
if (hasInitialState) {
|
|
return identity;
|
|
}
|
|
return [a, b, c, d, tx, ty];
|
|
}
|
|
|
|
/**
|
|
* Appends the specified matrix properties to this matrix. All parameters are required.
|
|
* This is the equivalent of multiplying `(this matrix) * (specified matrix)`.
|
|
* @method append
|
|
* @param {Number} a2
|
|
* @param {Number} b2
|
|
* @param {Number} c2
|
|
* @param {Number} d2
|
|
* @param {Number} tx2
|
|
* @param {Number} ty2
|
|
**/
|
|
export function append(a2, b2, c2, d2, tx2, ty2) {
|
|
const change = a2 !== 1 || b2 !== 0 || c2 !== 0 || d2 !== 1;
|
|
const translate = tx2 !== 0 || ty2 !== 0;
|
|
if (!change && !translate) {
|
|
return;
|
|
}
|
|
if (hasInitialState) {
|
|
hasInitialState = false;
|
|
a = a2;
|
|
b = b2;
|
|
c = c2;
|
|
d = d2;
|
|
tx = tx2;
|
|
ty = ty2;
|
|
return;
|
|
}
|
|
const a1 = a;
|
|
const b1 = b;
|
|
const c1 = c;
|
|
const d1 = d;
|
|
if (change) {
|
|
a = a1 * a2 + c1 * b2;
|
|
b = b1 * a2 + d1 * b2;
|
|
c = a1 * c2 + c1 * d2;
|
|
d = b1 * c2 + d1 * d2;
|
|
}
|
|
if (translate) {
|
|
tx = a1 * tx2 + c1 * ty2 + tx;
|
|
ty = b1 * tx2 + d1 * ty2 + ty;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generates matrix properties from the specified display object transform properties, and appends them to this matrix.
|
|
* For example, you can use this to generate a matrix representing the transformations of a display object:
|
|
*
|
|
* reset();
|
|
* appendTransform(o.x, o.y, o.scaleX, o.scaleY, o.rotation);
|
|
* var matrix = toArray()
|
|
*
|
|
* @method appendTransform
|
|
* @param {Number} x
|
|
* @param {Number} y
|
|
* @param {Number} scaleX
|
|
* @param {Number} scaleY
|
|
* @param {Number} rotation
|
|
* @param {Number} skewX
|
|
* @param {Number} skewY
|
|
* @param {Number} regX Optional.
|
|
* @param {Number} regY Optional.
|
|
**/
|
|
export function appendTransform(x, y, scaleX, scaleY, rotation, skewX, skewY, regX, regY) {
|
|
if (x === 0 && y === 0 && scaleX === 1 && scaleY === 1 && rotation === 0 && skewX === 0 && skewY === 0 && regX === 0 && regY === 0) {
|
|
return;
|
|
}
|
|
let cos, sin;
|
|
if (rotation % 360) {
|
|
const r = rotation * DEG_TO_RAD;
|
|
cos = Math.cos(r);
|
|
sin = Math.sin(r);
|
|
} else {
|
|
cos = 1;
|
|
sin = 0;
|
|
}
|
|
const a2 = cos * scaleX;
|
|
const b2 = sin * scaleX;
|
|
const c2 = -sin * scaleY;
|
|
const d2 = cos * scaleY;
|
|
if (skewX || skewY) {
|
|
const b1 = Math.tan(skewY * DEG_TO_RAD);
|
|
const c1 = Math.tan(skewX * DEG_TO_RAD);
|
|
append(a2 + c1 * b2, b1 * a2 + b2, c2 + c1 * d2, b1 * c2 + d2, x, y);
|
|
} else {
|
|
append(a2, b2, c2, d2, x, y);
|
|
}
|
|
if (regX || regY) {
|
|
// append the registration offset:
|
|
tx -= regX * a + regY * c;
|
|
ty -= regX * b + regY * d;
|
|
hasInitialState = false;
|
|
}
|
|
}
|
|
//# sourceMappingURL=Matrix2D.js.map
|