@thednp/dommatrix 3.0.6 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/dommatrix.js CHANGED
@@ -2,8 +2,8 @@
2
2
  typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define([], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, global.CSSMatrix = factory());
3
3
  })(this, function() {
4
4
  //#region src/index.ts
5
- /** A model for JSONMatrix */
6
- const JSON_MATRIX = {
5
+ /** The property names of a JSONMatrix, used for compatibility checks */
6
+ const JSON_KEYS = Object.keys({
7
7
  a: 1,
8
8
  b: 0,
9
9
  c: 0,
@@ -28,14 +28,14 @@
28
28
  m44: 1,
29
29
  is2D: true,
30
30
  isIdentity: true
31
- };
31
+ });
32
32
  /** Checks if an array is compatible with CSSMatrix */
33
33
  const isCompatibleArray = (array) => {
34
34
  return (array instanceof Float64Array || array instanceof Float32Array || Array.isArray(array) && array.every((x) => typeof x === "number")) && [6, 16].some((x) => array.length === x);
35
35
  };
36
36
  /** Checks if an object is compatible with CSSMatrix */
37
37
  const isCompatibleObject = (object) => {
38
- return typeof DOMMatrix !== "undefined" && object instanceof DOMMatrix || object instanceof CSSMatrix || typeof object === "object" && Object.keys(JSON_MATRIX).every((k) => object && k in object);
38
+ return typeof DOMMatrix !== "undefined" && object instanceof DOMMatrix || object instanceof CSSMatrix || typeof object === "object" && JSON_KEYS.every((k) => object && k in object);
39
39
  };
40
40
  /**
41
41
  * Creates a new mutable `CSSMatrix` instance given an array of 16/6 floating point values.
@@ -45,80 +45,106 @@
45
45
  * the result is a 3D matrix. Otherwise, a TypeError exception is thrown.
46
46
  *
47
47
  * @param array an `Array` to feed values from.
48
+ * @param target an optional matrix instance to write the values into; when omitted
49
+ * a new matrix is returned. Used internally by `setMatrixValue` to mutate in place.
48
50
  * @return the resulted matrix.
49
51
  */
50
- const fromArray = (array) => {
51
- const m = new CSSMatrix();
52
- const a = Array.from(array);
53
- if (!isCompatibleArray(a)) throw TypeError(`CSSMatrix: "${a.join(",")}" must be an array with 6/16 numbers.`);
52
+ const fromArray = (array, target) => {
53
+ if (!isCompatibleArray(array)) throw TypeError(`CSSMatrix: "${Array.from(array).join(",")}" must be an array with 6/16 numbers.`);
54
54
  // istanbul ignore else @preserve
55
- if (a.length === 16) {
56
- const [m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44] = a;
57
- m.m11 = m11;
58
- m.a = m11;
59
- m.m21 = m21;
60
- m.c = m21;
61
- m.m31 = m31;
62
- m.m41 = m41;
63
- m.e = m41;
64
- m.m12 = m12;
65
- m.b = m12;
66
- m.m22 = m22;
67
- m.d = m22;
68
- m.m32 = m32;
69
- m.m42 = m42;
70
- m.f = m42;
71
- m.m13 = m13;
72
- m.m23 = m23;
73
- m.m33 = m33;
74
- m.m43 = m43;
75
- m.m14 = m14;
76
- m.m24 = m24;
77
- m.m34 = m34;
78
- m.m44 = m44;
79
- } else if (a.length === 6) {
80
- const [M11, M12, M21, M22, M41, M42] = a;
81
- m.m11 = M11;
82
- m.a = M11;
83
- m.m12 = M12;
84
- m.b = M12;
85
- m.m21 = M21;
86
- m.c = M21;
87
- m.m22 = M22;
88
- m.d = M22;
89
- m.m41 = M41;
90
- m.e = M41;
91
- m.m42 = M42;
92
- m.f = M42;
55
+ if (array.length === 16) {
56
+ const [m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44] = array;
57
+ return writeValues(target ?? new CSSMatrix(), m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44);
93
58
  }
94
- return m;
59
+ const [M11, M12, M21, M22, M41, M42] = array;
60
+ return writeValues(target ?? new CSSMatrix(), M11, M12, 0, 0, M21, M22, 0, 0, 0, 0, 1, 0, M41, M42, 0, 1);
61
+ };
62
+ /**
63
+ * Internal helper that writes the 16 values of a matrix into a given `CSSMatrix`
64
+ * instance. This is the single place where all 22 aliases (`a`-`f` and `m11`-`m44`)
65
+ * are written, so every write path keeps the instance monomorphic.
66
+ *
67
+ * @param target the matrix instance to write the values into.
68
+ * @param m11 the `m11` value.
69
+ * @param m12 the `m12` value.
70
+ * @param m13 the `m13` value.
71
+ * @param m14 the `m14` value.
72
+ * @param m21 the `m21` value.
73
+ * @param m22 the `m22` value.
74
+ * @param m23 the `m23` value.
75
+ * @param m24 the `m24` value.
76
+ * @param m31 the `m31` value.
77
+ * @param m32 the `m32` value.
78
+ * @param m33 the `m33` value.
79
+ * @param m34 the `m34` value.
80
+ * @param m41 the `m41` value.
81
+ * @param m42 the `m42` value.
82
+ * @param m43 the `m43` value.
83
+ * @param m44 the `m44` value.
84
+ * @return the target matrix.
85
+ */
86
+ const writeValues = (target, m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44) => {
87
+ target.m11 = m11;
88
+ target.a = m11;
89
+ target.m21 = m21;
90
+ target.c = m21;
91
+ target.m31 = m31;
92
+ target.m41 = m41;
93
+ target.e = m41;
94
+ target.m12 = m12;
95
+ target.b = m12;
96
+ target.m22 = m22;
97
+ target.d = m22;
98
+ target.m32 = m32;
99
+ target.m42 = m42;
100
+ target.f = m42;
101
+ target.m13 = m13;
102
+ target.m23 = m23;
103
+ target.m33 = m33;
104
+ target.m43 = m43;
105
+ target.m14 = m14;
106
+ target.m24 = m24;
107
+ target.m34 = m34;
108
+ target.m44 = m44;
109
+ return target;
110
+ };
111
+ /**
112
+ * Creates a new mutable `CSSMatrix` instance given the 16 values of the matrix.
113
+ * This internal helper skips the validation and intermediate array steps of
114
+ * `fromArray` and is used by the fast paths of the library.
115
+ *
116
+ * @param m11 the `m11` value.
117
+ * @param m12 the `m12` value.
118
+ * @param m13 the `m13` value.
119
+ * @param m14 the `m14` value.
120
+ * @param m21 the `m21` value.
121
+ * @param m22 the `m22` value.
122
+ * @param m23 the `m23` value.
123
+ * @param m24 the `m24` value.
124
+ * @param m31 the `m31` value.
125
+ * @param m32 the `m32` value.
126
+ * @param m33 the `m33` value.
127
+ * @param m34 the `m34` value.
128
+ * @param m41 the `m41` value.
129
+ * @param m42 the `m42` value.
130
+ * @param m43 the `m43` value.
131
+ * @param m44 the `m44` value.
132
+ * @return the resulted matrix.
133
+ */
134
+ const fromValues = (m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44) => {
135
+ return writeValues(new CSSMatrix(), m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44);
95
136
  };
96
137
  /**
97
138
  * Creates a new mutable `CSSMatrix` instance given an existing matrix or a
98
139
  * `DOMMatrix` instance which provides the values for its properties.
99
140
  *
100
141
  * @param m the source matrix to feed values from.
142
+ * @param target an optional matrix instance to write the values into; when omitted
143
+ * a new matrix is returned. Used internally by `setMatrixValue` to mutate in place.
101
144
  * @return the resulted matrix.
102
145
  */
103
- const fromMatrix = (m) => {
104
- if (isCompatibleObject(m)) return fromArray([
105
- m.m11,
106
- m.m12,
107
- m.m13,
108
- m.m14,
109
- m.m21,
110
- m.m22,
111
- m.m23,
112
- m.m24,
113
- m.m31,
114
- m.m32,
115
- m.m33,
116
- m.m34,
117
- m.m41,
118
- m.m42,
119
- m.m43,
120
- m.m44
121
- ]);
146
+ const fromMatrix = (m, target) => {
147
+ if (isCompatibleObject(m)) return writeValues(target ?? new CSSMatrix(), m.m11, m.m12, m.m13, m.m14, m.m21, m.m22, m.m23, m.m24, m.m31, m.m32, m.m33, m.m34, m.m41, m.m42, m.m43, m.m44);
122
148
  throw TypeError(`CSSMatrix: "${JSON.stringify(m)}" is not a DOMMatrix / CSSMatrix / JSON compatible object.`);
123
149
  };
124
150
  /**
@@ -139,8 +165,13 @@
139
165
  const str = String(source).replace(/\s/g, "");
140
166
  const m = new CSSMatrix();
141
167
  const invalidStringError = `CSSMatrix: invalid transform string "${source}"`;
142
- str.split(")").filter((f) => f).forEach((tf) => {
143
- const [prop, value] = tf.split("(");
168
+ const transformFn = /([\w-]+)\(([^)]*)\)/g;
169
+ let consumed = 0;
170
+ let match;
171
+ while (match = transformFn.exec(str)) {
172
+ const prop = match[1];
173
+ const value = match[2];
174
+ consumed += match[0].length;
144
175
  if (!value) throw TypeError(invalidStringError);
145
176
  const components = value.split(",").map((n) => n.includes("rad") ? parseFloat(n) * (180 / Math.PI) : parseFloat(n));
146
177
  const [x, y, z, a] = components;
@@ -192,7 +223,8 @@
192
223
  m[method](...axeValues);
193
224
  }
194
225
  else throw TypeError(invalidStringError);
195
- });
226
+ }
227
+ if (consumed !== str.length) throw TypeError(invalidStringError);
196
228
  return m;
197
229
  };
198
230
  /**
@@ -410,14 +442,16 @@
410
442
  return Skew(0, angle);
411
443
  };
412
444
  /**
413
- * Creates a new `CSSMatrix` resulted from the multiplication of two matrixes
414
- * and returns it. Both matrixes are not changed.
445
+ * Computes the multiplication of two matrixes and stores the result into the
446
+ * third matrix argument, which is also returned. Both source matrixes are
447
+ * not changed.
415
448
  *
416
449
  * @param m1 the first matrix.
417
450
  * @param m2 the second matrix.
451
+ * @param m the matrix to store the result into.
418
452
  * @return the resulted matrix.
419
453
  */
420
- const Multiply = (m1, m2) => {
454
+ const multiplyInto = (m1, m2, m) => {
421
455
  const m11 = m2.m11 * m1.m11 + m2.m12 * m1.m21 + m2.m13 * m1.m31 + m2.m14 * m1.m41;
422
456
  const m12 = m2.m11 * m1.m12 + m2.m12 * m1.m22 + m2.m13 * m1.m32 + m2.m14 * m1.m42;
423
457
  const m13 = m2.m11 * m1.m13 + m2.m12 * m1.m23 + m2.m13 * m1.m33 + m2.m14 * m1.m43;
@@ -434,24 +468,40 @@
434
468
  const m42 = m2.m41 * m1.m12 + m2.m42 * m1.m22 + m2.m43 * m1.m32 + m2.m44 * m1.m42;
435
469
  const m43 = m2.m41 * m1.m13 + m2.m42 * m1.m23 + m2.m43 * m1.m33 + m2.m44 * m1.m43;
436
470
  const m44 = m2.m41 * m1.m14 + m2.m42 * m1.m24 + m2.m43 * m1.m34 + m2.m44 * m1.m44;
437
- return fromArray([
438
- m11,
439
- m12,
440
- m13,
441
- m14,
442
- m21,
443
- m22,
444
- m23,
445
- m24,
446
- m31,
447
- m32,
448
- m33,
449
- m34,
450
- m41,
451
- m42,
452
- m43,
453
- m44
454
- ]);
471
+ m.m11 = m11;
472
+ m.a = m11;
473
+ m.m21 = m21;
474
+ m.c = m21;
475
+ m.m31 = m31;
476
+ m.m41 = m41;
477
+ m.e = m41;
478
+ m.m12 = m12;
479
+ m.b = m12;
480
+ m.m22 = m22;
481
+ m.d = m22;
482
+ m.m32 = m32;
483
+ m.m42 = m42;
484
+ m.f = m42;
485
+ m.m13 = m13;
486
+ m.m23 = m23;
487
+ m.m33 = m33;
488
+ m.m43 = m43;
489
+ m.m14 = m14;
490
+ m.m24 = m24;
491
+ m.m34 = m34;
492
+ m.m44 = m44;
493
+ return m;
494
+ };
495
+ /**
496
+ * Creates a new `CSSMatrix` resulted from the multiplication of two matrixes
497
+ * and returns it. Both matrixes are not changed.
498
+ *
499
+ * @param m1 the first matrix.
500
+ * @param m2 the second matrix.
501
+ * @return the resulted matrix.
502
+ */
503
+ const Multiply = (m1, m2) => {
504
+ return multiplyInto(m1, m2, new CSSMatrix());
455
505
  };
456
506
  /**
457
507
  * Creates and returns a new `DOMMatrix` compatible instance
@@ -500,6 +550,11 @@
500
550
  * * a 6/16 elements *Array*.
501
551
  */
502
552
  constructor(init) {
553
+ if (init) {
554
+ if (typeof init === "string" && init.length && init !== "none") return fromString(init);
555
+ if (Array.isArray(init) || init instanceof Float64Array || init instanceof Float32Array) return fromArray(init);
556
+ if (typeof init === "object") return fromMatrix(init);
557
+ }
503
558
  this.a = 1;
504
559
  this.b = 0;
505
560
  this.c = 0;
@@ -522,7 +577,6 @@
522
577
  this.m42 = 0;
523
578
  this.m43 = 0;
524
579
  this.m44 = 1;
525
- if (init) return this.setMatrixValue(init);
526
580
  return this;
527
581
  }
528
582
  /**
@@ -555,13 +609,19 @@
555
609
  * This method expects valid *matrix()* / *matrix3d()* string values, as well
556
610
  * as other transform functions like *translateX(10px)*.
557
611
  *
612
+ * The matrix is mutated in place (the same instance is returned), matching
613
+ * the behavior of the native `DOMMatrix.setMatrixValue()`.
614
+ *
558
615
  * @param source
559
- * @return the matrix instance
616
+ * @return the current matrix instance
560
617
  */
561
618
  setMatrixValue(source) {
562
- if (typeof source === "string" && source.length && source !== "none") return fromString(source);
563
- if (Array.isArray(source) || source instanceof Float64Array || source instanceof Float32Array) return fromArray(source);
564
- if (typeof source === "object") return fromMatrix(source);
619
+ if (typeof source === "string" && source.length && source !== "none") {
620
+ const m = fromString(source);
621
+ return writeValues(this, m.m11, m.m12, m.m13, m.m14, m.m21, m.m22, m.m23, m.m24, m.m31, m.m32, m.m33, m.m34, m.m41, m.m42, m.m43, m.m44);
622
+ }
623
+ if (Array.isArray(source) || source instanceof Float64Array || source instanceof Float32Array) return fromArray(source, this);
624
+ if (typeof source === "object") return fromMatrix(source, this);
565
625
  return this;
566
626
  }
567
627
  /**
@@ -573,7 +633,31 @@
573
633
  * @return an *Array* representation of the matrix
574
634
  */
575
635
  toFloat32Array(is2D) {
576
- return Float32Array.from(toArray(this, is2D));
636
+ return is2D ? new Float32Array([
637
+ this.a,
638
+ this.b,
639
+ this.c,
640
+ this.d,
641
+ this.e,
642
+ this.f
643
+ ]) : new Float32Array([
644
+ this.m11,
645
+ this.m12,
646
+ this.m13,
647
+ this.m14,
648
+ this.m21,
649
+ this.m22,
650
+ this.m23,
651
+ this.m24,
652
+ this.m31,
653
+ this.m32,
654
+ this.m33,
655
+ this.m34,
656
+ this.m41,
657
+ this.m42,
658
+ this.m43,
659
+ this.m44
660
+ ]);
577
661
  }
578
662
  /**
579
663
  * Returns a *Float64Array* containing elements which comprise the matrix.
@@ -584,7 +668,31 @@
584
668
  * @return an *Array* representation of the matrix
585
669
  */
586
670
  toFloat64Array(is2D) {
587
- return Float64Array.from(toArray(this, is2D));
671
+ return is2D ? new Float64Array([
672
+ this.a,
673
+ this.b,
674
+ this.c,
675
+ this.d,
676
+ this.e,
677
+ this.f
678
+ ]) : new Float64Array([
679
+ this.m11,
680
+ this.m12,
681
+ this.m13,
682
+ this.m14,
683
+ this.m21,
684
+ this.m22,
685
+ this.m23,
686
+ this.m24,
687
+ this.m31,
688
+ this.m32,
689
+ this.m33,
690
+ this.m34,
691
+ this.m41,
692
+ this.m42,
693
+ this.m43,
694
+ this.m44
695
+ ]);
588
696
  }
589
697
  /**
590
698
  * Creates and returns a string representation of the matrix in `CSS` matrix syntax,
@@ -613,7 +721,28 @@
613
721
  toJSON() {
614
722
  const { is2D, isIdentity } = this;
615
723
  return {
616
- ...this,
724
+ a: this.a,
725
+ b: this.b,
726
+ c: this.c,
727
+ d: this.d,
728
+ e: this.e,
729
+ f: this.f,
730
+ m11: this.m11,
731
+ m12: this.m12,
732
+ m13: this.m13,
733
+ m14: this.m14,
734
+ m21: this.m21,
735
+ m22: this.m22,
736
+ m23: this.m23,
737
+ m24: this.m24,
738
+ m31: this.m31,
739
+ m32: this.m32,
740
+ m33: this.m33,
741
+ m34: this.m34,
742
+ m41: this.m41,
743
+ m42: this.m42,
744
+ m43: this.m43,
745
+ m44: this.m44,
617
746
  is2D,
618
747
  isIdentity
619
748
  };
@@ -641,7 +770,14 @@
641
770
  * @return The resulted matrix
642
771
  */
643
772
  translate(x, y, z) {
644
- return this.multiply(Translate(x, y ?? 0, z ?? 0));
773
+ const ty = y ?? 0;
774
+ const tz = z ?? 0;
775
+ const { m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44 } = this;
776
+ const n41 = x * m11 + ty * m21 + tz * m31 + m41;
777
+ const n42 = x * m12 + ty * m22 + tz * m32 + m42;
778
+ const n43 = x * m13 + ty * m23 + tz * m33 + m43;
779
+ const n44 = x * m14 + ty * m24 + tz * m34 + m44;
780
+ return fromValues(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, n41, n42, n43, n44);
645
781
  }
646
782
  /**
647
783
  * The scale method returns a new matrix which is this matrix post multiplied by
@@ -655,7 +791,10 @@
655
791
  * @return The resulted matrix
656
792
  */
657
793
  scale(x, y, z) {
658
- return this.multiply(Scale(x, y ?? x, z ?? 1));
794
+ const sy = y ?? x;
795
+ const sz = z ?? 1;
796
+ const { m41, m42, m43, m44 } = this;
797
+ return fromValues(this.m11 * x, this.m12 * x, this.m13 * x, this.m14 * x, this.m21 * sy, this.m22 * sy, this.m23 * sy, this.m24 * sy, this.m31 * sz, this.m32 * sz, this.m33 * sz, this.m34 * sz, m41, m42, m43, m44);
659
798
  }
660
799
  /**
661
800
  * The rotate method returns a new matrix which is this matrix post multiplied
@@ -710,7 +849,7 @@
710
849
  * @return The resulted matrix
711
850
  */
712
851
  skewX(angle) {
713
- return this.multiply(SkewX(angle));
852
+ return this.skew(angle, 0);
714
853
  }
715
854
  /**
716
855
  * Specifies a skew transformation along the `y-axis` by the given angle.
@@ -720,7 +859,7 @@
720
859
  * @return The resulted matrix
721
860
  */
722
861
  skewY(angle) {
723
- return this.multiply(SkewY(angle));
862
+ return this.skew(0, angle);
724
863
  }
725
864
  /**
726
865
  * Specifies a skew transformation along both the `x-axis` and `y-axis`.
@@ -731,7 +870,10 @@
731
870
  * @return The resulted matrix
732
871
  */
733
872
  skew(angleX, angleY) {
734
- return this.multiply(Skew(angleX, angleY));
873
+ const tX = angleX ? Math.tan(angleX * Math.PI / 180) : 0;
874
+ const tY = angleY ? Math.tan(angleY * Math.PI / 180) : 0;
875
+ const { m11, m12, m13, m14, m21, m22, m23, m24 } = this;
876
+ return fromValues(m11 + tY * m21, m12 + tY * m22, m13 + tY * m23, m14 + tY * m24, tX * m11 + m21, tX * m12 + m22, tX * m13 + m23, tX * m14 + m24, this.m31, this.m32, this.m33, this.m34, this.m41, this.m42, this.m43, this.m44);
735
877
  }
736
878
  /**
737
879
  * Modifies the current matrix by post-multiplying it with another matrix.
@@ -741,8 +883,7 @@
741
883
  * @return this matrix (modified)
742
884
  */
743
885
  multiplySelf(m2) {
744
- const result = Multiply(this, m2);
745
- Object.assign(this, result);
886
+ multiplyInto(this, m2, this);
746
887
  return this;
747
888
  }
748
889
  /**
@@ -755,7 +896,20 @@
755
896
  * @return this matrix (modified)
756
897
  */
757
898
  translateSelf(x, y, z) {
758
- return this.multiplySelf(Translate(x, y ?? 0, z ?? 0));
899
+ const ty = y ?? 0;
900
+ const tz = z ?? 0;
901
+ const { m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44 } = this;
902
+ const n41 = x * m11 + ty * m21 + tz * m31 + m41;
903
+ const n42 = x * m12 + ty * m22 + tz * m32 + m42;
904
+ const n43 = x * m13 + ty * m23 + tz * m33 + m43;
905
+ const n44 = x * m14 + ty * m24 + tz * m34 + m44;
906
+ this.m41 = n41;
907
+ this.e = n41;
908
+ this.m42 = n42;
909
+ this.f = n42;
910
+ this.m43 = n43;
911
+ this.m44 = n44;
912
+ return this;
759
913
  }
760
914
  /**
761
915
  * Modifies the current matrix by post-multiplying it with a scale matrix.
@@ -767,7 +921,25 @@
767
921
  * @return this matrix (modified)
768
922
  */
769
923
  scaleSelf(x, y, z) {
770
- return this.multiplySelf(Scale(x, y ?? x, z ?? 1));
924
+ const sy = y ?? x;
925
+ const sz = z ?? 1;
926
+ this.m11 *= x;
927
+ this.a *= x;
928
+ this.m12 *= x;
929
+ this.b *= x;
930
+ this.m13 *= x;
931
+ this.m14 *= x;
932
+ this.m21 *= sy;
933
+ this.c *= sy;
934
+ this.m22 *= sy;
935
+ this.d *= sy;
936
+ this.m23 *= sy;
937
+ this.m24 *= sy;
938
+ this.m31 *= sz;
939
+ this.m32 *= sz;
940
+ this.m33 *= sz;
941
+ this.m34 *= sz;
942
+ return this;
771
943
  }
772
944
  /**
773
945
  * Modifies the current matrix by post-multiplying it with a rotation matrix.
@@ -818,7 +990,7 @@
818
990
  * @return this matrix (modified)
819
991
  */
820
992
  skewXSelf(angle) {
821
- return this.multiplySelf(SkewX(angle));
993
+ return this.skewSelf(angle, 0);
822
994
  }
823
995
  /**
824
996
  * Modifies the current matrix by post-multiplying it with a skewY matrix.
@@ -828,7 +1000,7 @@
828
1000
  * @return this matrix (modified)
829
1001
  */
830
1002
  skewYSelf(angle) {
831
- return this.multiplySelf(SkewY(angle));
1003
+ return this.skewSelf(0, angle);
832
1004
  }
833
1005
  /**
834
1006
  * Modifies the current matrix by post-multiplying it with a skew matrix.
@@ -839,7 +1011,30 @@
839
1011
  * @return this matrix (modified)
840
1012
  */
841
1013
  skewSelf(angleX, angleY) {
842
- return this.multiplySelf(Skew(angleX, angleY));
1014
+ const tX = angleX ? Math.tan(angleX * Math.PI / 180) : 0;
1015
+ const tY = angleY ? Math.tan(angleY * Math.PI / 180) : 0;
1016
+ const { m11, m12, m13, m14, m21, m22, m23, m24 } = this;
1017
+ const n11 = m11 + tY * m21;
1018
+ const n12 = m12 + tY * m22;
1019
+ const n13 = m13 + tY * m23;
1020
+ const n14 = m14 + tY * m24;
1021
+ const n21 = tX * m11 + m21;
1022
+ const n22 = tX * m12 + m22;
1023
+ const n23 = tX * m13 + m23;
1024
+ const n24 = tX * m14 + m24;
1025
+ this.m11 = n11;
1026
+ this.a = n11;
1027
+ this.m12 = n12;
1028
+ this.b = n12;
1029
+ this.m13 = n13;
1030
+ this.m14 = n14;
1031
+ this.m21 = n21;
1032
+ this.c = n21;
1033
+ this.m22 = n22;
1034
+ this.d = n22;
1035
+ this.m23 = n23;
1036
+ this.m24 = n24;
1037
+ return this;
843
1038
  }
844
1039
  /**
845
1040
  * Transforms a specified vector using the matrix, returning a new