1 |
|
2 |
|
3 |
|
4 |
|
5 | const DEG_TO_RAD = Math.PI / 180;
|
6 |
|
7 | export const identity: [number, number, number, number, number, number] = [
|
8 | 1,
|
9 | 0,
|
10 | 0,
|
11 | 1,
|
12 | 0,
|
13 | 0,
|
14 | ];
|
15 |
|
16 | let a = 1;
|
17 | let b = 0;
|
18 | let c = 0;
|
19 | let d = 1;
|
20 | let tx = 0;
|
21 | let ty = 0;
|
22 | let hasInitialState = true;
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 | export function reset() {
|
41 | if (hasInitialState) {
|
42 | return;
|
43 | }
|
44 | a = d = 1;
|
45 | b = c = tx = ty = 0;
|
46 | hasInitialState = true;
|
47 | }
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 | export function toArray(): [number, number, number, number, number, number] {
|
55 | if (hasInitialState) {
|
56 | return identity;
|
57 | }
|
58 | return [a, b, c, d, tx, ty];
|
59 | }
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 | export function append(
|
73 | a2: number,
|
74 | b2: number,
|
75 | c2: number,
|
76 | d2: number,
|
77 | tx2: number,
|
78 | ty2: number,
|
79 | ) {
|
80 | const change = a2 !== 1 || b2 !== 0 || c2 !== 0 || d2 !== 1;
|
81 | const translate = tx2 !== 0 || ty2 !== 0;
|
82 | if (!change && !translate) {
|
83 | return;
|
84 | }
|
85 | if (hasInitialState) {
|
86 | hasInitialState = false;
|
87 | a = a2;
|
88 | b = b2;
|
89 | c = c2;
|
90 | d = d2;
|
91 | tx = tx2;
|
92 | ty = ty2;
|
93 | return;
|
94 | }
|
95 | const a1 = a;
|
96 | const b1 = b;
|
97 | const c1 = c;
|
98 | const d1 = d;
|
99 | if (change) {
|
100 | a = a1 * a2 + c1 * b2;
|
101 | b = b1 * a2 + d1 * b2;
|
102 | c = a1 * c2 + c1 * d2;
|
103 | d = b1 * c2 + d1 * d2;
|
104 | }
|
105 | if (translate) {
|
106 | tx = a1 * tx2 + c1 * ty2 + tx;
|
107 | ty = b1 * tx2 + d1 * ty2 + ty;
|
108 | }
|
109 | }
|
110 |
|
111 |
|
112 |
|
113 |
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 | export function appendTransform(
|
131 | x: number,
|
132 | y: number,
|
133 | scaleX: number,
|
134 | scaleY: number,
|
135 | rotation: number,
|
136 | skewX: number,
|
137 | skewY: number,
|
138 | regX: number,
|
139 | regY: number,
|
140 | ) {
|
141 | if (
|
142 | x === 0 &&
|
143 | y === 0 &&
|
144 | scaleX === 1 &&
|
145 | scaleY === 1 &&
|
146 | rotation === 0 &&
|
147 | skewX === 0 &&
|
148 | skewY === 0 &&
|
149 | regX === 0 &&
|
150 | regY === 0
|
151 | ) {
|
152 | return;
|
153 | }
|
154 | let cos, sin;
|
155 | if (rotation % 360) {
|
156 | const r = rotation * DEG_TO_RAD;
|
157 | cos = Math.cos(r);
|
158 | sin = Math.sin(r);
|
159 | } else {
|
160 | cos = 1;
|
161 | sin = 0;
|
162 | }
|
163 |
|
164 | const a2 = cos * scaleX;
|
165 | const b2 = sin * scaleX;
|
166 | const c2 = -sin * scaleY;
|
167 | const d2 = cos * scaleY;
|
168 |
|
169 | if (skewX || skewY) {
|
170 | const b1 = Math.tan(skewY * DEG_TO_RAD);
|
171 | const c1 = Math.tan(skewX * DEG_TO_RAD);
|
172 | append(a2 + c1 * b2, b1 * a2 + b2, c2 + c1 * d2, b1 * c2 + d2, x, y);
|
173 | } else {
|
174 | append(a2, b2, c2, d2, x, y);
|
175 | }
|
176 |
|
177 | if (regX || regY) {
|
178 |
|
179 | tx -= regX * a + regY * c;
|
180 | ty -= regX * b + regY * d;
|
181 | hasInitialState = false;
|
182 | }
|
183 | }
|