@aurigma/design-atoms-model
Version:
Design Atoms is a part of Customer's Canvas SDK which allows for manipulating individual design elements through your code.
125 lines • 5 kB
JavaScript
import { PointF } from "./PointF";
import { ConvertDegreeToRadian, ConvertRadianToDegree, EqualsOfFloatNumbers } from "./Common";
import { ArgumentException } from "../Exception";
import { isNumber } from "../Utils/Utils";
/**
* Creates a 2D transform matrix.
* [ x'] [ m00 m01 m02 ] [ x ] [ m00x + m01y + m02 ]
* [ y'] = [ m10 m11 m12 ] [ y ] = [ m10x + m11y + m12 ]
* [ 1 ] [ 0 0 1 ] [ 1 ] [ 1 ]
*/
export class Matrix {
constructor(m00, m10, m01, m11, m02, m12) {
this._equalityTolerance = 0.000001;
if (arguments.length == 6) {
this.setTransform(m00, m10, m01, m11, m02, m12);
}
else if (arguments.length == 0) {
this.setTransform(1, 0, 0, 1, 0, 0);
}
else {
throw new Error('Arguments error');
}
}
get angle() {
return ConvertRadianToDegree(Math.atan(-this.m01 / this.m00));
}
get scaleX() {
return Math.sqrt(this.m00 * this.m00 + this.m10 * this.m10);
}
get scaleY() {
return Math.sqrt(this.m01 * this.m01 + this.m11 * this.m11);
}
get translateX() {
return this.m02;
}
get translateY() {
return this.m12;
}
get isIdentity() {
return EqualsOfFloatNumbers(this.m00, 1, this._equalityTolerance)
&& EqualsOfFloatNumbers(this.m01, 0, this._equalityTolerance)
&& EqualsOfFloatNumbers(this.m02, 0, this._equalityTolerance)
&& EqualsOfFloatNumbers(this.m10, 0, this._equalityTolerance)
&& EqualsOfFloatNumbers(this.m11, 1, this._equalityTolerance)
&& EqualsOfFloatNumbers(this.m12, 0, this._equalityTolerance);
}
setTransform(m00, m10, m01, m11, m02, m12) {
this.m00 = m00;
this.m10 = m10;
this.m01 = m01;
this.m11 = m11;
this.m02 = m02;
this.m12 = m12;
}
transformPoint(p, clone = false) {
var pp = clone ? new PointF() : p;
var x = p.x, y = p.y;
pp.x = x * this.m00 + y * this.m01 + this.m02;
pp.y = x * this.m10 + y * this.m11 + this.m12;
return pp;
}
concatenate(m) {
const m00 = this.m00;
const m01 = this.m01;
this.m00 = m00 * m.m00 + m01 * m.m10;
this.m01 = m00 * m.m01 + m01 * m.m11;
this.m02 = m00 * m.m02 + m01 * m.m12 + this.m02;
const m10 = this.m10;
const m11 = this.m11;
this.m10 = m10 * m.m00 + m11 * m.m10;
this.m11 = m10 * m.m01 + m11 * m.m11;
this.m12 = m10 * m.m02 + m11 * m.m12 + this.m12;
return this;
}
rotate(angle) {
angle = ConvertDegreeToRadian(angle);
const cos = Math.cos(angle);
const sin = Math.sin(angle);
return this.concatenate(new Matrix(cos, sin, -sin, cos, 0, 0));
}
rotateAt(angle, x, y) {
this.translate(x, y);
this.rotate(angle);
this.translate(-x, -y);
return this;
}
scale(sx, sy) {
return this.concatenate(new Matrix(sx, 0, 0, sy, 0, 0));
}
scaleRelativeToPoint(sx, sy, origin) {
return this.concatenate(new Matrix(sx, 0, 0, sy, origin.x * (1 - sx), origin.y * (1 - sy)));
}
translate(dx, dy) {
return this.concatenate(new Matrix(1, 0, 0, 1, dx, dy));
}
clone() {
return new Matrix(this.m00, this.m10, this.m01, this.m11, this.m02, this.m12);
}
updateObjectByMatrix(object, key1, key2) {
if (object == null)
throw new ArgumentException("object cannot be null");
if (!isNumber(object[key1]) || !isNumber(object[key2]))
throw new ArgumentException("object members by given keys nust be a numbers!");
const resultPoint = this.transformPoint(new PointF(object[key1], object[key2]));
object[key1] = resultPoint.x;
object[key2] = resultPoint.y;
return object;
}
getInversed() {
const determinant = this._determinant;
return new Matrix(this.m11 / determinant, -this.m10 / determinant, -this.m01 / determinant, this.m00 / determinant, (this.m01 * this.m12 - this.m11 * this.m02) / determinant, (this.m10 * this.m02 - this.m00 * this.m12) / determinant);
}
equals(other) {
return EqualsOfFloatNumbers(this.m00, other.m00, this._equalityTolerance)
&& EqualsOfFloatNumbers(this.m01, other.m01, this._equalityTolerance)
&& EqualsOfFloatNumbers(this.m02, other.m02, this._equalityTolerance)
&& EqualsOfFloatNumbers(this.m10, other.m10, this._equalityTolerance)
&& EqualsOfFloatNumbers(this.m11, other.m11, this._equalityTolerance)
&& EqualsOfFloatNumbers(this.m12, other.m12, this._equalityTolerance);
}
get _determinant() {
return this.m00 * this.m11 - this.m01 * this.m10;
}
}
//# sourceMappingURL=Matrix.js.map