@emasoft/svg-matrix 1.0.27 → 1.0.29
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 +325 -0
- package/bin/svg-matrix.js +994 -378
- package/bin/svglinter.cjs +4172 -433
- package/bin/svgm.js +744 -184
- package/package.json +16 -4
- package/src/animation-references.js +71 -52
- package/src/arc-length.js +160 -96
- package/src/bezier-analysis.js +257 -117
- package/src/bezier-intersections.js +411 -148
- package/src/browser-verify.js +240 -100
- package/src/clip-path-resolver.js +350 -142
- package/src/convert-path-data.js +279 -134
- package/src/css-specificity.js +78 -70
- package/src/flatten-pipeline.js +751 -263
- package/src/geometry-to-path.js +511 -182
- package/src/index.js +191 -46
- package/src/inkscape-support.js +404 -0
- package/src/marker-resolver.js +278 -164
- package/src/mask-resolver.js +209 -98
- package/src/matrix.js +147 -67
- package/src/mesh-gradient.js +187 -96
- package/src/off-canvas-detection.js +201 -104
- package/src/path-analysis.js +187 -107
- package/src/path-data-plugins.js +628 -167
- package/src/path-simplification.js +0 -1
- package/src/pattern-resolver.js +125 -88
- package/src/polygon-clip.js +111 -66
- package/src/svg-boolean-ops.js +194 -118
- package/src/svg-collections.js +48 -19
- package/src/svg-flatten.js +282 -164
- package/src/svg-parser.js +427 -200
- package/src/svg-rendering-context.js +147 -104
- package/src/svg-toolbox.js +16411 -3298
- package/src/svg2-polyfills.js +114 -245
- package/src/transform-decomposition.js +46 -41
- package/src/transform-optimization.js +89 -68
- package/src/transforms2d.js +49 -16
- package/src/transforms3d.js +58 -22
- package/src/use-symbol-resolver.js +150 -110
- package/src/vector.js +67 -15
- package/src/vendor/README.md +110 -0
- package/src/vendor/inkscape-hatch-polyfill.js +401 -0
- package/src/vendor/inkscape-hatch-polyfill.min.js +8 -0
- package/src/vendor/inkscape-mesh-polyfill.js +843 -0
- package/src/vendor/inkscape-mesh-polyfill.min.js +8 -0
- package/src/verification.js +288 -124
package/src/transforms3d.js
CHANGED
|
@@ -1,12 +1,27 @@
|
|
|
1
|
-
import Decimal from
|
|
2
|
-
import { Matrix } from
|
|
1
|
+
import Decimal from "decimal.js";
|
|
2
|
+
import { Matrix } from "./matrix.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Helper to convert any numeric input to Decimal.
|
|
6
6
|
* @param {number|string|Decimal} x - The value to convert
|
|
7
7
|
* @returns {Decimal} The Decimal representation
|
|
8
8
|
*/
|
|
9
|
-
const D = x => (x instanceof Decimal ? x : new Decimal(x));
|
|
9
|
+
const D = (x) => (x instanceof Decimal ? x : new Decimal(x));
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Validates that a value is a valid numeric type (number, string, or Decimal).
|
|
13
|
+
* @param {*} value - The value to validate
|
|
14
|
+
* @param {string} name - The parameter name for error messages
|
|
15
|
+
* @throws {Error} If value is null, undefined, or not a valid numeric type
|
|
16
|
+
*/
|
|
17
|
+
function validateNumeric(value, name) {
|
|
18
|
+
if (value === undefined || value === null) {
|
|
19
|
+
throw new Error(`${name} is required`);
|
|
20
|
+
}
|
|
21
|
+
if (typeof value !== 'number' && typeof value !== 'string' && !(value instanceof Decimal)) {
|
|
22
|
+
throw new Error(`${name} must be a number, string, or Decimal`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
10
25
|
|
|
11
26
|
/**
|
|
12
27
|
* 3D Affine Transforms using 4x4 homogeneous matrices.
|
|
@@ -85,11 +100,14 @@ const D = x => (x instanceof Decimal ? x : new Decimal(x));
|
|
|
85
100
|
* // First translates by (10,0,0), then rotates around Z
|
|
86
101
|
*/
|
|
87
102
|
export function translation(tx, ty, tz) {
|
|
103
|
+
validateNumeric(tx, 'tx');
|
|
104
|
+
validateNumeric(ty, 'ty');
|
|
105
|
+
validateNumeric(tz, 'tz');
|
|
88
106
|
return Matrix.from([
|
|
89
107
|
[new Decimal(1), new Decimal(0), new Decimal(0), D(tx)],
|
|
90
108
|
[new Decimal(0), new Decimal(1), new Decimal(0), D(ty)],
|
|
91
109
|
[new Decimal(0), new Decimal(0), new Decimal(1), D(tz)],
|
|
92
|
-
[new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)]
|
|
110
|
+
[new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)],
|
|
93
111
|
]);
|
|
94
112
|
}
|
|
95
113
|
|
|
@@ -131,13 +149,20 @@ export function translation(tx, ty, tz) {
|
|
|
131
149
|
* const mirror = scale(-1, 1, 1); // Flip X axis
|
|
132
150
|
*/
|
|
133
151
|
export function scale(sx, sy = null, sz = null) {
|
|
134
|
-
|
|
135
|
-
if (
|
|
152
|
+
validateNumeric(sx, 'sx');
|
|
153
|
+
if (sy !== null) {
|
|
154
|
+
validateNumeric(sy, 'sy');
|
|
155
|
+
}
|
|
156
|
+
if (sz !== null) {
|
|
157
|
+
validateNumeric(sz, 'sz');
|
|
158
|
+
}
|
|
159
|
+
const syValue = sy === null ? sx : sy;
|
|
160
|
+
const szValue = sz === null ? sx : sz;
|
|
136
161
|
return Matrix.from([
|
|
137
162
|
[D(sx), new Decimal(0), new Decimal(0), new Decimal(0)],
|
|
138
|
-
[new Decimal(0), D(
|
|
139
|
-
[new Decimal(0), new Decimal(0), D(
|
|
140
|
-
[new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)]
|
|
163
|
+
[new Decimal(0), D(syValue), new Decimal(0), new Decimal(0)],
|
|
164
|
+
[new Decimal(0), new Decimal(0), D(szValue), new Decimal(0)],
|
|
165
|
+
[new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)],
|
|
141
166
|
]);
|
|
142
167
|
}
|
|
143
168
|
|
|
@@ -180,7 +205,7 @@ export function rotateX(theta) {
|
|
|
180
205
|
[new Decimal(1), new Decimal(0), new Decimal(0), new Decimal(0)],
|
|
181
206
|
[new Decimal(0), c, s.negated(), new Decimal(0)],
|
|
182
207
|
[new Decimal(0), s, c, new Decimal(0)],
|
|
183
|
-
[new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)]
|
|
208
|
+
[new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)],
|
|
184
209
|
]);
|
|
185
210
|
}
|
|
186
211
|
|
|
@@ -224,7 +249,7 @@ export function rotateY(theta) {
|
|
|
224
249
|
[c, new Decimal(0), s, new Decimal(0)],
|
|
225
250
|
[new Decimal(0), new Decimal(1), new Decimal(0), new Decimal(0)],
|
|
226
251
|
[s.negated(), new Decimal(0), c, new Decimal(0)],
|
|
227
|
-
[new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)]
|
|
252
|
+
[new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)],
|
|
228
253
|
]);
|
|
229
254
|
}
|
|
230
255
|
|
|
@@ -269,7 +294,7 @@ export function rotateZ(theta) {
|
|
|
269
294
|
[c, s.negated(), new Decimal(0), new Decimal(0)],
|
|
270
295
|
[s, c, new Decimal(0), new Decimal(0)],
|
|
271
296
|
[new Decimal(0), new Decimal(0), new Decimal(1), new Decimal(0)],
|
|
272
|
-
[new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)]
|
|
297
|
+
[new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)],
|
|
273
298
|
]);
|
|
274
299
|
}
|
|
275
300
|
|
|
@@ -328,9 +353,13 @@ export function rotateZ(theta) {
|
|
|
328
353
|
* // Equivalent to rotateX(Math.PI / 2)
|
|
329
354
|
*/
|
|
330
355
|
export function rotateAroundAxis(ux, uy, uz, theta) {
|
|
356
|
+
validateNumeric(ux, 'ux');
|
|
357
|
+
validateNumeric(uy, 'uy');
|
|
358
|
+
validateNumeric(uz, 'uz');
|
|
359
|
+
validateNumeric(theta, 'theta');
|
|
331
360
|
const u = [D(ux), D(uy), D(uz)];
|
|
332
|
-
|
|
333
|
-
if (norm.isZero()) throw new Error(
|
|
361
|
+
const norm = u[0].mul(u[0]).plus(u[1].mul(u[1])).plus(u[2].mul(u[2])).sqrt();
|
|
362
|
+
if (norm.isZero()) throw new Error("Rotation axis cannot be zero vector");
|
|
334
363
|
// Normalize axis
|
|
335
364
|
u[0] = u[0].div(norm);
|
|
336
365
|
u[1] = u[1].div(norm);
|
|
@@ -342,7 +371,9 @@ export function rotateAroundAxis(ux, uy, uz, theta) {
|
|
|
342
371
|
const one = new Decimal(1);
|
|
343
372
|
|
|
344
373
|
// Rodrigues' rotation formula components
|
|
345
|
-
const ux2 = u[0].mul(u[0]),
|
|
374
|
+
const ux2 = u[0].mul(u[0]),
|
|
375
|
+
uy2 = u[1].mul(u[1]),
|
|
376
|
+
uz2 = u[2].mul(u[2]);
|
|
346
377
|
const m00 = ux2.plus(c.mul(one.minus(ux2)));
|
|
347
378
|
const m01 = u[0].mul(u[1]).mul(one.minus(c)).minus(u[2].mul(s));
|
|
348
379
|
const m02 = u[0].mul(u[2]).mul(one.minus(c)).plus(u[1].mul(s));
|
|
@@ -357,7 +388,7 @@ export function rotateAroundAxis(ux, uy, uz, theta) {
|
|
|
357
388
|
[m00, m01, m02, new Decimal(0)],
|
|
358
389
|
[m10, m11, m12, new Decimal(0)],
|
|
359
390
|
[m20, m21, m22, new Decimal(0)],
|
|
360
|
-
[new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)]
|
|
391
|
+
[new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)],
|
|
361
392
|
]);
|
|
362
393
|
}
|
|
363
394
|
|
|
@@ -404,7 +435,9 @@ export function rotateAroundAxis(ux, uy, uz, theta) {
|
|
|
404
435
|
* // Complex rotation around axis (1,1,1) passing through (10,20,30)
|
|
405
436
|
*/
|
|
406
437
|
export function rotateAroundPoint(ux, uy, uz, theta, px, py, pz) {
|
|
407
|
-
const pxD = D(px),
|
|
438
|
+
const pxD = D(px),
|
|
439
|
+
pyD = D(py),
|
|
440
|
+
pzD = D(pz);
|
|
408
441
|
return translation(pxD, pyD, pzD)
|
|
409
442
|
.mul(rotateAroundAxis(ux, uy, uz, theta))
|
|
410
443
|
.mul(translation(pxD.negated(), pyD.negated(), pzD.negated()));
|
|
@@ -458,7 +491,10 @@ export function rotateAroundPoint(ux, uy, uz, theta, px, py, pz) {
|
|
|
458
491
|
export function applyTransform(M, x, y, z) {
|
|
459
492
|
const P = Matrix.from([[D(x)], [D(y)], [D(z)], [new Decimal(1)]]);
|
|
460
493
|
const R = M.mul(P);
|
|
461
|
-
const rx = R.data[0][0],
|
|
494
|
+
const rx = R.data[0][0],
|
|
495
|
+
ry = R.data[1][0],
|
|
496
|
+
rz = R.data[2][0],
|
|
497
|
+
rw = R.data[3][0];
|
|
462
498
|
// Perspective division (for affine transforms, rw is always 1)
|
|
463
499
|
return [rx.div(rw), ry.div(rw), rz.div(rw)];
|
|
464
500
|
}
|
|
@@ -499,7 +535,7 @@ export function reflectXY() {
|
|
|
499
535
|
[new Decimal(1), new Decimal(0), new Decimal(0), new Decimal(0)],
|
|
500
536
|
[new Decimal(0), new Decimal(1), new Decimal(0), new Decimal(0)],
|
|
501
537
|
[new Decimal(0), new Decimal(0), new Decimal(-1), new Decimal(0)],
|
|
502
|
-
[new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)]
|
|
538
|
+
[new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)],
|
|
503
539
|
]);
|
|
504
540
|
}
|
|
505
541
|
|
|
@@ -538,7 +574,7 @@ export function reflectXZ() {
|
|
|
538
574
|
[new Decimal(1), new Decimal(0), new Decimal(0), new Decimal(0)],
|
|
539
575
|
[new Decimal(0), new Decimal(-1), new Decimal(0), new Decimal(0)],
|
|
540
576
|
[new Decimal(0), new Decimal(0), new Decimal(1), new Decimal(0)],
|
|
541
|
-
[new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)]
|
|
577
|
+
[new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)],
|
|
542
578
|
]);
|
|
543
579
|
}
|
|
544
580
|
|
|
@@ -577,7 +613,7 @@ export function reflectYZ() {
|
|
|
577
613
|
[new Decimal(-1), new Decimal(0), new Decimal(0), new Decimal(0)],
|
|
578
614
|
[new Decimal(0), new Decimal(1), new Decimal(0), new Decimal(0)],
|
|
579
615
|
[new Decimal(0), new Decimal(0), new Decimal(1), new Decimal(0)],
|
|
580
|
-
[new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)]
|
|
616
|
+
[new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)],
|
|
581
617
|
]);
|
|
582
618
|
}
|
|
583
619
|
|
|
@@ -627,6 +663,6 @@ export function reflectOrigin() {
|
|
|
627
663
|
[new Decimal(-1), new Decimal(0), new Decimal(0), new Decimal(0)],
|
|
628
664
|
[new Decimal(0), new Decimal(-1), new Decimal(0), new Decimal(0)],
|
|
629
665
|
[new Decimal(0), new Decimal(0), new Decimal(-1), new Decimal(0)],
|
|
630
|
-
[new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)]
|
|
666
|
+
[new Decimal(0), new Decimal(0), new Decimal(0), new Decimal(1)],
|
|
631
667
|
]);
|
|
632
668
|
}
|