modern-path2d 0.0.4 → 0.1.0
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/README.md +39 -1
- package/dist/index.cjs +1567 -84
- package/dist/index.d.cts +171 -124
- package/dist/index.d.mts +171 -124
- package/dist/index.d.ts +171 -124
- package/dist/index.js +1 -1
- package/dist/index.mjs +1566 -82
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,205 @@
|
|
|
1
|
+
var __defProp$6 = Object.defineProperty;
|
|
2
|
+
var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField$6 = (obj, key, value) => {
|
|
4
|
+
__defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
|
+
return value;
|
|
6
|
+
};
|
|
7
|
+
class Matrix3 {
|
|
8
|
+
constructor(n11 = 1, n12 = 0, n13 = 0, n21 = 0, n22 = 1, n23 = 0, n31 = 0, n32 = 0, n33 = 1) {
|
|
9
|
+
__publicField$6(this, "elements", []);
|
|
10
|
+
this.set(n11, n12, n13, n21, n22, n23, n31, n32, n33);
|
|
11
|
+
}
|
|
12
|
+
set(n11, n12, n13, n21, n22, n23, n31, n32, n33) {
|
|
13
|
+
const te = this.elements;
|
|
14
|
+
te[0] = n11;
|
|
15
|
+
te[1] = n21;
|
|
16
|
+
te[2] = n31;
|
|
17
|
+
te[3] = n12;
|
|
18
|
+
te[4] = n22;
|
|
19
|
+
te[5] = n32;
|
|
20
|
+
te[6] = n13;
|
|
21
|
+
te[7] = n23;
|
|
22
|
+
te[8] = n33;
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
25
|
+
identity() {
|
|
26
|
+
this.set(
|
|
27
|
+
1,
|
|
28
|
+
0,
|
|
29
|
+
0,
|
|
30
|
+
0,
|
|
31
|
+
1,
|
|
32
|
+
0,
|
|
33
|
+
0,
|
|
34
|
+
0,
|
|
35
|
+
1
|
|
36
|
+
);
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
copy(m) {
|
|
40
|
+
const te = this.elements;
|
|
41
|
+
const me = m.elements;
|
|
42
|
+
te[0] = me[0];
|
|
43
|
+
te[1] = me[1];
|
|
44
|
+
te[2] = me[2];
|
|
45
|
+
te[3] = me[3];
|
|
46
|
+
te[4] = me[4];
|
|
47
|
+
te[5] = me[5];
|
|
48
|
+
te[6] = me[6];
|
|
49
|
+
te[7] = me[7];
|
|
50
|
+
te[8] = me[8];
|
|
51
|
+
return this;
|
|
52
|
+
}
|
|
53
|
+
multiply(m) {
|
|
54
|
+
return this.multiplyMatrices(this, m);
|
|
55
|
+
}
|
|
56
|
+
premultiply(m) {
|
|
57
|
+
return this.multiplyMatrices(m, this);
|
|
58
|
+
}
|
|
59
|
+
multiplyMatrices(a, b) {
|
|
60
|
+
const ae = a.elements;
|
|
61
|
+
const be = b.elements;
|
|
62
|
+
const te = this.elements;
|
|
63
|
+
const a11 = ae[0];
|
|
64
|
+
const a12 = ae[3];
|
|
65
|
+
const a13 = ae[6];
|
|
66
|
+
const a21 = ae[1];
|
|
67
|
+
const a22 = ae[4];
|
|
68
|
+
const a23 = ae[7];
|
|
69
|
+
const a31 = ae[2];
|
|
70
|
+
const a32 = ae[5];
|
|
71
|
+
const a33 = ae[8];
|
|
72
|
+
const b11 = be[0];
|
|
73
|
+
const b12 = be[3];
|
|
74
|
+
const b13 = be[6];
|
|
75
|
+
const b21 = be[1];
|
|
76
|
+
const b22 = be[4];
|
|
77
|
+
const b23 = be[7];
|
|
78
|
+
const b31 = be[2];
|
|
79
|
+
const b32 = be[5];
|
|
80
|
+
const b33 = be[8];
|
|
81
|
+
te[0] = a11 * b11 + a12 * b21 + a13 * b31;
|
|
82
|
+
te[3] = a11 * b12 + a12 * b22 + a13 * b32;
|
|
83
|
+
te[6] = a11 * b13 + a12 * b23 + a13 * b33;
|
|
84
|
+
te[1] = a21 * b11 + a22 * b21 + a23 * b31;
|
|
85
|
+
te[4] = a21 * b12 + a22 * b22 + a23 * b32;
|
|
86
|
+
te[7] = a21 * b13 + a22 * b23 + a23 * b33;
|
|
87
|
+
te[2] = a31 * b11 + a32 * b21 + a33 * b31;
|
|
88
|
+
te[5] = a31 * b12 + a32 * b22 + a33 * b32;
|
|
89
|
+
te[8] = a31 * b13 + a32 * b23 + a33 * b33;
|
|
90
|
+
return this;
|
|
91
|
+
}
|
|
92
|
+
invert() {
|
|
93
|
+
const te = this.elements;
|
|
94
|
+
const n11 = te[0];
|
|
95
|
+
const n21 = te[1];
|
|
96
|
+
const n31 = te[2];
|
|
97
|
+
const n12 = te[3];
|
|
98
|
+
const n22 = te[4];
|
|
99
|
+
const n32 = te[5];
|
|
100
|
+
const n13 = te[6];
|
|
101
|
+
const n23 = te[7];
|
|
102
|
+
const n33 = te[8];
|
|
103
|
+
const t11 = n33 * n22 - n32 * n23;
|
|
104
|
+
const t12 = n32 * n13 - n33 * n12;
|
|
105
|
+
const t13 = n23 * n12 - n22 * n13;
|
|
106
|
+
const det = n11 * t11 + n21 * t12 + n31 * t13;
|
|
107
|
+
if (det === 0)
|
|
108
|
+
return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0);
|
|
109
|
+
const detInv = 1 / det;
|
|
110
|
+
te[0] = t11 * detInv;
|
|
111
|
+
te[1] = (n31 * n23 - n33 * n21) * detInv;
|
|
112
|
+
te[2] = (n32 * n21 - n31 * n22) * detInv;
|
|
113
|
+
te[3] = t12 * detInv;
|
|
114
|
+
te[4] = (n33 * n11 - n31 * n13) * detInv;
|
|
115
|
+
te[5] = (n31 * n12 - n32 * n11) * detInv;
|
|
116
|
+
te[6] = t13 * detInv;
|
|
117
|
+
te[7] = (n21 * n13 - n23 * n11) * detInv;
|
|
118
|
+
te[8] = (n22 * n11 - n21 * n12) * detInv;
|
|
119
|
+
return this;
|
|
120
|
+
}
|
|
121
|
+
transpose() {
|
|
122
|
+
let tmp;
|
|
123
|
+
const m = this.elements;
|
|
124
|
+
tmp = m[1];
|
|
125
|
+
m[1] = m[3];
|
|
126
|
+
m[3] = tmp;
|
|
127
|
+
tmp = m[2];
|
|
128
|
+
m[2] = m[6];
|
|
129
|
+
m[6] = tmp;
|
|
130
|
+
tmp = m[5];
|
|
131
|
+
m[5] = m[7];
|
|
132
|
+
m[7] = tmp;
|
|
133
|
+
return this;
|
|
134
|
+
}
|
|
135
|
+
scale(sx, sy) {
|
|
136
|
+
this.premultiply(_m3.makeScale(sx, sy));
|
|
137
|
+
return this;
|
|
138
|
+
}
|
|
139
|
+
rotate(theta) {
|
|
140
|
+
this.premultiply(_m3.makeRotation(-theta));
|
|
141
|
+
return this;
|
|
142
|
+
}
|
|
143
|
+
translate(tx, ty) {
|
|
144
|
+
this.premultiply(_m3.makeTranslation(tx, ty));
|
|
145
|
+
return this;
|
|
146
|
+
}
|
|
147
|
+
makeTranslation(x, y) {
|
|
148
|
+
this.set(
|
|
149
|
+
1,
|
|
150
|
+
0,
|
|
151
|
+
x,
|
|
152
|
+
0,
|
|
153
|
+
1,
|
|
154
|
+
y,
|
|
155
|
+
0,
|
|
156
|
+
0,
|
|
157
|
+
1
|
|
158
|
+
);
|
|
159
|
+
return this;
|
|
160
|
+
}
|
|
161
|
+
makeRotation(theta) {
|
|
162
|
+
const c = Math.cos(theta);
|
|
163
|
+
const s = Math.sin(theta);
|
|
164
|
+
this.set(
|
|
165
|
+
c,
|
|
166
|
+
-s,
|
|
167
|
+
0,
|
|
168
|
+
s,
|
|
169
|
+
c,
|
|
170
|
+
0,
|
|
171
|
+
0,
|
|
172
|
+
0,
|
|
173
|
+
1
|
|
174
|
+
);
|
|
175
|
+
return this;
|
|
176
|
+
}
|
|
177
|
+
makeScale(x, y) {
|
|
178
|
+
this.set(
|
|
179
|
+
x,
|
|
180
|
+
0,
|
|
181
|
+
0,
|
|
182
|
+
0,
|
|
183
|
+
y,
|
|
184
|
+
0,
|
|
185
|
+
0,
|
|
186
|
+
0,
|
|
187
|
+
1
|
|
188
|
+
);
|
|
189
|
+
return this;
|
|
190
|
+
}
|
|
191
|
+
fromArray(array, offset = 0) {
|
|
192
|
+
for (let i = 0; i < 9; i++) {
|
|
193
|
+
this.elements[i] = array[i + offset];
|
|
194
|
+
}
|
|
195
|
+
return this;
|
|
196
|
+
}
|
|
197
|
+
clone() {
|
|
198
|
+
return new this.constructor().fromArray(this.elements);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
const _m3 = /* @__PURE__ */ new Matrix3();
|
|
202
|
+
|
|
1
203
|
class Point2D {
|
|
2
204
|
constructor(x = 0, y = 0) {
|
|
3
205
|
this.x = x;
|
|
@@ -59,6 +261,15 @@ class Point2D {
|
|
|
59
261
|
equals(point) {
|
|
60
262
|
return this.x === point.x && this.y === point.y;
|
|
61
263
|
}
|
|
264
|
+
applyMatrix3(matrix3) {
|
|
265
|
+
const [a, c, tx, b, d, ty] = matrix3.elements;
|
|
266
|
+
const { x, y } = this;
|
|
267
|
+
this.set(
|
|
268
|
+
a * x + c * y + tx,
|
|
269
|
+
b * x + d * y + ty
|
|
270
|
+
);
|
|
271
|
+
return this;
|
|
272
|
+
}
|
|
62
273
|
copy(point) {
|
|
63
274
|
this.x = point.x;
|
|
64
275
|
this.y = point.y;
|
|
@@ -69,6 +280,574 @@ class Point2D {
|
|
|
69
280
|
}
|
|
70
281
|
}
|
|
71
282
|
|
|
283
|
+
function svgAngle(ux, uy, vx, vy) {
|
|
284
|
+
const dot = ux * vx + uy * vy;
|
|
285
|
+
const len = Math.sqrt(ux * ux + uy * uy) * Math.sqrt(vx * vx + vy * vy);
|
|
286
|
+
let ang = Math.acos(Math.max(-1, Math.min(1, dot / len)));
|
|
287
|
+
if (ux * vy - uy * vx < 0)
|
|
288
|
+
ang = -ang;
|
|
289
|
+
return ang;
|
|
290
|
+
}
|
|
291
|
+
function parseArcCommand(path, rx, ry, xAxisRotation, largeArcFlag, sweepFlag, start, end) {
|
|
292
|
+
if (rx === 0 || ry === 0) {
|
|
293
|
+
path.lineTo(end.x, end.y);
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
xAxisRotation = xAxisRotation * Math.PI / 180;
|
|
297
|
+
rx = Math.abs(rx);
|
|
298
|
+
ry = Math.abs(ry);
|
|
299
|
+
const dx2 = (start.x - end.x) / 2;
|
|
300
|
+
const dy2 = (start.y - end.y) / 2;
|
|
301
|
+
const x1p = Math.cos(xAxisRotation) * dx2 + Math.sin(xAxisRotation) * dy2;
|
|
302
|
+
const y1p = -Math.sin(xAxisRotation) * dx2 + Math.cos(xAxisRotation) * dy2;
|
|
303
|
+
let rxs = rx * rx;
|
|
304
|
+
let rys = ry * ry;
|
|
305
|
+
const x1ps = x1p * x1p;
|
|
306
|
+
const y1ps = y1p * y1p;
|
|
307
|
+
const cr = x1ps / rxs + y1ps / rys;
|
|
308
|
+
if (cr > 1) {
|
|
309
|
+
const s = Math.sqrt(cr);
|
|
310
|
+
rx = s * rx;
|
|
311
|
+
ry = s * ry;
|
|
312
|
+
rxs = rx * rx;
|
|
313
|
+
rys = ry * ry;
|
|
314
|
+
}
|
|
315
|
+
const dq = rxs * y1ps + rys * x1ps;
|
|
316
|
+
const pq = (rxs * rys - dq) / dq;
|
|
317
|
+
let q = Math.sqrt(Math.max(0, pq));
|
|
318
|
+
if (largeArcFlag === sweepFlag)
|
|
319
|
+
q = -q;
|
|
320
|
+
const cxp = q * rx * y1p / ry;
|
|
321
|
+
const cyp = -q * ry * x1p / rx;
|
|
322
|
+
const cx = Math.cos(xAxisRotation) * cxp - Math.sin(xAxisRotation) * cyp + (start.x + end.x) / 2;
|
|
323
|
+
const cy = Math.sin(xAxisRotation) * cxp + Math.cos(xAxisRotation) * cyp + (start.y + end.y) / 2;
|
|
324
|
+
const theta = svgAngle(1, 0, (x1p - cxp) / rx, (y1p - cyp) / ry);
|
|
325
|
+
const delta = svgAngle((x1p - cxp) / rx, (y1p - cyp) / ry, (-x1p - cxp) / rx, (-y1p - cyp) / ry) % (Math.PI * 2);
|
|
326
|
+
path.currentPath.absellipse(cx, cy, rx, ry, theta, theta + delta, sweepFlag === 0, xAxisRotation);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function getReflection(a, b) {
|
|
330
|
+
return a - (b - a);
|
|
331
|
+
}
|
|
332
|
+
function addPathCommandsToPath2D(commands, path) {
|
|
333
|
+
const point = new Point2D();
|
|
334
|
+
const control = new Point2D();
|
|
335
|
+
const firstPoint = new Point2D();
|
|
336
|
+
let isFirstPoint = true;
|
|
337
|
+
let doSetFirstPoint = false;
|
|
338
|
+
for (let i = 0, l = commands.length; i < l; i++) {
|
|
339
|
+
const command = commands[i];
|
|
340
|
+
if (isFirstPoint) {
|
|
341
|
+
doSetFirstPoint = true;
|
|
342
|
+
isFirstPoint = false;
|
|
343
|
+
}
|
|
344
|
+
if (command.type === "m" || command.type === "M") {
|
|
345
|
+
if (command.type === "m") {
|
|
346
|
+
point.x += command.x;
|
|
347
|
+
point.y += command.y;
|
|
348
|
+
} else {
|
|
349
|
+
point.x = command.x;
|
|
350
|
+
point.y = command.y;
|
|
351
|
+
}
|
|
352
|
+
control.x = point.x;
|
|
353
|
+
control.y = point.y;
|
|
354
|
+
path.moveTo(point.x, point.y);
|
|
355
|
+
if (i === 0)
|
|
356
|
+
firstPoint.copy(point);
|
|
357
|
+
} else if (command.type === "h" || command.type === "H") {
|
|
358
|
+
if (command.type === "h") {
|
|
359
|
+
point.x += command.x;
|
|
360
|
+
} else {
|
|
361
|
+
point.x = command.x;
|
|
362
|
+
}
|
|
363
|
+
control.x = point.x;
|
|
364
|
+
control.y = point.y;
|
|
365
|
+
path.lineTo(point.x, point.y);
|
|
366
|
+
if (doSetFirstPoint)
|
|
367
|
+
firstPoint.copy(point);
|
|
368
|
+
} else if (command.type === "v" || command.type === "V") {
|
|
369
|
+
if (command.type === "v") {
|
|
370
|
+
point.y += command.y;
|
|
371
|
+
} else {
|
|
372
|
+
point.y = command.y;
|
|
373
|
+
}
|
|
374
|
+
control.x = point.x;
|
|
375
|
+
control.y = point.y;
|
|
376
|
+
path.lineTo(point.x, point.y);
|
|
377
|
+
if (doSetFirstPoint)
|
|
378
|
+
firstPoint.copy(point);
|
|
379
|
+
} else if (command.type === "l" || command.type === "L") {
|
|
380
|
+
if (command.type === "l") {
|
|
381
|
+
point.x += command.x;
|
|
382
|
+
point.y += command.y;
|
|
383
|
+
} else {
|
|
384
|
+
point.x = command.x;
|
|
385
|
+
point.y = command.y;
|
|
386
|
+
}
|
|
387
|
+
control.x = point.x;
|
|
388
|
+
control.y = point.y;
|
|
389
|
+
path.lineTo(point.x, point.y);
|
|
390
|
+
if (doSetFirstPoint)
|
|
391
|
+
firstPoint.copy(point);
|
|
392
|
+
} else if (command.type === "c" || command.type === "C") {
|
|
393
|
+
if (command.type === "c") {
|
|
394
|
+
path.bezierCurveTo(
|
|
395
|
+
point.x + command.x1,
|
|
396
|
+
point.y + command.y1,
|
|
397
|
+
point.x + command.x2,
|
|
398
|
+
point.y + command.y2,
|
|
399
|
+
point.x + command.x,
|
|
400
|
+
point.y + command.y
|
|
401
|
+
);
|
|
402
|
+
control.x = point.x + command.x2;
|
|
403
|
+
control.y = point.y + command.y2;
|
|
404
|
+
point.x += command.x;
|
|
405
|
+
point.y += command.y;
|
|
406
|
+
} else {
|
|
407
|
+
path.bezierCurveTo(
|
|
408
|
+
command.x1,
|
|
409
|
+
command.y1,
|
|
410
|
+
command.x2,
|
|
411
|
+
command.y2,
|
|
412
|
+
command.x,
|
|
413
|
+
command.y
|
|
414
|
+
);
|
|
415
|
+
control.x = command.x2;
|
|
416
|
+
control.y = command.y2;
|
|
417
|
+
point.x = command.x;
|
|
418
|
+
point.y = command.y;
|
|
419
|
+
}
|
|
420
|
+
if (doSetFirstPoint)
|
|
421
|
+
firstPoint.copy(point);
|
|
422
|
+
} else if (command.type === "s" || command.type === "S") {
|
|
423
|
+
if (command.type === "s") {
|
|
424
|
+
path.bezierCurveTo(
|
|
425
|
+
getReflection(point.x, control.x),
|
|
426
|
+
getReflection(point.y, control.y),
|
|
427
|
+
point.x + command.x2,
|
|
428
|
+
point.y + command.y2,
|
|
429
|
+
point.x + command.x,
|
|
430
|
+
point.y + command.y
|
|
431
|
+
);
|
|
432
|
+
control.x = point.x + command.x2;
|
|
433
|
+
control.y = point.y + command.y2;
|
|
434
|
+
point.x += command.x;
|
|
435
|
+
point.y += command.y;
|
|
436
|
+
} else {
|
|
437
|
+
path.bezierCurveTo(
|
|
438
|
+
getReflection(point.x, control.x),
|
|
439
|
+
getReflection(point.y, control.y),
|
|
440
|
+
command.x2,
|
|
441
|
+
command.y2,
|
|
442
|
+
command.x,
|
|
443
|
+
command.y
|
|
444
|
+
);
|
|
445
|
+
control.x = command.x2;
|
|
446
|
+
control.y = command.y2;
|
|
447
|
+
point.x = command.x;
|
|
448
|
+
point.y = command.y;
|
|
449
|
+
}
|
|
450
|
+
if (doSetFirstPoint)
|
|
451
|
+
firstPoint.copy(point);
|
|
452
|
+
} else if (command.type === "q" || command.type === "Q") {
|
|
453
|
+
if (command.type === "q") {
|
|
454
|
+
path.quadraticCurveTo(
|
|
455
|
+
point.x + command.x1,
|
|
456
|
+
point.y + command.y1,
|
|
457
|
+
point.x + command.x,
|
|
458
|
+
point.y + command.y
|
|
459
|
+
);
|
|
460
|
+
control.x = point.x + command.x1;
|
|
461
|
+
control.y = point.y + command.y1;
|
|
462
|
+
point.x += command.x;
|
|
463
|
+
point.y += command.y;
|
|
464
|
+
} else {
|
|
465
|
+
path.quadraticCurveTo(
|
|
466
|
+
command.x1,
|
|
467
|
+
command.y1,
|
|
468
|
+
command.x,
|
|
469
|
+
command.y
|
|
470
|
+
);
|
|
471
|
+
control.x = command.x1;
|
|
472
|
+
control.y = command.y1;
|
|
473
|
+
point.x = command.x;
|
|
474
|
+
point.y = command.y;
|
|
475
|
+
}
|
|
476
|
+
if (doSetFirstPoint)
|
|
477
|
+
firstPoint.copy(point);
|
|
478
|
+
} else if (command.type === "t" || command.type === "T") {
|
|
479
|
+
const rx = getReflection(point.x, control.x);
|
|
480
|
+
const ry = getReflection(point.y, control.y);
|
|
481
|
+
control.x = rx;
|
|
482
|
+
control.y = ry;
|
|
483
|
+
if (command.type === "t") {
|
|
484
|
+
path.quadraticCurveTo(
|
|
485
|
+
rx,
|
|
486
|
+
ry,
|
|
487
|
+
point.x + command.x,
|
|
488
|
+
point.y + command.y
|
|
489
|
+
);
|
|
490
|
+
point.x += command.x;
|
|
491
|
+
point.y += command.y;
|
|
492
|
+
} else {
|
|
493
|
+
path.quadraticCurveTo(
|
|
494
|
+
rx,
|
|
495
|
+
ry,
|
|
496
|
+
command.x,
|
|
497
|
+
command.y
|
|
498
|
+
);
|
|
499
|
+
point.x = command.x;
|
|
500
|
+
point.y = command.y;
|
|
501
|
+
}
|
|
502
|
+
if (doSetFirstPoint)
|
|
503
|
+
firstPoint.copy(point);
|
|
504
|
+
} else if (command.type === "a" || command.type === "A") {
|
|
505
|
+
if (command.type === "a") {
|
|
506
|
+
if (command.x === 0 && command.y === 0)
|
|
507
|
+
continue;
|
|
508
|
+
point.x += command.x;
|
|
509
|
+
point.y += command.y;
|
|
510
|
+
} else {
|
|
511
|
+
if (command.x === point.x && command.y === point.y)
|
|
512
|
+
continue;
|
|
513
|
+
point.x = command.x;
|
|
514
|
+
point.y = command.y;
|
|
515
|
+
}
|
|
516
|
+
const start = point.clone();
|
|
517
|
+
control.x = point.x;
|
|
518
|
+
control.y = point.y;
|
|
519
|
+
parseArcCommand(
|
|
520
|
+
path,
|
|
521
|
+
command.rx,
|
|
522
|
+
command.ry,
|
|
523
|
+
command.angle,
|
|
524
|
+
command.largeArcFlag,
|
|
525
|
+
command.sweepFlag,
|
|
526
|
+
start,
|
|
527
|
+
point
|
|
528
|
+
);
|
|
529
|
+
if (doSetFirstPoint)
|
|
530
|
+
firstPoint.copy(point);
|
|
531
|
+
} else if (command.type === "z" || command.type === "Z") {
|
|
532
|
+
path.currentPath.autoClose = true;
|
|
533
|
+
if (path.currentPath.curves.length > 0) {
|
|
534
|
+
point.copy(firstPoint);
|
|
535
|
+
path.currentPath.currentPoint.copy(point);
|
|
536
|
+
isFirstPoint = true;
|
|
537
|
+
}
|
|
538
|
+
} else {
|
|
539
|
+
console.warn(command);
|
|
540
|
+
}
|
|
541
|
+
doSetFirstPoint = false;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
const RE$3 = {
|
|
546
|
+
SEPARATOR: /[ \t\r\n,.\-+]/,
|
|
547
|
+
WHITESPACE: /[ \t\r\n]/,
|
|
548
|
+
DIGIT: /\d/,
|
|
549
|
+
SIGN: /[-+]/,
|
|
550
|
+
POINT: /\./,
|
|
551
|
+
COMMA: /,/,
|
|
552
|
+
EXP: /e/i,
|
|
553
|
+
FLAGS: /[01]/
|
|
554
|
+
};
|
|
555
|
+
function parsePathDataArgs(input, flags, stride = 0) {
|
|
556
|
+
const SEP = 0;
|
|
557
|
+
const INT = 1;
|
|
558
|
+
const FLOAT = 2;
|
|
559
|
+
const EXP = 3;
|
|
560
|
+
let state = SEP;
|
|
561
|
+
let seenComma = true;
|
|
562
|
+
let number = "";
|
|
563
|
+
let exponent = "";
|
|
564
|
+
const result = [];
|
|
565
|
+
function throwSyntaxError(current2, i, partial) {
|
|
566
|
+
const error = new SyntaxError(`Unexpected character "${current2}" at index ${i}.`);
|
|
567
|
+
error.partial = partial;
|
|
568
|
+
throw error;
|
|
569
|
+
}
|
|
570
|
+
function newNumber() {
|
|
571
|
+
if (number !== "") {
|
|
572
|
+
if (exponent === "")
|
|
573
|
+
result.push(Number(number));
|
|
574
|
+
else
|
|
575
|
+
result.push(Number(number) * 10 ** Number(exponent));
|
|
576
|
+
}
|
|
577
|
+
number = "";
|
|
578
|
+
exponent = "";
|
|
579
|
+
}
|
|
580
|
+
let current;
|
|
581
|
+
const length = input.length;
|
|
582
|
+
for (let i = 0; i < length; i++) {
|
|
583
|
+
current = input[i];
|
|
584
|
+
if (Array.isArray(flags) && flags.includes(result.length % stride) && RE$3.FLAGS.test(current)) {
|
|
585
|
+
state = INT;
|
|
586
|
+
number = current;
|
|
587
|
+
newNumber();
|
|
588
|
+
continue;
|
|
589
|
+
}
|
|
590
|
+
if (state === SEP) {
|
|
591
|
+
if (RE$3.WHITESPACE.test(current)) {
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
594
|
+
if (RE$3.DIGIT.test(current) || RE$3.SIGN.test(current)) {
|
|
595
|
+
state = INT;
|
|
596
|
+
number = current;
|
|
597
|
+
continue;
|
|
598
|
+
}
|
|
599
|
+
if (RE$3.POINT.test(current)) {
|
|
600
|
+
state = FLOAT;
|
|
601
|
+
number = current;
|
|
602
|
+
continue;
|
|
603
|
+
}
|
|
604
|
+
if (RE$3.COMMA.test(current)) {
|
|
605
|
+
if (seenComma) {
|
|
606
|
+
throwSyntaxError(current, i, result);
|
|
607
|
+
}
|
|
608
|
+
seenComma = true;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
if (state === INT) {
|
|
612
|
+
if (RE$3.DIGIT.test(current)) {
|
|
613
|
+
number += current;
|
|
614
|
+
continue;
|
|
615
|
+
}
|
|
616
|
+
if (RE$3.POINT.test(current)) {
|
|
617
|
+
number += current;
|
|
618
|
+
state = FLOAT;
|
|
619
|
+
continue;
|
|
620
|
+
}
|
|
621
|
+
if (RE$3.EXP.test(current)) {
|
|
622
|
+
state = EXP;
|
|
623
|
+
continue;
|
|
624
|
+
}
|
|
625
|
+
if (RE$3.SIGN.test(current) && number.length === 1 && RE$3.SIGN.test(number[0])) {
|
|
626
|
+
throwSyntaxError(current, i, result);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
if (state === FLOAT) {
|
|
630
|
+
if (RE$3.DIGIT.test(current)) {
|
|
631
|
+
number += current;
|
|
632
|
+
continue;
|
|
633
|
+
}
|
|
634
|
+
if (RE$3.EXP.test(current)) {
|
|
635
|
+
state = EXP;
|
|
636
|
+
continue;
|
|
637
|
+
}
|
|
638
|
+
if (RE$3.POINT.test(current) && number[number.length - 1] === ".") {
|
|
639
|
+
throwSyntaxError(current, i, result);
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
if (state === EXP) {
|
|
643
|
+
if (RE$3.DIGIT.test(current)) {
|
|
644
|
+
exponent += current;
|
|
645
|
+
continue;
|
|
646
|
+
}
|
|
647
|
+
if (RE$3.SIGN.test(current)) {
|
|
648
|
+
if (exponent === "") {
|
|
649
|
+
exponent += current;
|
|
650
|
+
continue;
|
|
651
|
+
}
|
|
652
|
+
if (exponent.length === 1 && RE$3.SIGN.test(exponent)) {
|
|
653
|
+
throwSyntaxError(current, i, result);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
if (RE$3.WHITESPACE.test(current)) {
|
|
658
|
+
newNumber();
|
|
659
|
+
state = SEP;
|
|
660
|
+
seenComma = false;
|
|
661
|
+
} else if (RE$3.COMMA.test(current)) {
|
|
662
|
+
newNumber();
|
|
663
|
+
state = SEP;
|
|
664
|
+
seenComma = true;
|
|
665
|
+
} else if (RE$3.SIGN.test(current)) {
|
|
666
|
+
newNumber();
|
|
667
|
+
state = INT;
|
|
668
|
+
number = current;
|
|
669
|
+
} else if (RE$3.POINT.test(current)) {
|
|
670
|
+
newNumber();
|
|
671
|
+
state = FLOAT;
|
|
672
|
+
number = current;
|
|
673
|
+
} else {
|
|
674
|
+
throwSyntaxError(current, i, result);
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
newNumber();
|
|
678
|
+
return result;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
function commandToData(cmd) {
|
|
682
|
+
switch (cmd.type) {
|
|
683
|
+
case "m":
|
|
684
|
+
case "M":
|
|
685
|
+
return `${cmd.type} ${cmd.x} ${cmd.y}`;
|
|
686
|
+
case "h":
|
|
687
|
+
case "H":
|
|
688
|
+
return `${cmd.type} ${cmd.x}`;
|
|
689
|
+
case "v":
|
|
690
|
+
case "V":
|
|
691
|
+
return `${cmd.type} ${cmd.y}`;
|
|
692
|
+
case "l":
|
|
693
|
+
case "L":
|
|
694
|
+
return `${cmd.type} ${cmd.x} ${cmd.y}`;
|
|
695
|
+
case "c":
|
|
696
|
+
case "C":
|
|
697
|
+
return `${cmd.type} ${cmd.x1} ${cmd.y1} ${cmd.x2} ${cmd.y2} ${cmd.x} ${cmd.y}`;
|
|
698
|
+
case "s":
|
|
699
|
+
case "S":
|
|
700
|
+
return `${cmd.type} ${cmd.x2} ${cmd.y2} ${cmd.x} ${cmd.y}`;
|
|
701
|
+
case "q":
|
|
702
|
+
case "Q":
|
|
703
|
+
return `${cmd.type} ${cmd.x1} ${cmd.y1} ${cmd.x} ${cmd.y}`;
|
|
704
|
+
case "t":
|
|
705
|
+
case "T":
|
|
706
|
+
return `${cmd.type} ${cmd.x} ${cmd.y}`;
|
|
707
|
+
case "a":
|
|
708
|
+
case "A":
|
|
709
|
+
return `${cmd.type} ${cmd.rx} ${cmd.ry} ${cmd.angle} ${cmd.largeArcFlag} ${cmd.sweepFlag} ${cmd.x} ${cmd.y}`;
|
|
710
|
+
case "z":
|
|
711
|
+
case "Z":
|
|
712
|
+
return cmd.type;
|
|
713
|
+
default:
|
|
714
|
+
return "";
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
function pathCommandsToPathData(commands) {
|
|
718
|
+
let data = "";
|
|
719
|
+
for (let i = 0, len = commands.length; i < len; i++) {
|
|
720
|
+
data += `${commandToData(commands[i])} `;
|
|
721
|
+
}
|
|
722
|
+
return data;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
const RE$2 = /[a-df-z][^a-df-z]*/gi;
|
|
726
|
+
function pathDataToPathCommands(d) {
|
|
727
|
+
const commands = [];
|
|
728
|
+
const matched = d.match(RE$2);
|
|
729
|
+
if (!matched) {
|
|
730
|
+
return commands;
|
|
731
|
+
}
|
|
732
|
+
for (let i = 0, len = matched.length; i < len; i++) {
|
|
733
|
+
const command = matched[i];
|
|
734
|
+
const type = command.charAt(0);
|
|
735
|
+
const data = command.slice(1).trim();
|
|
736
|
+
let args;
|
|
737
|
+
switch (type) {
|
|
738
|
+
case "m":
|
|
739
|
+
case "M":
|
|
740
|
+
args = parsePathDataArgs(data);
|
|
741
|
+
for (let i2 = 0, len2 = args.length; i2 < len2; i2 += 2) {
|
|
742
|
+
if (i2 === 0) {
|
|
743
|
+
commands.push({ type, x: args[i2], y: args[i2 + 1] });
|
|
744
|
+
} else {
|
|
745
|
+
commands.push({ type: type === "m" ? "l" : "L", x: args[i2], y: args[i2 + 1] });
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
break;
|
|
749
|
+
case "h":
|
|
750
|
+
case "H":
|
|
751
|
+
args = parsePathDataArgs(data);
|
|
752
|
+
for (let i2 = 0, len2 = args.length; i2 < len2; i2++) {
|
|
753
|
+
commands.push({ type, x: args[i2] });
|
|
754
|
+
}
|
|
755
|
+
break;
|
|
756
|
+
case "v":
|
|
757
|
+
case "V":
|
|
758
|
+
args = parsePathDataArgs(data);
|
|
759
|
+
for (let i2 = 0, len2 = args.length; i2 < len2; i2++) {
|
|
760
|
+
commands.push({ type, y: args[i2] });
|
|
761
|
+
}
|
|
762
|
+
break;
|
|
763
|
+
case "l":
|
|
764
|
+
case "L":
|
|
765
|
+
args = parsePathDataArgs(data);
|
|
766
|
+
for (let i2 = 0, len2 = args.length; i2 < len2; i2 += 2) {
|
|
767
|
+
commands.push({ type, x: args[i2], y: args[i2 + 1] });
|
|
768
|
+
}
|
|
769
|
+
break;
|
|
770
|
+
case "c":
|
|
771
|
+
case "C":
|
|
772
|
+
args = parsePathDataArgs(data);
|
|
773
|
+
for (let i2 = 0, len2 = args.length; i2 < len2; i2 += 6) {
|
|
774
|
+
commands.push({
|
|
775
|
+
type,
|
|
776
|
+
x1: args[i2],
|
|
777
|
+
y1: args[i2 + 1],
|
|
778
|
+
x2: args[i2 + 2],
|
|
779
|
+
y2: args[i2 + 3],
|
|
780
|
+
x: args[i2 + 4],
|
|
781
|
+
y: args[i2 + 5]
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
break;
|
|
785
|
+
case "s":
|
|
786
|
+
case "S":
|
|
787
|
+
args = parsePathDataArgs(data);
|
|
788
|
+
for (let i2 = 0, len2 = args.length; i2 < len2; i2 += 4) {
|
|
789
|
+
commands.push({
|
|
790
|
+
type,
|
|
791
|
+
x2: args[i2],
|
|
792
|
+
y2: args[i2 + 1],
|
|
793
|
+
x: args[i2 + 2],
|
|
794
|
+
y: args[i2 + 3]
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
break;
|
|
798
|
+
case "q":
|
|
799
|
+
case "Q":
|
|
800
|
+
args = parsePathDataArgs(data);
|
|
801
|
+
for (let i2 = 0, len2 = args.length; i2 < len2; i2 += 4) {
|
|
802
|
+
commands.push({
|
|
803
|
+
type,
|
|
804
|
+
x1: args[i2],
|
|
805
|
+
y1: args[i2 + 1],
|
|
806
|
+
x: args[i2 + 2],
|
|
807
|
+
y: args[i2 + 3]
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
break;
|
|
811
|
+
case "t":
|
|
812
|
+
case "T":
|
|
813
|
+
args = parsePathDataArgs(data);
|
|
814
|
+
for (let i2 = 0, len2 = args.length; i2 < len2; i2 += 2) {
|
|
815
|
+
commands.push({
|
|
816
|
+
type,
|
|
817
|
+
x: args[i2],
|
|
818
|
+
y: args[i2 + 1]
|
|
819
|
+
});
|
|
820
|
+
}
|
|
821
|
+
break;
|
|
822
|
+
case "a":
|
|
823
|
+
case "A":
|
|
824
|
+
args = parsePathDataArgs(data, [3, 4], 7);
|
|
825
|
+
for (let i2 = 0, len2 = args.length; i2 < len2; i2 += 7) {
|
|
826
|
+
commands.push({
|
|
827
|
+
type,
|
|
828
|
+
rx: args[i2],
|
|
829
|
+
ry: args[i2 + 1],
|
|
830
|
+
angle: args[i2 + 2],
|
|
831
|
+
largeArcFlag: args[i2 + 3],
|
|
832
|
+
sweepFlag: args[i2 + 4],
|
|
833
|
+
x: args[i2 + 5],
|
|
834
|
+
y: args[i2 + 6]
|
|
835
|
+
});
|
|
836
|
+
}
|
|
837
|
+
break;
|
|
838
|
+
case "z":
|
|
839
|
+
case "Z":
|
|
840
|
+
commands.push({
|
|
841
|
+
type
|
|
842
|
+
});
|
|
843
|
+
break;
|
|
844
|
+
default:
|
|
845
|
+
console.warn(command);
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
return commands;
|
|
849
|
+
}
|
|
850
|
+
|
|
72
851
|
var __defProp$5 = Object.defineProperty;
|
|
73
852
|
var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
74
853
|
var __publicField$5 = (obj, key, value) => {
|
|
@@ -81,12 +860,6 @@ class Curve {
|
|
|
81
860
|
__publicField$5(this, "_cacheArcLengths");
|
|
82
861
|
__publicField$5(this, "_needsUpdate", false);
|
|
83
862
|
}
|
|
84
|
-
getMinMax(min = Point2D.MAX, max = Point2D.MIN) {
|
|
85
|
-
return { min, max };
|
|
86
|
-
}
|
|
87
|
-
getDivisions(divisions) {
|
|
88
|
-
return divisions;
|
|
89
|
-
}
|
|
90
863
|
getPointAt(u, output = new Point2D()) {
|
|
91
864
|
return this.getPoint(this.getUtoTmapping(u), output);
|
|
92
865
|
}
|
|
@@ -179,25 +952,30 @@ class Curve {
|
|
|
179
952
|
getTangentAt(u, output = new Point2D()) {
|
|
180
953
|
return this.getTangent(this.getUtoTmapping(u), output);
|
|
181
954
|
}
|
|
955
|
+
/** overrideable */
|
|
956
|
+
// eslint-disable-next-line unused-imports/no-unused-vars
|
|
957
|
+
transform(matrix) {
|
|
958
|
+
return this;
|
|
959
|
+
}
|
|
960
|
+
/** overrideable */
|
|
961
|
+
getDivisions(divisions) {
|
|
962
|
+
return divisions;
|
|
963
|
+
}
|
|
964
|
+
/** overrideable */
|
|
965
|
+
getMinMax(min = Point2D.MAX, max = Point2D.MIN) {
|
|
966
|
+
return { min, max };
|
|
967
|
+
}
|
|
968
|
+
/** overrideable */
|
|
969
|
+
getCommands() {
|
|
970
|
+
return [];
|
|
971
|
+
}
|
|
182
972
|
getData() {
|
|
183
|
-
return this.getCommands()
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
case "C":
|
|
190
|
-
return `C ${cmd.x1} ${cmd.y1} ${cmd.x2} ${cmd.y2} ${cmd.x} ${cmd.y}`;
|
|
191
|
-
case "Q":
|
|
192
|
-
return `Q ${cmd.x1} ${cmd.y1} ${cmd.x} ${cmd.y}`;
|
|
193
|
-
case "A":
|
|
194
|
-
return `A ${cmd.rx} ${cmd.ry} ${cmd.xAxisRotation} ${cmd.largeArcFlag} ${cmd.sweepFlag} ${cmd.x} ${cmd.y}`;
|
|
195
|
-
case "Z":
|
|
196
|
-
return "Z";
|
|
197
|
-
default:
|
|
198
|
-
return "";
|
|
199
|
-
}
|
|
200
|
-
}).join(" ");
|
|
973
|
+
return pathCommandsToPathData(this.getCommands());
|
|
974
|
+
}
|
|
975
|
+
/** overrideable */
|
|
976
|
+
// eslint-disable-next-line unused-imports/no-unused-vars
|
|
977
|
+
drawTo(ctx) {
|
|
978
|
+
return this;
|
|
201
979
|
}
|
|
202
980
|
clone() {
|
|
203
981
|
return new this.constructor().copy(this);
|
|
@@ -216,13 +994,6 @@ class CircleCurve extends Curve {
|
|
|
216
994
|
this.start = start;
|
|
217
995
|
this.end = end;
|
|
218
996
|
}
|
|
219
|
-
getMinMax(min = Point2D.MAX, max = Point2D.MIN) {
|
|
220
|
-
min.x = Math.min(min.x, this.center.x - this.radius);
|
|
221
|
-
min.y = Math.min(min.y, this.center.y - this.radius);
|
|
222
|
-
max.x = Math.max(max.x, this.center.x + this.radius);
|
|
223
|
-
max.y = Math.max(max.y, this.center.y + this.radius);
|
|
224
|
-
return { min, max };
|
|
225
|
-
}
|
|
226
997
|
getPoint(t) {
|
|
227
998
|
const { radius, center } = this;
|
|
228
999
|
return center.clone().add(this.getNormal(t).clone().multiplyScalar(radius));
|
|
@@ -236,10 +1007,12 @@ class CircleCurve extends Curve {
|
|
|
236
1007
|
const _t = t * (end - start) + start - 0.5 * Math.PI;
|
|
237
1008
|
return new Point2D(Math.cos(_t), Math.sin(_t));
|
|
238
1009
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
1010
|
+
getMinMax(min = Point2D.MAX, max = Point2D.MIN) {
|
|
1011
|
+
min.x = Math.min(min.x, this.center.x - this.radius);
|
|
1012
|
+
min.y = Math.min(min.y, this.center.y - this.radius);
|
|
1013
|
+
max.x = Math.max(max.x, this.center.x + this.radius);
|
|
1014
|
+
max.y = Math.max(max.y, this.center.y + this.radius);
|
|
1015
|
+
return { min, max };
|
|
243
1016
|
}
|
|
244
1017
|
}
|
|
245
1018
|
|
|
@@ -305,6 +1078,13 @@ class CubicBezierCurve extends Curve {
|
|
|
305
1078
|
max.y = Math.max(max.y, v0.y, v1.y, v2.y, v3.y);
|
|
306
1079
|
return { min, max };
|
|
307
1080
|
}
|
|
1081
|
+
transform(matrix) {
|
|
1082
|
+
this.v0.applyMatrix3(matrix);
|
|
1083
|
+
this.v1.applyMatrix3(matrix);
|
|
1084
|
+
this.v2.applyMatrix3(matrix);
|
|
1085
|
+
this.v3.applyMatrix3(matrix);
|
|
1086
|
+
return this;
|
|
1087
|
+
}
|
|
308
1088
|
getCommands() {
|
|
309
1089
|
const { v0, v1, v2, v3 } = this;
|
|
310
1090
|
return [
|
|
@@ -316,6 +1096,7 @@ class CubicBezierCurve extends Curve {
|
|
|
316
1096
|
const { v0, v1, v2, v3 } = this;
|
|
317
1097
|
ctx.moveTo(v0.x, v0.y);
|
|
318
1098
|
ctx.bezierCurveTo(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y);
|
|
1099
|
+
return this;
|
|
319
1100
|
}
|
|
320
1101
|
copy(source) {
|
|
321
1102
|
super.copy(source);
|
|
@@ -327,13 +1108,17 @@ class CubicBezierCurve extends Curve {
|
|
|
327
1108
|
}
|
|
328
1109
|
}
|
|
329
1110
|
|
|
1111
|
+
const tempTransform0$1 = new Matrix3();
|
|
1112
|
+
const tempTransform1$1 = new Matrix3();
|
|
1113
|
+
const tempTransform2$1 = new Matrix3();
|
|
1114
|
+
const tempV2 = new Point2D();
|
|
330
1115
|
class EllipseCurve extends Curve {
|
|
331
|
-
constructor(x = 0, y = 0,
|
|
1116
|
+
constructor(x = 0, y = 0, radiusX = 1, radiusY = 1, startAngle = 0, endAngle = Math.PI * 2, clockwise = false, rotation = 0) {
|
|
332
1117
|
super();
|
|
333
1118
|
this.x = x;
|
|
334
1119
|
this.y = y;
|
|
335
|
-
this.
|
|
336
|
-
this.
|
|
1120
|
+
this.radiusX = radiusX;
|
|
1121
|
+
this.radiusY = radiusY;
|
|
337
1122
|
this.startAngle = startAngle;
|
|
338
1123
|
this.endAngle = endAngle;
|
|
339
1124
|
this.clockwise = clockwise;
|
|
@@ -365,8 +1150,8 @@ class EllipseCurve extends Curve {
|
|
|
365
1150
|
}
|
|
366
1151
|
}
|
|
367
1152
|
const angle = this.startAngle + t * deltaAngle;
|
|
368
|
-
let _x = this.x + this.
|
|
369
|
-
let _y = this.y + this.
|
|
1153
|
+
let _x = this.x + this.radiusX * Math.cos(angle);
|
|
1154
|
+
let _y = this.y + this.radiusY * Math.sin(angle);
|
|
370
1155
|
if (this.rotation !== 0) {
|
|
371
1156
|
const cos = Math.cos(this.rotation);
|
|
372
1157
|
const sin = Math.sin(this.rotation);
|
|
@@ -378,50 +1163,65 @@ class EllipseCurve extends Curve {
|
|
|
378
1163
|
return output.set(_x, _y);
|
|
379
1164
|
}
|
|
380
1165
|
getCommands() {
|
|
381
|
-
const { x, y,
|
|
1166
|
+
const { x, y, radiusX, radiusY, startAngle, endAngle, clockwise } = this;
|
|
382
1167
|
const anticlockwise = !clockwise;
|
|
383
|
-
const startX = x +
|
|
384
|
-
const startY = y +
|
|
385
|
-
const endX = x +
|
|
386
|
-
const endY = y +
|
|
1168
|
+
const startX = x + radiusX * Math.cos(startAngle);
|
|
1169
|
+
const startY = y + radiusY * Math.sin(startAngle);
|
|
1170
|
+
const endX = x + radiusX * Math.cos(endAngle);
|
|
1171
|
+
const endY = y + radiusY * Math.sin(endAngle);
|
|
387
1172
|
const angleDiff = Math.abs(startAngle - endAngle);
|
|
388
1173
|
const largeArcFlag = angleDiff > Math.PI ? 1 : 0;
|
|
389
1174
|
const sweepFlag = anticlockwise ? 0 : 1;
|
|
390
|
-
const midX = x +
|
|
391
|
-
const midY = y +
|
|
1175
|
+
const midX = x + radiusX * Math.cos(startAngle + (endAngle - startAngle) / 2);
|
|
1176
|
+
const midY = y + radiusY * Math.sin(startAngle + (endAngle - startAngle) / 2);
|
|
392
1177
|
if (angleDiff >= 2 * Math.PI) {
|
|
393
1178
|
return [
|
|
394
1179
|
{ type: "M", x: startX, y: startY },
|
|
395
|
-
{ type: "A", rx, ry,
|
|
396
|
-
{ type: "A", rx, ry,
|
|
1180
|
+
{ type: "A", rx: radiusX, ry: radiusY, angle: 0, largeArcFlag: 1, sweepFlag, x: midX, y: midY },
|
|
1181
|
+
{ type: "A", rx: radiusX, ry: radiusY, angle: 0, largeArcFlag: 1, sweepFlag, x: startX, y: startY }
|
|
397
1182
|
];
|
|
398
1183
|
} else {
|
|
399
1184
|
return [
|
|
400
1185
|
{ type: "M", x: startX, y: startY },
|
|
401
|
-
{ type: "A", rx, ry,
|
|
1186
|
+
{ type: "A", rx: radiusX, ry: radiusY, angle: 0, largeArcFlag, sweepFlag, x: endX, y: endY }
|
|
402
1187
|
];
|
|
403
1188
|
}
|
|
404
1189
|
}
|
|
405
1190
|
drawTo(ctx) {
|
|
406
|
-
const { x, y,
|
|
407
|
-
const startX = x +
|
|
408
|
-
const startY = y +
|
|
1191
|
+
const { x, y, radiusX, radiusY, rotation, startAngle, endAngle, clockwise } = this;
|
|
1192
|
+
const startX = x + radiusX * Math.cos(startAngle);
|
|
1193
|
+
const startY = y + radiusY * Math.sin(startAngle);
|
|
409
1194
|
ctx.moveTo(startX, startY);
|
|
410
|
-
ctx.
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
1195
|
+
ctx.ellipse(
|
|
1196
|
+
x,
|
|
1197
|
+
y,
|
|
1198
|
+
radiusX,
|
|
1199
|
+
radiusY,
|
|
1200
|
+
rotation,
|
|
1201
|
+
startAngle,
|
|
1202
|
+
endAngle,
|
|
1203
|
+
!clockwise
|
|
417
1204
|
);
|
|
1205
|
+
return this;
|
|
1206
|
+
}
|
|
1207
|
+
transform(matrix) {
|
|
1208
|
+
tempV2.set(this.x, this.y);
|
|
1209
|
+
tempV2.applyMatrix3(matrix);
|
|
1210
|
+
this.x = tempV2.x;
|
|
1211
|
+
this.y = tempV2.y;
|
|
1212
|
+
if (isTransformSkewed(matrix)) {
|
|
1213
|
+
transfEllipseGeneric(this, matrix);
|
|
1214
|
+
} else {
|
|
1215
|
+
transfEllipseNoSkew(this, matrix);
|
|
1216
|
+
}
|
|
1217
|
+
return this;
|
|
418
1218
|
}
|
|
419
1219
|
copy(source) {
|
|
420
1220
|
super.copy(source);
|
|
421
1221
|
this.x = source.x;
|
|
422
1222
|
this.y = source.y;
|
|
423
|
-
this.
|
|
424
|
-
this.
|
|
1223
|
+
this.radiusX = source.radiusX;
|
|
1224
|
+
this.radiusY = source.radiusY;
|
|
425
1225
|
this.startAngle = source.startAngle;
|
|
426
1226
|
this.endAngle = source.endAngle;
|
|
427
1227
|
this.clockwise = source.clockwise;
|
|
@@ -429,6 +1229,145 @@ class EllipseCurve extends Curve {
|
|
|
429
1229
|
return this;
|
|
430
1230
|
}
|
|
431
1231
|
}
|
|
1232
|
+
function transfEllipseGeneric(curve, m) {
|
|
1233
|
+
const a = curve.radiusX;
|
|
1234
|
+
const b = curve.radiusY;
|
|
1235
|
+
const cosTheta = Math.cos(curve.rotation);
|
|
1236
|
+
const sinTheta = Math.sin(curve.rotation);
|
|
1237
|
+
const v1 = new Point2D(a * cosTheta, a * sinTheta);
|
|
1238
|
+
const v2 = new Point2D(-b * sinTheta, b * cosTheta);
|
|
1239
|
+
const f1 = v1.applyMatrix3(m);
|
|
1240
|
+
const f2 = v2.applyMatrix3(m);
|
|
1241
|
+
const mF = tempTransform0$1.set(
|
|
1242
|
+
f1.x,
|
|
1243
|
+
f2.x,
|
|
1244
|
+
0,
|
|
1245
|
+
f1.y,
|
|
1246
|
+
f2.y,
|
|
1247
|
+
0,
|
|
1248
|
+
0,
|
|
1249
|
+
0,
|
|
1250
|
+
1
|
|
1251
|
+
);
|
|
1252
|
+
const mFInv = tempTransform1$1.copy(mF).invert();
|
|
1253
|
+
const mFInvT = tempTransform2$1.copy(mFInv).transpose();
|
|
1254
|
+
const mQ = mFInvT.multiply(mFInv);
|
|
1255
|
+
const mQe = mQ.elements;
|
|
1256
|
+
const ed = eigenDecomposition(mQe[0], mQe[1], mQe[4]);
|
|
1257
|
+
const rt1sqrt = Math.sqrt(ed.rt1);
|
|
1258
|
+
const rt2sqrt = Math.sqrt(ed.rt2);
|
|
1259
|
+
curve.radiusX = 1 / rt1sqrt;
|
|
1260
|
+
curve.radiusY = 1 / rt2sqrt;
|
|
1261
|
+
curve.rotation = Math.atan2(ed.sn, ed.cs);
|
|
1262
|
+
const isFullEllipse = (curve.endAngle - curve.startAngle) % (2 * Math.PI) < Number.EPSILON;
|
|
1263
|
+
if (!isFullEllipse) {
|
|
1264
|
+
const mDsqrt = tempTransform1$1.set(
|
|
1265
|
+
rt1sqrt,
|
|
1266
|
+
0,
|
|
1267
|
+
0,
|
|
1268
|
+
0,
|
|
1269
|
+
rt2sqrt,
|
|
1270
|
+
0,
|
|
1271
|
+
0,
|
|
1272
|
+
0,
|
|
1273
|
+
1
|
|
1274
|
+
);
|
|
1275
|
+
const mRT = tempTransform2$1.set(
|
|
1276
|
+
ed.cs,
|
|
1277
|
+
ed.sn,
|
|
1278
|
+
0,
|
|
1279
|
+
-ed.sn,
|
|
1280
|
+
ed.cs,
|
|
1281
|
+
0,
|
|
1282
|
+
0,
|
|
1283
|
+
0,
|
|
1284
|
+
1
|
|
1285
|
+
);
|
|
1286
|
+
const mDRF = mDsqrt.multiply(mRT).multiply(mF);
|
|
1287
|
+
const transformAngle = (phi) => {
|
|
1288
|
+
const { x: cosR, y: sinR } = new Point2D(Math.cos(phi), Math.sin(phi)).applyMatrix3(mDRF);
|
|
1289
|
+
return Math.atan2(sinR, cosR);
|
|
1290
|
+
};
|
|
1291
|
+
curve.startAngle = transformAngle(curve.startAngle);
|
|
1292
|
+
curve.endAngle = transformAngle(curve.endAngle);
|
|
1293
|
+
if (isTransformFlipped(m)) {
|
|
1294
|
+
curve.clockwise = !curve.clockwise;
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
function transfEllipseNoSkew(curve, m) {
|
|
1299
|
+
const sx = getTransformScaleX(m);
|
|
1300
|
+
const sy = getTransformScaleY(m);
|
|
1301
|
+
curve.radiusX *= sx;
|
|
1302
|
+
curve.radiusY *= sy;
|
|
1303
|
+
const theta = sx > Number.EPSILON ? Math.atan2(m.elements[1], m.elements[0]) : Math.atan2(-m.elements[3], m.elements[4]);
|
|
1304
|
+
curve.rotation += theta;
|
|
1305
|
+
if (isTransformFlipped(m)) {
|
|
1306
|
+
curve.startAngle *= -1;
|
|
1307
|
+
curve.endAngle *= -1;
|
|
1308
|
+
curve.clockwise = !curve.clockwise;
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
function isTransformFlipped(m) {
|
|
1312
|
+
const te = m.elements;
|
|
1313
|
+
return te[0] * te[4] - te[1] * te[3] < 0;
|
|
1314
|
+
}
|
|
1315
|
+
function isTransformSkewed(m) {
|
|
1316
|
+
const te = m.elements;
|
|
1317
|
+
const basisDot = te[0] * te[3] + te[1] * te[4];
|
|
1318
|
+
if (basisDot === 0)
|
|
1319
|
+
return false;
|
|
1320
|
+
const sx = getTransformScaleX(m);
|
|
1321
|
+
const sy = getTransformScaleY(m);
|
|
1322
|
+
return Math.abs(basisDot / (sx * sy)) > Number.EPSILON;
|
|
1323
|
+
}
|
|
1324
|
+
function getTransformScaleX(m) {
|
|
1325
|
+
const te = m.elements;
|
|
1326
|
+
return Math.sqrt(te[0] * te[0] + te[1] * te[1]);
|
|
1327
|
+
}
|
|
1328
|
+
function getTransformScaleY(m) {
|
|
1329
|
+
const te = m.elements;
|
|
1330
|
+
return Math.sqrt(te[3] * te[3] + te[4] * te[4]);
|
|
1331
|
+
}
|
|
1332
|
+
function eigenDecomposition(A, B, C) {
|
|
1333
|
+
let rt1, rt2, cs, sn, t;
|
|
1334
|
+
const sm = A + C;
|
|
1335
|
+
const df = A - C;
|
|
1336
|
+
const rt = Math.sqrt(df * df + 4 * B * B);
|
|
1337
|
+
if (sm > 0) {
|
|
1338
|
+
rt1 = 0.5 * (sm + rt);
|
|
1339
|
+
t = 1 / rt1;
|
|
1340
|
+
rt2 = A * t * C - B * t * B;
|
|
1341
|
+
} else if (sm < 0) {
|
|
1342
|
+
rt2 = 0.5 * (sm - rt);
|
|
1343
|
+
} else {
|
|
1344
|
+
rt1 = 0.5 * rt;
|
|
1345
|
+
rt2 = -0.5 * rt;
|
|
1346
|
+
}
|
|
1347
|
+
if (df > 0) {
|
|
1348
|
+
cs = df + rt;
|
|
1349
|
+
} else {
|
|
1350
|
+
cs = df - rt;
|
|
1351
|
+
}
|
|
1352
|
+
if (Math.abs(cs) > 2 * Math.abs(B)) {
|
|
1353
|
+
t = -2 * B / cs;
|
|
1354
|
+
sn = 1 / Math.sqrt(1 + t * t);
|
|
1355
|
+
cs = t * sn;
|
|
1356
|
+
} else if (Math.abs(B) === 0) {
|
|
1357
|
+
cs = 1;
|
|
1358
|
+
sn = 0;
|
|
1359
|
+
} else {
|
|
1360
|
+
t = -0.5 * cs / B;
|
|
1361
|
+
cs = 1 / Math.sqrt(1 + t * t);
|
|
1362
|
+
sn = t * cs;
|
|
1363
|
+
}
|
|
1364
|
+
if (df > 0) {
|
|
1365
|
+
t = cs;
|
|
1366
|
+
cs = -sn;
|
|
1367
|
+
sn = t;
|
|
1368
|
+
}
|
|
1369
|
+
return { rt1, rt2, cs, sn };
|
|
1370
|
+
}
|
|
432
1371
|
|
|
433
1372
|
class LineCurve extends Curve {
|
|
434
1373
|
constructor(v1 = new Point2D(), v2 = new Point2D()) {
|
|
@@ -472,10 +1411,16 @@ class LineCurve extends Curve {
|
|
|
472
1411
|
max.y = Math.max(max.y, v1.y, v2.y);
|
|
473
1412
|
return { min, max };
|
|
474
1413
|
}
|
|
1414
|
+
transform(matrix) {
|
|
1415
|
+
this.v1.applyMatrix3(matrix);
|
|
1416
|
+
this.v2.applyMatrix3(matrix);
|
|
1417
|
+
return this;
|
|
1418
|
+
}
|
|
475
1419
|
drawTo(ctx) {
|
|
476
1420
|
const { v1, v2 } = this;
|
|
477
1421
|
ctx.moveTo(v1.x, v1.y);
|
|
478
1422
|
ctx.lineTo(v2.x, v2.y);
|
|
1423
|
+
return this;
|
|
479
1424
|
}
|
|
480
1425
|
copy(source) {
|
|
481
1426
|
super.copy(source);
|
|
@@ -558,6 +1503,7 @@ class HeartCurve extends Curve {
|
|
|
558
1503
|
}
|
|
559
1504
|
drawTo(ctx) {
|
|
560
1505
|
this.curves.forEach((curve) => curve.drawTo(ctx));
|
|
1506
|
+
return this;
|
|
561
1507
|
}
|
|
562
1508
|
}
|
|
563
1509
|
|
|
@@ -620,6 +1566,7 @@ class PloygonCurve extends Curve {
|
|
|
620
1566
|
}
|
|
621
1567
|
drawTo(ctx) {
|
|
622
1568
|
this.curves.forEach((curve) => curve.drawTo(ctx));
|
|
1569
|
+
return this;
|
|
623
1570
|
}
|
|
624
1571
|
}
|
|
625
1572
|
|
|
@@ -657,10 +1604,17 @@ class QuadraticBezierCurve extends Curve {
|
|
|
657
1604
|
max.y = Math.max(max.y, v0.y, v2.y, y1, y2);
|
|
658
1605
|
return { min, max };
|
|
659
1606
|
}
|
|
1607
|
+
transform(matrix) {
|
|
1608
|
+
this.v0.applyMatrix3(matrix);
|
|
1609
|
+
this.v1.applyMatrix3(matrix);
|
|
1610
|
+
this.v2.applyMatrix3(matrix);
|
|
1611
|
+
return this;
|
|
1612
|
+
}
|
|
660
1613
|
drawTo(ctx) {
|
|
661
1614
|
const { v0, v1, v2 } = this;
|
|
662
1615
|
ctx.moveTo(v0.x, v0.y);
|
|
663
1616
|
ctx.quadraticCurveTo(v1.x, v1.y, v2.x, v2.y);
|
|
1617
|
+
return this;
|
|
664
1618
|
}
|
|
665
1619
|
copy(source) {
|
|
666
1620
|
super.copy(source);
|
|
@@ -754,6 +1708,7 @@ class RectangularCurve extends Curve {
|
|
|
754
1708
|
}
|
|
755
1709
|
drawTo(ctx) {
|
|
756
1710
|
this.curves.forEach((curve) => curve.drawTo(ctx));
|
|
1711
|
+
return this;
|
|
757
1712
|
}
|
|
758
1713
|
}
|
|
759
1714
|
|
|
@@ -780,11 +1735,6 @@ class SplineCurve extends Curve {
|
|
|
780
1735
|
);
|
|
781
1736
|
return output;
|
|
782
1737
|
}
|
|
783
|
-
getCommands() {
|
|
784
|
-
return [];
|
|
785
|
-
}
|
|
786
|
-
drawTo(_ctx) {
|
|
787
|
-
}
|
|
788
1738
|
copy(source) {
|
|
789
1739
|
super.copy(source);
|
|
790
1740
|
this.points = [];
|
|
@@ -956,13 +1906,13 @@ class CurvePath extends Curve {
|
|
|
956
1906
|
this.absellipse(x, y, radius, radius, startAngle, endAngle, clockwise);
|
|
957
1907
|
return this;
|
|
958
1908
|
}
|
|
959
|
-
ellipse(x, y,
|
|
1909
|
+
ellipse(x, y, radiusX, radiusY, startAngle, endAngle, clockwise = false, rotation = 0) {
|
|
960
1910
|
const point = this.currentPoint;
|
|
961
|
-
this.absellipse(x + point.x, y + point.y,
|
|
1911
|
+
this.absellipse(x + point.x, y + point.y, radiusX, radiusY, startAngle, endAngle, clockwise, rotation);
|
|
962
1912
|
return this;
|
|
963
1913
|
}
|
|
964
|
-
absellipse(x, y,
|
|
965
|
-
const curve = new EllipseCurve(x, y,
|
|
1914
|
+
absellipse(x, y, radiusX, radiusY, startAngle, endAngle, clockwise = false, rotation = 0) {
|
|
1915
|
+
const curve = new EllipseCurve(x, y, radiusX, radiusY, startAngle, endAngle, clockwise, rotation);
|
|
966
1916
|
if (this.curves.length > 0) {
|
|
967
1917
|
const firstPoint = curve.getPoint(0);
|
|
968
1918
|
if (!firstPoint.equals(this.currentPoint)) {
|
|
@@ -982,6 +1932,7 @@ class CurvePath extends Curve {
|
|
|
982
1932
|
}
|
|
983
1933
|
drawTo(ctx) {
|
|
984
1934
|
this.curves.forEach((curve) => curve.drawTo(ctx));
|
|
1935
|
+
return this;
|
|
985
1936
|
}
|
|
986
1937
|
copy(source) {
|
|
987
1938
|
super.copy(source);
|
|
@@ -1003,12 +1954,26 @@ var __publicField = (obj, key, value) => {
|
|
|
1003
1954
|
return value;
|
|
1004
1955
|
};
|
|
1005
1956
|
class Path2D {
|
|
1006
|
-
constructor() {
|
|
1957
|
+
constructor(path) {
|
|
1007
1958
|
__publicField(this, "currentPath", new CurvePath());
|
|
1008
1959
|
__publicField(this, "paths", [this.currentPath]);
|
|
1960
|
+
__publicField(this, "userData");
|
|
1961
|
+
if (path) {
|
|
1962
|
+
if (path instanceof Path2D) {
|
|
1963
|
+
this.addPath(path);
|
|
1964
|
+
} else if (Array.isArray(path)) {
|
|
1965
|
+
this.addCommands(path);
|
|
1966
|
+
} else {
|
|
1967
|
+
this.addData(path);
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1009
1970
|
}
|
|
1010
1971
|
addPath(path) {
|
|
1011
|
-
|
|
1972
|
+
if (path instanceof Path2D) {
|
|
1973
|
+
this.paths.push(...path.paths.map((v) => v.clone()));
|
|
1974
|
+
} else {
|
|
1975
|
+
this.paths.push(path);
|
|
1976
|
+
}
|
|
1012
1977
|
return this;
|
|
1013
1978
|
}
|
|
1014
1979
|
closePath() {
|
|
@@ -1075,12 +2040,28 @@ class Path2D {
|
|
|
1075
2040
|
this.currentPath.rect(x, y, w, h);
|
|
1076
2041
|
return this;
|
|
1077
2042
|
}
|
|
2043
|
+
addCommands(commands) {
|
|
2044
|
+
addPathCommandsToPath2D(commands, this);
|
|
2045
|
+
return this;
|
|
2046
|
+
}
|
|
2047
|
+
addData(data) {
|
|
2048
|
+
this.addCommands(pathDataToPathCommands(data));
|
|
2049
|
+
return this;
|
|
2050
|
+
}
|
|
1078
2051
|
splineThru(points) {
|
|
1079
2052
|
this.currentPath.splineThru(points);
|
|
1080
2053
|
return this;
|
|
1081
2054
|
}
|
|
2055
|
+
forEachCurve(cb) {
|
|
2056
|
+
this.paths.forEach((path) => path.curves.forEach((curve) => cb(curve)));
|
|
2057
|
+
return this;
|
|
2058
|
+
}
|
|
2059
|
+
transform(matrix) {
|
|
2060
|
+
this.forEachCurve((curve) => curve.transform(matrix));
|
|
2061
|
+
return this;
|
|
2062
|
+
}
|
|
1082
2063
|
getMinMax(min = new Point2D(), max = new Point2D()) {
|
|
1083
|
-
this.
|
|
2064
|
+
this.forEachCurve((curve) => curve.getMinMax(min, max));
|
|
1084
2065
|
return { min, max };
|
|
1085
2066
|
}
|
|
1086
2067
|
getCommands() {
|
|
@@ -1090,9 +2071,7 @@ class Path2D {
|
|
|
1090
2071
|
return this.paths.map((path) => path.getData()).join(" ");
|
|
1091
2072
|
}
|
|
1092
2073
|
getBoundingBox() {
|
|
1093
|
-
const min =
|
|
1094
|
-
const max = Point2D.MIN;
|
|
1095
|
-
this.paths.forEach((path) => path.getMinMax(min, max));
|
|
2074
|
+
const { min, max } = this.getMinMax();
|
|
1096
2075
|
return {
|
|
1097
2076
|
x: min.x,
|
|
1098
2077
|
y: min.y,
|
|
@@ -1108,10 +2087,8 @@ class Path2D {
|
|
|
1108
2087
|
return `data:image/svg+xml;base64,${btoa(this.getSvgString())}`;
|
|
1109
2088
|
}
|
|
1110
2089
|
drawTo(ctx) {
|
|
1111
|
-
this.
|
|
1112
|
-
|
|
1113
|
-
curve.drawTo(ctx);
|
|
1114
|
-
});
|
|
2090
|
+
this.forEachCurve((curve) => {
|
|
2091
|
+
curve.drawTo(ctx);
|
|
1115
2092
|
});
|
|
1116
2093
|
}
|
|
1117
2094
|
strokeTo(ctx) {
|
|
@@ -1124,4 +2101,511 @@ class Path2D {
|
|
|
1124
2101
|
}
|
|
1125
2102
|
}
|
|
1126
2103
|
|
|
1127
|
-
|
|
2104
|
+
const defaultUnit = "px";
|
|
2105
|
+
const defaultDPI = 90;
|
|
2106
|
+
const units = ["mm", "cm", "in", "pt", "pc", "px"];
|
|
2107
|
+
const unitConversion = {
|
|
2108
|
+
mm: {
|
|
2109
|
+
mm: 1,
|
|
2110
|
+
cm: 0.1,
|
|
2111
|
+
in: 1 / 25.4,
|
|
2112
|
+
pt: 72 / 25.4,
|
|
2113
|
+
pc: 6 / 25.4,
|
|
2114
|
+
px: -1
|
|
2115
|
+
},
|
|
2116
|
+
cm: {
|
|
2117
|
+
mm: 10,
|
|
2118
|
+
cm: 1,
|
|
2119
|
+
in: 1 / 2.54,
|
|
2120
|
+
pt: 72 / 2.54,
|
|
2121
|
+
pc: 6 / 2.54,
|
|
2122
|
+
px: -1
|
|
2123
|
+
},
|
|
2124
|
+
in: {
|
|
2125
|
+
mm: 25.4,
|
|
2126
|
+
cm: 2.54,
|
|
2127
|
+
in: 1,
|
|
2128
|
+
pt: 72,
|
|
2129
|
+
pc: 6,
|
|
2130
|
+
px: -1
|
|
2131
|
+
},
|
|
2132
|
+
pt: {
|
|
2133
|
+
mm: 25.4 / 72,
|
|
2134
|
+
cm: 2.54 / 72,
|
|
2135
|
+
in: 1 / 72,
|
|
2136
|
+
pt: 1,
|
|
2137
|
+
pc: 6 / 72,
|
|
2138
|
+
px: -1
|
|
2139
|
+
},
|
|
2140
|
+
pc: {
|
|
2141
|
+
mm: 25.4 / 6,
|
|
2142
|
+
cm: 2.54 / 6,
|
|
2143
|
+
in: 1 / 6,
|
|
2144
|
+
pt: 72 / 6,
|
|
2145
|
+
pc: 1,
|
|
2146
|
+
px: -1
|
|
2147
|
+
},
|
|
2148
|
+
px: {
|
|
2149
|
+
px: 1
|
|
2150
|
+
}
|
|
2151
|
+
};
|
|
2152
|
+
function parseFloatWithUnits(string) {
|
|
2153
|
+
let theUnit = "px";
|
|
2154
|
+
if (typeof string === "string" || string instanceof String) {
|
|
2155
|
+
for (let i = 0, n = units.length; i < n; i++) {
|
|
2156
|
+
const u = units[i];
|
|
2157
|
+
if (string.endsWith(u)) {
|
|
2158
|
+
theUnit = u;
|
|
2159
|
+
string = string.substring(0, string.length - u.length);
|
|
2160
|
+
break;
|
|
2161
|
+
}
|
|
2162
|
+
}
|
|
2163
|
+
}
|
|
2164
|
+
let scale;
|
|
2165
|
+
if (theUnit === "px" && defaultUnit !== "px") {
|
|
2166
|
+
scale = unitConversion.in[defaultUnit] / defaultDPI;
|
|
2167
|
+
} else {
|
|
2168
|
+
scale = unitConversion[theUnit][defaultUnit];
|
|
2169
|
+
if (scale < 0) {
|
|
2170
|
+
scale = unitConversion[theUnit].in * defaultDPI;
|
|
2171
|
+
}
|
|
2172
|
+
}
|
|
2173
|
+
return scale * Number.parseFloat(string);
|
|
2174
|
+
}
|
|
2175
|
+
|
|
2176
|
+
const tempTransform0 = new Matrix3();
|
|
2177
|
+
const tempTransform1 = new Matrix3();
|
|
2178
|
+
const tempTransform2 = new Matrix3();
|
|
2179
|
+
const tempTransform3 = new Matrix3();
|
|
2180
|
+
function getNodeTransform(node, currentTransform, transformStack) {
|
|
2181
|
+
if (!(node.hasAttribute("transform") || node.nodeName === "use" && (node.hasAttribute("x") || node.hasAttribute("y")))) {
|
|
2182
|
+
return null;
|
|
2183
|
+
}
|
|
2184
|
+
const transform = parseNodeTransform(node);
|
|
2185
|
+
if (transformStack.length > 0) {
|
|
2186
|
+
transform.premultiply(transformStack[transformStack.length - 1]);
|
|
2187
|
+
}
|
|
2188
|
+
currentTransform.copy(transform);
|
|
2189
|
+
transformStack.push(transform);
|
|
2190
|
+
return transform;
|
|
2191
|
+
}
|
|
2192
|
+
function parseNodeTransform(node) {
|
|
2193
|
+
const transform = new Matrix3();
|
|
2194
|
+
const currentTransform = tempTransform0;
|
|
2195
|
+
if (node.nodeName === "use" && (node.hasAttribute("x") || node.hasAttribute("y"))) {
|
|
2196
|
+
transform.translate(
|
|
2197
|
+
parseFloatWithUnits(node.getAttribute("x")),
|
|
2198
|
+
parseFloatWithUnits(node.getAttribute("y"))
|
|
2199
|
+
);
|
|
2200
|
+
}
|
|
2201
|
+
if (node.hasAttribute("transform")) {
|
|
2202
|
+
const transformsTexts = node.getAttribute("transform").split(")");
|
|
2203
|
+
for (let tIndex = transformsTexts.length - 1; tIndex >= 0; tIndex--) {
|
|
2204
|
+
const transformText = transformsTexts[tIndex].trim();
|
|
2205
|
+
if (transformText === "")
|
|
2206
|
+
continue;
|
|
2207
|
+
const openParPos = transformText.indexOf("(");
|
|
2208
|
+
const closeParPos = transformText.length;
|
|
2209
|
+
if (openParPos > 0 && openParPos < closeParPos) {
|
|
2210
|
+
const transformType = transformText.slice(0, openParPos);
|
|
2211
|
+
const array = parsePathDataArgs(transformText.slice(openParPos + 1));
|
|
2212
|
+
currentTransform.identity();
|
|
2213
|
+
switch (transformType) {
|
|
2214
|
+
case "translate":
|
|
2215
|
+
if (array.length >= 1) {
|
|
2216
|
+
const tx = array[0];
|
|
2217
|
+
let ty = 0;
|
|
2218
|
+
if (array.length >= 2) {
|
|
2219
|
+
ty = array[1];
|
|
2220
|
+
}
|
|
2221
|
+
currentTransform.translate(tx, ty);
|
|
2222
|
+
}
|
|
2223
|
+
break;
|
|
2224
|
+
case "rotate":
|
|
2225
|
+
if (array.length >= 1) {
|
|
2226
|
+
let angle = 0;
|
|
2227
|
+
let cx = 0;
|
|
2228
|
+
let cy = 0;
|
|
2229
|
+
angle = array[0] * Math.PI / 180;
|
|
2230
|
+
if (array.length >= 3) {
|
|
2231
|
+
cx = array[1];
|
|
2232
|
+
cy = array[2];
|
|
2233
|
+
}
|
|
2234
|
+
tempTransform1.makeTranslation(-cx, -cy);
|
|
2235
|
+
tempTransform2.makeRotation(angle);
|
|
2236
|
+
tempTransform3.multiplyMatrices(tempTransform2, tempTransform1);
|
|
2237
|
+
tempTransform1.makeTranslation(cx, cy);
|
|
2238
|
+
currentTransform.multiplyMatrices(tempTransform1, tempTransform3);
|
|
2239
|
+
}
|
|
2240
|
+
break;
|
|
2241
|
+
case "scale":
|
|
2242
|
+
if (array.length >= 1) {
|
|
2243
|
+
currentTransform.scale(
|
|
2244
|
+
array[0],
|
|
2245
|
+
array[1] ?? array[0]
|
|
2246
|
+
);
|
|
2247
|
+
}
|
|
2248
|
+
break;
|
|
2249
|
+
case "skewX":
|
|
2250
|
+
if (array.length === 1) {
|
|
2251
|
+
currentTransform.set(
|
|
2252
|
+
1,
|
|
2253
|
+
Math.tan(array[0] * Math.PI / 180),
|
|
2254
|
+
0,
|
|
2255
|
+
0,
|
|
2256
|
+
1,
|
|
2257
|
+
0,
|
|
2258
|
+
0,
|
|
2259
|
+
0,
|
|
2260
|
+
1
|
|
2261
|
+
);
|
|
2262
|
+
}
|
|
2263
|
+
break;
|
|
2264
|
+
case "skewY":
|
|
2265
|
+
if (array.length === 1) {
|
|
2266
|
+
currentTransform.set(
|
|
2267
|
+
1,
|
|
2268
|
+
0,
|
|
2269
|
+
0,
|
|
2270
|
+
Math.tan(array[0] * Math.PI / 180),
|
|
2271
|
+
1,
|
|
2272
|
+
0,
|
|
2273
|
+
0,
|
|
2274
|
+
0,
|
|
2275
|
+
1
|
|
2276
|
+
);
|
|
2277
|
+
}
|
|
2278
|
+
break;
|
|
2279
|
+
case "matrix":
|
|
2280
|
+
if (array.length === 6) {
|
|
2281
|
+
currentTransform.set(
|
|
2282
|
+
array[0],
|
|
2283
|
+
array[2],
|
|
2284
|
+
array[4],
|
|
2285
|
+
array[1],
|
|
2286
|
+
array[3],
|
|
2287
|
+
array[5],
|
|
2288
|
+
0,
|
|
2289
|
+
0,
|
|
2290
|
+
1
|
|
2291
|
+
);
|
|
2292
|
+
}
|
|
2293
|
+
break;
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2296
|
+
transform.premultiply(currentTransform);
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2299
|
+
return transform;
|
|
2300
|
+
}
|
|
2301
|
+
|
|
2302
|
+
function parseCircleNode(node) {
|
|
2303
|
+
return new Path2D().addPath(
|
|
2304
|
+
new CurvePath().absarc(
|
|
2305
|
+
parseFloatWithUnits(node.getAttribute("cx") || 0),
|
|
2306
|
+
parseFloatWithUnits(node.getAttribute("cy") || 0),
|
|
2307
|
+
parseFloatWithUnits(node.getAttribute("r") || 0),
|
|
2308
|
+
0,
|
|
2309
|
+
Math.PI * 2
|
|
2310
|
+
)
|
|
2311
|
+
);
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2314
|
+
function parseCSSStylesheet(node, stylesheets) {
|
|
2315
|
+
if (!node.sheet || !node.sheet.cssRules || !node.sheet.cssRules.length)
|
|
2316
|
+
return;
|
|
2317
|
+
for (let i = 0; i < node.sheet.cssRules.length; i++) {
|
|
2318
|
+
const stylesheet = node.sheet.cssRules[i];
|
|
2319
|
+
if (stylesheet.type !== 1)
|
|
2320
|
+
continue;
|
|
2321
|
+
const selectorList = stylesheet.selectorText.split(/,/g).filter(Boolean).map((i2) => i2.trim());
|
|
2322
|
+
for (let j = 0; j < selectorList.length; j++) {
|
|
2323
|
+
const definitions = Object.fromEntries(
|
|
2324
|
+
Object.entries(stylesheet.style).filter(([, v]) => v !== "")
|
|
2325
|
+
);
|
|
2326
|
+
stylesheets[selectorList[j]] = Object.assign(
|
|
2327
|
+
stylesheets[selectorList[j]] || {},
|
|
2328
|
+
definitions
|
|
2329
|
+
);
|
|
2330
|
+
}
|
|
2331
|
+
}
|
|
2332
|
+
}
|
|
2333
|
+
|
|
2334
|
+
function parseEllipseNode(node) {
|
|
2335
|
+
return new Path2D().addPath(
|
|
2336
|
+
new CurvePath().absellipse(
|
|
2337
|
+
parseFloatWithUnits(node.getAttribute("cx") || 0),
|
|
2338
|
+
parseFloatWithUnits(node.getAttribute("cy") || 0),
|
|
2339
|
+
parseFloatWithUnits(node.getAttribute("rx") || 0),
|
|
2340
|
+
parseFloatWithUnits(node.getAttribute("ry") || 0),
|
|
2341
|
+
0,
|
|
2342
|
+
Math.PI * 2
|
|
2343
|
+
)
|
|
2344
|
+
);
|
|
2345
|
+
}
|
|
2346
|
+
|
|
2347
|
+
function parseLineNode(node) {
|
|
2348
|
+
return new Path2D().moveTo(
|
|
2349
|
+
parseFloatWithUnits(node.getAttribute("x1") || 0),
|
|
2350
|
+
parseFloatWithUnits(node.getAttribute("y1") || 0)
|
|
2351
|
+
).lineTo(
|
|
2352
|
+
parseFloatWithUnits(node.getAttribute("x2") || 0),
|
|
2353
|
+
parseFloatWithUnits(node.getAttribute("y2") || 0)
|
|
2354
|
+
);
|
|
2355
|
+
}
|
|
2356
|
+
|
|
2357
|
+
function parsePathNode(node) {
|
|
2358
|
+
const path = new Path2D();
|
|
2359
|
+
const d = node.getAttribute("d");
|
|
2360
|
+
if (!d || d === "none")
|
|
2361
|
+
return null;
|
|
2362
|
+
path.addData(d);
|
|
2363
|
+
return path;
|
|
2364
|
+
}
|
|
2365
|
+
|
|
2366
|
+
const RE$1 = /([+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:e[+-]?\d+)?)(?:,|\s)([+-]?\d*\.?\d+(?:e[+-]?\d+)?)/g;
|
|
2367
|
+
function parsePolygonNode(node) {
|
|
2368
|
+
const path = new Path2D();
|
|
2369
|
+
let index = 0;
|
|
2370
|
+
node.getAttribute("points")?.replace(RE$1, (match, a, b) => {
|
|
2371
|
+
const x = parseFloatWithUnits(a);
|
|
2372
|
+
const y = parseFloatWithUnits(b);
|
|
2373
|
+
if (index === 0) {
|
|
2374
|
+
path.moveTo(x, y);
|
|
2375
|
+
} else {
|
|
2376
|
+
path.lineTo(x, y);
|
|
2377
|
+
}
|
|
2378
|
+
index++;
|
|
2379
|
+
return match;
|
|
2380
|
+
});
|
|
2381
|
+
path.currentPath.autoClose = true;
|
|
2382
|
+
return path;
|
|
2383
|
+
}
|
|
2384
|
+
|
|
2385
|
+
const RE = /([+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:e[+-]?\d+)?)(?:,|\s)([+-]?\d*\.?\d+(?:e[+-]?\d+)?)/g;
|
|
2386
|
+
function parsePolylineNode(node) {
|
|
2387
|
+
const path = new Path2D();
|
|
2388
|
+
let index = 0;
|
|
2389
|
+
node.getAttribute("points")?.replace(RE, (match, a, b) => {
|
|
2390
|
+
const x = parseFloatWithUnits(a);
|
|
2391
|
+
const y = parseFloatWithUnits(b);
|
|
2392
|
+
if (index === 0) {
|
|
2393
|
+
path.moveTo(x, y);
|
|
2394
|
+
} else {
|
|
2395
|
+
path.lineTo(x, y);
|
|
2396
|
+
}
|
|
2397
|
+
index++;
|
|
2398
|
+
return match;
|
|
2399
|
+
});
|
|
2400
|
+
path.currentPath.autoClose = false;
|
|
2401
|
+
return path;
|
|
2402
|
+
}
|
|
2403
|
+
|
|
2404
|
+
function parseRectNode(node) {
|
|
2405
|
+
const x = parseFloatWithUnits(node.getAttribute("x") || 0);
|
|
2406
|
+
const y = parseFloatWithUnits(node.getAttribute("y") || 0);
|
|
2407
|
+
const rx = parseFloatWithUnits(node.getAttribute("rx") || node.getAttribute("ry") || 0);
|
|
2408
|
+
const ry = parseFloatWithUnits(node.getAttribute("ry") || node.getAttribute("rx") || 0);
|
|
2409
|
+
const w = parseFloatWithUnits(node.getAttribute("width"));
|
|
2410
|
+
const h = parseFloatWithUnits(node.getAttribute("height"));
|
|
2411
|
+
const bci = 1 - 0.551915024494;
|
|
2412
|
+
const path = new Path2D();
|
|
2413
|
+
path.moveTo(x + rx, y);
|
|
2414
|
+
path.lineTo(x + w - rx, y);
|
|
2415
|
+
if (rx !== 0 || ry !== 0) {
|
|
2416
|
+
path.bezierCurveTo(
|
|
2417
|
+
x + w - rx * bci,
|
|
2418
|
+
y,
|
|
2419
|
+
x + w,
|
|
2420
|
+
y + ry * bci,
|
|
2421
|
+
x + w,
|
|
2422
|
+
y + ry
|
|
2423
|
+
);
|
|
2424
|
+
}
|
|
2425
|
+
path.lineTo(x + w, y + h - ry);
|
|
2426
|
+
if (rx !== 0 || ry !== 0) {
|
|
2427
|
+
path.bezierCurveTo(
|
|
2428
|
+
x + w,
|
|
2429
|
+
y + h - ry * bci,
|
|
2430
|
+
x + w - rx * bci,
|
|
2431
|
+
y + h,
|
|
2432
|
+
x + w - rx,
|
|
2433
|
+
y + h
|
|
2434
|
+
);
|
|
2435
|
+
}
|
|
2436
|
+
path.lineTo(x + rx, y + h);
|
|
2437
|
+
if (rx !== 0 || ry !== 0) {
|
|
2438
|
+
path.bezierCurveTo(
|
|
2439
|
+
x + rx * bci,
|
|
2440
|
+
y + h,
|
|
2441
|
+
x,
|
|
2442
|
+
y + h - ry * bci,
|
|
2443
|
+
x,
|
|
2444
|
+
y + h - ry
|
|
2445
|
+
);
|
|
2446
|
+
}
|
|
2447
|
+
path.lineTo(x, y + ry);
|
|
2448
|
+
if (rx !== 0 || ry !== 0) {
|
|
2449
|
+
path.bezierCurveTo(x, y + ry * bci, x + rx * bci, y, x + rx, y);
|
|
2450
|
+
}
|
|
2451
|
+
return path;
|
|
2452
|
+
}
|
|
2453
|
+
|
|
2454
|
+
function parseStyle(node, style, stylesheets) {
|
|
2455
|
+
style = Object.assign({}, style);
|
|
2456
|
+
let stylesheetStyles = {};
|
|
2457
|
+
if (node.hasAttribute("class")) {
|
|
2458
|
+
const classSelectors = node.getAttribute("class").split(/\s/).filter(Boolean).map((i) => i.trim());
|
|
2459
|
+
for (let i = 0; i < classSelectors.length; i++) {
|
|
2460
|
+
stylesheetStyles = Object.assign(stylesheetStyles, stylesheets[`.${classSelectors[i]}`]);
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
if (node.hasAttribute("id")) {
|
|
2464
|
+
stylesheetStyles = Object.assign(stylesheetStyles, stylesheets[`#${node.getAttribute("id")}`]);
|
|
2465
|
+
}
|
|
2466
|
+
function addStyle(svgName, jsName, adjustFunction) {
|
|
2467
|
+
if (adjustFunction === void 0) {
|
|
2468
|
+
adjustFunction = function copy(v) {
|
|
2469
|
+
if (v.startsWith("url"))
|
|
2470
|
+
console.warn("url access in attributes is not implemented.");
|
|
2471
|
+
return v;
|
|
2472
|
+
};
|
|
2473
|
+
}
|
|
2474
|
+
if (node.hasAttribute(svgName))
|
|
2475
|
+
style[jsName] = adjustFunction(node.getAttribute(svgName));
|
|
2476
|
+
if (stylesheetStyles[svgName])
|
|
2477
|
+
style[jsName] = adjustFunction(stylesheetStyles[svgName]);
|
|
2478
|
+
if (node.style && node.style[svgName] !== "")
|
|
2479
|
+
style[jsName] = adjustFunction(node.style[svgName]);
|
|
2480
|
+
}
|
|
2481
|
+
function clamp(v) {
|
|
2482
|
+
return Math.max(0, Math.min(1, parseFloatWithUnits(v)));
|
|
2483
|
+
}
|
|
2484
|
+
function positive(v) {
|
|
2485
|
+
return Math.max(0, parseFloatWithUnits(v));
|
|
2486
|
+
}
|
|
2487
|
+
addStyle("fill", "fill");
|
|
2488
|
+
addStyle("fill-opacity", "fillOpacity", clamp);
|
|
2489
|
+
addStyle("fill-rule", "fillRule");
|
|
2490
|
+
addStyle("opacity", "opacity", clamp);
|
|
2491
|
+
addStyle("stroke", "stroke");
|
|
2492
|
+
addStyle("stroke-dashoffset", "strokeDashoffset");
|
|
2493
|
+
addStyle("stroke-dasharray", "strokeDasharray");
|
|
2494
|
+
addStyle("stroke-linecap", "strokeLineCap");
|
|
2495
|
+
addStyle("stroke-linejoin", "strokeLineJoin");
|
|
2496
|
+
addStyle("stroke-miterlimit", "strokeMiterLimit", positive);
|
|
2497
|
+
addStyle("stroke-opacity", "strokeOpacity", clamp);
|
|
2498
|
+
addStyle("stroke-width", "strokeWidth", positive);
|
|
2499
|
+
addStyle("visibility", "visibility");
|
|
2500
|
+
return style;
|
|
2501
|
+
}
|
|
2502
|
+
|
|
2503
|
+
function parseNode(node, style, paths = []) {
|
|
2504
|
+
if (node.nodeType !== 1)
|
|
2505
|
+
return paths;
|
|
2506
|
+
let isDefsNode = false;
|
|
2507
|
+
let path = null;
|
|
2508
|
+
const stylesheets = {};
|
|
2509
|
+
switch (node.nodeName) {
|
|
2510
|
+
case "svg":
|
|
2511
|
+
style = parseStyle(node, style, stylesheets);
|
|
2512
|
+
break;
|
|
2513
|
+
case "style":
|
|
2514
|
+
parseCSSStylesheet(node, stylesheets);
|
|
2515
|
+
break;
|
|
2516
|
+
case "g":
|
|
2517
|
+
style = parseStyle(node, style, stylesheets);
|
|
2518
|
+
break;
|
|
2519
|
+
case "path":
|
|
2520
|
+
style = parseStyle(node, style, stylesheets);
|
|
2521
|
+
if (node.hasAttribute("d"))
|
|
2522
|
+
path = parsePathNode(node);
|
|
2523
|
+
break;
|
|
2524
|
+
case "rect":
|
|
2525
|
+
style = parseStyle(node, style, stylesheets);
|
|
2526
|
+
path = parseRectNode(node);
|
|
2527
|
+
break;
|
|
2528
|
+
case "polygon":
|
|
2529
|
+
style = parseStyle(node, style, stylesheets);
|
|
2530
|
+
path = parsePolygonNode(node);
|
|
2531
|
+
break;
|
|
2532
|
+
case "polyline":
|
|
2533
|
+
style = parseStyle(node, style, stylesheets);
|
|
2534
|
+
path = parsePolylineNode(node);
|
|
2535
|
+
break;
|
|
2536
|
+
case "circle":
|
|
2537
|
+
style = parseStyle(node, style, stylesheets);
|
|
2538
|
+
path = parseCircleNode(node);
|
|
2539
|
+
break;
|
|
2540
|
+
case "ellipse":
|
|
2541
|
+
style = parseStyle(node, style, stylesheets);
|
|
2542
|
+
path = parseEllipseNode(node);
|
|
2543
|
+
break;
|
|
2544
|
+
case "line":
|
|
2545
|
+
style = parseStyle(node, style, stylesheets);
|
|
2546
|
+
path = parseLineNode(node);
|
|
2547
|
+
break;
|
|
2548
|
+
case "defs":
|
|
2549
|
+
isDefsNode = true;
|
|
2550
|
+
break;
|
|
2551
|
+
case "use": {
|
|
2552
|
+
style = parseStyle(node, style, stylesheets);
|
|
2553
|
+
const href = node.getAttributeNS("http://www.w3.org/1999/xlink", "href") || "";
|
|
2554
|
+
const usedNodeId = href.substring(1);
|
|
2555
|
+
const usedNode = node.viewportElement?.getElementById(usedNodeId);
|
|
2556
|
+
if (usedNode) {
|
|
2557
|
+
parseNode(usedNode, style, paths);
|
|
2558
|
+
} else {
|
|
2559
|
+
console.warn(`'use node' references non-existent node id: ${usedNodeId}`);
|
|
2560
|
+
}
|
|
2561
|
+
break;
|
|
2562
|
+
}
|
|
2563
|
+
default:
|
|
2564
|
+
console.warn(node);
|
|
2565
|
+
break;
|
|
2566
|
+
}
|
|
2567
|
+
const currentTransform = new Matrix3();
|
|
2568
|
+
const transformStack = [];
|
|
2569
|
+
const transform = getNodeTransform(node, currentTransform, transformStack);
|
|
2570
|
+
if (path) {
|
|
2571
|
+
path.transform(currentTransform);
|
|
2572
|
+
paths.push(path);
|
|
2573
|
+
path.userData = { node, style };
|
|
2574
|
+
}
|
|
2575
|
+
const childNodes = node.childNodes;
|
|
2576
|
+
for (let i = 0, len = childNodes.length; i < len; i++) {
|
|
2577
|
+
const node2 = childNodes[i];
|
|
2578
|
+
if (isDefsNode && node2.nodeName !== "style" && node2.nodeName !== "defs")
|
|
2579
|
+
continue;
|
|
2580
|
+
parseNode(node2, style, paths);
|
|
2581
|
+
}
|
|
2582
|
+
if (transform) {
|
|
2583
|
+
transformStack.pop();
|
|
2584
|
+
if (transformStack.length > 0) {
|
|
2585
|
+
currentTransform.copy(transformStack[transformStack.length - 1]);
|
|
2586
|
+
} else {
|
|
2587
|
+
currentTransform.identity();
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2590
|
+
return paths;
|
|
2591
|
+
}
|
|
2592
|
+
|
|
2593
|
+
function parseSvg(svg) {
|
|
2594
|
+
let node;
|
|
2595
|
+
if (typeof svg === "string") {
|
|
2596
|
+
node = new DOMParser().parseFromString(svg, "image/svg+xml").documentElement;
|
|
2597
|
+
} else {
|
|
2598
|
+
node = svg;
|
|
2599
|
+
}
|
|
2600
|
+
return parseNode(node, {
|
|
2601
|
+
fill: "#000",
|
|
2602
|
+
fillOpacity: 1,
|
|
2603
|
+
strokeOpacity: 1,
|
|
2604
|
+
strokeWidth: 1,
|
|
2605
|
+
strokeLineJoin: "miter",
|
|
2606
|
+
strokeLineCap: "butt",
|
|
2607
|
+
strokeMiterLimit: 4
|
|
2608
|
+
});
|
|
2609
|
+
}
|
|
2610
|
+
|
|
2611
|
+
export { CircleCurve, CubicBezierCurve, Curve, CurvePath, EllipseCurve, HeartCurve, LineCurve, Matrix3, Path2D, PloygonCurve, Point2D, QuadraticBezierCurve, RectangularCurve, SplineCurve, parseSvg };
|