@emasoft/svg-matrix 1.0.30 → 1.0.31
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/bin/svg-matrix.js +310 -61
- package/bin/svglinter.cjs +102 -3
- package/bin/svgm.js +236 -27
- package/package.json +1 -1
- package/src/animation-optimization.js +137 -17
- package/src/animation-references.js +123 -6
- package/src/arc-length.js +213 -4
- package/src/bezier-analysis.js +217 -21
- package/src/bezier-intersections.js +275 -12
- package/src/browser-verify.js +237 -4
- package/src/clip-path-resolver.js +168 -0
- package/src/convert-path-data.js +479 -28
- package/src/css-specificity.js +73 -10
- package/src/douglas-peucker.js +219 -2
- package/src/flatten-pipeline.js +284 -26
- package/src/geometry-to-path.js +250 -25
- package/src/gjk-collision.js +236 -33
- package/src/index.js +261 -3
- package/src/inkscape-support.js +86 -28
- package/src/logger.js +48 -3
- package/src/marker-resolver.js +278 -74
- package/src/mask-resolver.js +265 -66
- package/src/matrix.js +44 -5
- package/src/mesh-gradient.js +352 -102
- package/src/off-canvas-detection.js +382 -13
- package/src/path-analysis.js +192 -18
- package/src/path-data-plugins.js +309 -5
- package/src/path-optimization.js +129 -5
- package/src/path-simplification.js +188 -32
- package/src/pattern-resolver.js +454 -106
- package/src/polygon-clip.js +324 -1
- package/src/svg-boolean-ops.js +226 -9
- package/src/svg-collections.js +7 -5
- package/src/svg-flatten.js +386 -62
- package/src/svg-parser.js +179 -8
- package/src/svg-rendering-context.js +235 -6
- package/src/svg-toolbox.js +45 -8
- package/src/svg2-polyfills.js +40 -10
- package/src/transform-decomposition.js +258 -32
- package/src/transform-optimization.js +259 -13
- package/src/transforms2d.js +82 -9
- package/src/transforms3d.js +62 -10
- package/src/use-symbol-resolver.js +286 -42
- package/src/vector.js +64 -8
- package/src/verification.js +392 -1
package/src/index.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* SVG path conversion, and 2D/3D affine transformations using Decimal.js.
|
|
6
6
|
*
|
|
7
7
|
* @module @emasoft/svg-matrix
|
|
8
|
-
* @version 1.0.
|
|
8
|
+
* @version 1.0.31
|
|
9
9
|
* @license MIT
|
|
10
10
|
*
|
|
11
11
|
* @example
|
|
@@ -93,7 +93,6 @@ import {
|
|
|
93
93
|
Logger,
|
|
94
94
|
LogLevel,
|
|
95
95
|
setLogLevel,
|
|
96
|
-
getLogLevel as _getLoggerLevel,
|
|
97
96
|
enableFileLogging,
|
|
98
97
|
disableFileLogging,
|
|
99
98
|
} from "./logger.js";
|
|
@@ -135,7 +134,7 @@ Decimal.set({ precision: 80 });
|
|
|
135
134
|
* Library version
|
|
136
135
|
* @constant {string}
|
|
137
136
|
*/
|
|
138
|
-
export const VERSION = '1.0.
|
|
137
|
+
export const VERSION = '1.0.31';
|
|
139
138
|
|
|
140
139
|
/**
|
|
141
140
|
* Default precision for path output (decimal places)
|
|
@@ -352,8 +351,15 @@ export { Logger, LogLevel, setLogLevel, enableFileLogging, disableFileLogging };
|
|
|
352
351
|
* @param {number|string|Decimal} tx - X translation
|
|
353
352
|
* @param {number|string|Decimal} ty - Y translation
|
|
354
353
|
* @returns {Matrix} 3x3 translation matrix
|
|
354
|
+
* @throws {TypeError} If tx or ty is null or undefined
|
|
355
355
|
*/
|
|
356
356
|
export function translate2D(tx, ty) {
|
|
357
|
+
if (tx == null) {
|
|
358
|
+
throw new TypeError("translate2D: tx cannot be null or undefined");
|
|
359
|
+
}
|
|
360
|
+
if (ty == null) {
|
|
361
|
+
throw new TypeError("translate2D: ty cannot be null or undefined");
|
|
362
|
+
}
|
|
357
363
|
return Transforms2D.translation(tx, ty);
|
|
358
364
|
}
|
|
359
365
|
|
|
@@ -362,8 +368,12 @@ export function translate2D(tx, ty) {
|
|
|
362
368
|
* Convenience wrapper for Transforms2D.rotate().
|
|
363
369
|
* @param {number|string|Decimal} angle - Rotation angle in radians
|
|
364
370
|
* @returns {Matrix} 3x3 rotation matrix
|
|
371
|
+
* @throws {TypeError} If angle is null or undefined
|
|
365
372
|
*/
|
|
366
373
|
export function rotate2D(angle) {
|
|
374
|
+
if (angle == null) {
|
|
375
|
+
throw new TypeError("rotate2D: angle cannot be null or undefined");
|
|
376
|
+
}
|
|
367
377
|
return Transforms2D.rotate(angle);
|
|
368
378
|
}
|
|
369
379
|
|
|
@@ -373,8 +383,12 @@ export function rotate2D(angle) {
|
|
|
373
383
|
* @param {number|string|Decimal} sx - X scale factor
|
|
374
384
|
* @param {number|string|Decimal} [sy=sx] - Y scale factor (defaults to sx for uniform scaling)
|
|
375
385
|
* @returns {Matrix} 3x3 scale matrix
|
|
386
|
+
* @throws {TypeError} If sx is null or undefined
|
|
376
387
|
*/
|
|
377
388
|
export function scale2D(sx, sy = null) {
|
|
389
|
+
if (sx == null) {
|
|
390
|
+
throw new TypeError("scale2D: sx cannot be null or undefined");
|
|
391
|
+
}
|
|
378
392
|
return Transforms2D.scale(sx, sy);
|
|
379
393
|
}
|
|
380
394
|
|
|
@@ -385,8 +399,18 @@ export function scale2D(sx, sy = null) {
|
|
|
385
399
|
* @param {number|string|Decimal} x - X coordinate
|
|
386
400
|
* @param {number|string|Decimal} y - Y coordinate
|
|
387
401
|
* @returns {[Decimal, Decimal]} Transformed [x, y] coordinates
|
|
402
|
+
* @throws {TypeError} If matrix, x, or y is null or undefined
|
|
388
403
|
*/
|
|
389
404
|
export function transform2D(matrix, x, y) {
|
|
405
|
+
if (matrix == null) {
|
|
406
|
+
throw new TypeError("transform2D: matrix cannot be null or undefined");
|
|
407
|
+
}
|
|
408
|
+
if (x == null) {
|
|
409
|
+
throw new TypeError("transform2D: x cannot be null or undefined");
|
|
410
|
+
}
|
|
411
|
+
if (y == null) {
|
|
412
|
+
throw new TypeError("transform2D: y cannot be null or undefined");
|
|
413
|
+
}
|
|
390
414
|
return Transforms2D.applyTransform(matrix, x, y);
|
|
391
415
|
}
|
|
392
416
|
|
|
@@ -397,8 +421,18 @@ export function transform2D(matrix, x, y) {
|
|
|
397
421
|
* @param {number|string|Decimal} ty - Y translation
|
|
398
422
|
* @param {number|string|Decimal} tz - Z translation
|
|
399
423
|
* @returns {Matrix} 4x4 translation matrix
|
|
424
|
+
* @throws {TypeError} If tx, ty, or tz is null or undefined
|
|
400
425
|
*/
|
|
401
426
|
export function translate3D(tx, ty, tz) {
|
|
427
|
+
if (tx == null) {
|
|
428
|
+
throw new TypeError("translate3D: tx cannot be null or undefined");
|
|
429
|
+
}
|
|
430
|
+
if (ty == null) {
|
|
431
|
+
throw new TypeError("translate3D: ty cannot be null or undefined");
|
|
432
|
+
}
|
|
433
|
+
if (tz == null) {
|
|
434
|
+
throw new TypeError("translate3D: tz cannot be null or undefined");
|
|
435
|
+
}
|
|
402
436
|
return Transforms3D.translation(tx, ty, tz);
|
|
403
437
|
}
|
|
404
438
|
|
|
@@ -409,8 +443,12 @@ export function translate3D(tx, ty, tz) {
|
|
|
409
443
|
* @param {number|string|Decimal} [sy=sx] - Y scale factor
|
|
410
444
|
* @param {number|string|Decimal} [sz=sx] - Z scale factor
|
|
411
445
|
* @returns {Matrix} 4x4 scale matrix
|
|
446
|
+
* @throws {TypeError} If sx is null or undefined
|
|
412
447
|
*/
|
|
413
448
|
export function scale3D(sx, sy = null, sz = null) {
|
|
449
|
+
if (sx == null) {
|
|
450
|
+
throw new TypeError("scale3D: sx cannot be null or undefined");
|
|
451
|
+
}
|
|
414
452
|
return Transforms3D.scale(sx, sy, sz);
|
|
415
453
|
}
|
|
416
454
|
|
|
@@ -422,8 +460,21 @@ export function scale3D(sx, sy = null, sz = null) {
|
|
|
422
460
|
* @param {number|string|Decimal} y - Y coordinate
|
|
423
461
|
* @param {number|string|Decimal} z - Z coordinate
|
|
424
462
|
* @returns {[Decimal, Decimal, Decimal]} Transformed [x, y, z] coordinates
|
|
463
|
+
* @throws {TypeError} If matrix, x, y, or z is null or undefined
|
|
425
464
|
*/
|
|
426
465
|
export function transform3D(matrix, x, y, z) {
|
|
466
|
+
if (matrix == null) {
|
|
467
|
+
throw new TypeError("transform3D: matrix cannot be null or undefined");
|
|
468
|
+
}
|
|
469
|
+
if (x == null) {
|
|
470
|
+
throw new TypeError("transform3D: x cannot be null or undefined");
|
|
471
|
+
}
|
|
472
|
+
if (y == null) {
|
|
473
|
+
throw new TypeError("transform3D: y cannot be null or undefined");
|
|
474
|
+
}
|
|
475
|
+
if (z == null) {
|
|
476
|
+
throw new TypeError("transform3D: z cannot be null or undefined");
|
|
477
|
+
}
|
|
427
478
|
return Transforms3D.applyTransform(matrix, x, y, z);
|
|
428
479
|
}
|
|
429
480
|
|
|
@@ -435,8 +486,25 @@ export function transform3D(matrix, x, y, z) {
|
|
|
435
486
|
* @param {number|string|Decimal} r - Radius
|
|
436
487
|
* @param {number} [precision=6] - Number of decimal places in output
|
|
437
488
|
* @returns {string} SVG path data string
|
|
489
|
+
* @throws {TypeError} If cx, cy, or r is null/undefined, or precision is not a number
|
|
490
|
+
* @throws {RangeError} If precision is negative
|
|
438
491
|
*/
|
|
439
492
|
export function circleToPath(cx, cy, r, precision = DEFAULT_PRECISION) {
|
|
493
|
+
if (cx == null) {
|
|
494
|
+
throw new TypeError("circleToPath: cx cannot be null or undefined");
|
|
495
|
+
}
|
|
496
|
+
if (cy == null) {
|
|
497
|
+
throw new TypeError("circleToPath: cy cannot be null or undefined");
|
|
498
|
+
}
|
|
499
|
+
if (r == null) {
|
|
500
|
+
throw new TypeError("circleToPath: r cannot be null or undefined");
|
|
501
|
+
}
|
|
502
|
+
if (typeof precision !== "number" || !Number.isFinite(precision)) {
|
|
503
|
+
throw new TypeError(`circleToPath: precision must be a finite number, got ${typeof precision}`);
|
|
504
|
+
}
|
|
505
|
+
if (precision < 0) {
|
|
506
|
+
throw new RangeError(`circleToPath: precision must be non-negative, got ${precision}`);
|
|
507
|
+
}
|
|
440
508
|
return GeometryToPath.circleToPathData(cx, cy, r, precision);
|
|
441
509
|
}
|
|
442
510
|
|
|
@@ -448,8 +516,28 @@ export function circleToPath(cx, cy, r, precision = DEFAULT_PRECISION) {
|
|
|
448
516
|
* @param {number|string|Decimal} ry - Y-axis radius
|
|
449
517
|
* @param {number} [precision=6] - Number of decimal places in output
|
|
450
518
|
* @returns {string} SVG path data string
|
|
519
|
+
* @throws {TypeError} If cx, cy, rx, or ry is null/undefined, or precision is not a number
|
|
520
|
+
* @throws {RangeError} If precision is negative
|
|
451
521
|
*/
|
|
452
522
|
export function ellipseToPath(cx, cy, rx, ry, precision = DEFAULT_PRECISION) {
|
|
523
|
+
if (cx == null) {
|
|
524
|
+
throw new TypeError("ellipseToPath: cx cannot be null or undefined");
|
|
525
|
+
}
|
|
526
|
+
if (cy == null) {
|
|
527
|
+
throw new TypeError("ellipseToPath: cy cannot be null or undefined");
|
|
528
|
+
}
|
|
529
|
+
if (rx == null) {
|
|
530
|
+
throw new TypeError("ellipseToPath: rx cannot be null or undefined");
|
|
531
|
+
}
|
|
532
|
+
if (ry == null) {
|
|
533
|
+
throw new TypeError("ellipseToPath: ry cannot be null or undefined");
|
|
534
|
+
}
|
|
535
|
+
if (typeof precision !== "number" || !Number.isFinite(precision)) {
|
|
536
|
+
throw new TypeError(`ellipseToPath: precision must be a finite number, got ${typeof precision}`);
|
|
537
|
+
}
|
|
538
|
+
if (precision < 0) {
|
|
539
|
+
throw new RangeError(`ellipseToPath: precision must be non-negative, got ${precision}`);
|
|
540
|
+
}
|
|
453
541
|
return GeometryToPath.ellipseToPathData(cx, cy, rx, ry, precision);
|
|
454
542
|
}
|
|
455
543
|
|
|
@@ -463,6 +551,8 @@ export function ellipseToPath(cx, cy, rx, ry, precision = DEFAULT_PRECISION) {
|
|
|
463
551
|
* @param {number|string|Decimal} [ry=rx] - Corner Y radius
|
|
464
552
|
* @param {number} [precision=6] - Number of decimal places in output
|
|
465
553
|
* @returns {string} SVG path data string
|
|
554
|
+
* @throws {TypeError} If x, y, width, or height is null/undefined, or precision is not a number
|
|
555
|
+
* @throws {RangeError} If precision is negative
|
|
466
556
|
*/
|
|
467
557
|
export function rectToPath(
|
|
468
558
|
x,
|
|
@@ -473,6 +563,24 @@ export function rectToPath(
|
|
|
473
563
|
ry = null,
|
|
474
564
|
precision = DEFAULT_PRECISION,
|
|
475
565
|
) {
|
|
566
|
+
if (x == null) {
|
|
567
|
+
throw new TypeError("rectToPath: x cannot be null or undefined");
|
|
568
|
+
}
|
|
569
|
+
if (y == null) {
|
|
570
|
+
throw new TypeError("rectToPath: y cannot be null or undefined");
|
|
571
|
+
}
|
|
572
|
+
if (width == null) {
|
|
573
|
+
throw new TypeError("rectToPath: width cannot be null or undefined");
|
|
574
|
+
}
|
|
575
|
+
if (height == null) {
|
|
576
|
+
throw new TypeError("rectToPath: height cannot be null or undefined");
|
|
577
|
+
}
|
|
578
|
+
if (typeof precision !== "number" || !Number.isFinite(precision)) {
|
|
579
|
+
throw new TypeError(`rectToPath: precision must be a finite number, got ${typeof precision}`);
|
|
580
|
+
}
|
|
581
|
+
if (precision < 0) {
|
|
582
|
+
throw new RangeError(`rectToPath: precision must be non-negative, got ${precision}`);
|
|
583
|
+
}
|
|
476
584
|
return GeometryToPath.rectToPathData(
|
|
477
585
|
x,
|
|
478
586
|
y,
|
|
@@ -493,8 +601,28 @@ export function rectToPath(
|
|
|
493
601
|
* @param {number|string|Decimal} y2 - End Y coordinate
|
|
494
602
|
* @param {number} [precision=6] - Number of decimal places in output
|
|
495
603
|
* @returns {string} SVG path data string
|
|
604
|
+
* @throws {TypeError} If x1, y1, x2, or y2 is null/undefined, or precision is not a number
|
|
605
|
+
* @throws {RangeError} If precision is negative
|
|
496
606
|
*/
|
|
497
607
|
export function lineToPath(x1, y1, x2, y2, precision = DEFAULT_PRECISION) {
|
|
608
|
+
if (x1 == null) {
|
|
609
|
+
throw new TypeError("lineToPath: x1 cannot be null or undefined");
|
|
610
|
+
}
|
|
611
|
+
if (y1 == null) {
|
|
612
|
+
throw new TypeError("lineToPath: y1 cannot be null or undefined");
|
|
613
|
+
}
|
|
614
|
+
if (x2 == null) {
|
|
615
|
+
throw new TypeError("lineToPath: x2 cannot be null or undefined");
|
|
616
|
+
}
|
|
617
|
+
if (y2 == null) {
|
|
618
|
+
throw new TypeError("lineToPath: y2 cannot be null or undefined");
|
|
619
|
+
}
|
|
620
|
+
if (typeof precision !== "number" || !Number.isFinite(precision)) {
|
|
621
|
+
throw new TypeError(`lineToPath: precision must be a finite number, got ${typeof precision}`);
|
|
622
|
+
}
|
|
623
|
+
if (precision < 0) {
|
|
624
|
+
throw new RangeError(`lineToPath: precision must be non-negative, got ${precision}`);
|
|
625
|
+
}
|
|
498
626
|
return GeometryToPath.lineToPathData(x1, y1, x2, y2, precision);
|
|
499
627
|
}
|
|
500
628
|
|
|
@@ -503,8 +631,19 @@ export function lineToPath(x1, y1, x2, y2, precision = DEFAULT_PRECISION) {
|
|
|
503
631
|
* @param {string|Array<[number, number]>} points - SVG points attribute or array of [x, y] pairs
|
|
504
632
|
* @param {number} [precision=6] - Number of decimal places in output
|
|
505
633
|
* @returns {string} SVG path data string (closed)
|
|
634
|
+
* @throws {TypeError} If points is null/undefined, or precision is not a number
|
|
635
|
+
* @throws {RangeError} If precision is negative
|
|
506
636
|
*/
|
|
507
637
|
export function polygonToPath(points, precision = DEFAULT_PRECISION) {
|
|
638
|
+
if (points == null) {
|
|
639
|
+
throw new TypeError("polygonToPath: points cannot be null or undefined");
|
|
640
|
+
}
|
|
641
|
+
if (typeof precision !== "number" || !Number.isFinite(precision)) {
|
|
642
|
+
throw new TypeError(`polygonToPath: precision must be a finite number, got ${typeof precision}`);
|
|
643
|
+
}
|
|
644
|
+
if (precision < 0) {
|
|
645
|
+
throw new RangeError(`polygonToPath: precision must be non-negative, got ${precision}`);
|
|
646
|
+
}
|
|
508
647
|
return GeometryToPath.polygonToPathData(points, precision);
|
|
509
648
|
}
|
|
510
649
|
|
|
@@ -513,8 +652,19 @@ export function polygonToPath(points, precision = DEFAULT_PRECISION) {
|
|
|
513
652
|
* @param {string|Array<[number, number]>} points - SVG points attribute or array of [x, y] pairs
|
|
514
653
|
* @param {number} [precision=6] - Number of decimal places in output
|
|
515
654
|
* @returns {string} SVG path data string (open)
|
|
655
|
+
* @throws {TypeError} If points is null/undefined, or precision is not a number
|
|
656
|
+
* @throws {RangeError} If precision is negative
|
|
516
657
|
*/
|
|
517
658
|
export function polylineToPath(points, precision = DEFAULT_PRECISION) {
|
|
659
|
+
if (points == null) {
|
|
660
|
+
throw new TypeError("polylineToPath: points cannot be null or undefined");
|
|
661
|
+
}
|
|
662
|
+
if (typeof precision !== "number" || !Number.isFinite(precision)) {
|
|
663
|
+
throw new TypeError(`polylineToPath: precision must be a finite number, got ${typeof precision}`);
|
|
664
|
+
}
|
|
665
|
+
if (precision < 0) {
|
|
666
|
+
throw new RangeError(`polylineToPath: precision must be non-negative, got ${precision}`);
|
|
667
|
+
}
|
|
518
668
|
return GeometryToPath.polylineToPathData(points, precision);
|
|
519
669
|
}
|
|
520
670
|
|
|
@@ -531,8 +681,12 @@ export function getKappa() {
|
|
|
531
681
|
* Parse SVG path data into an array of commands with Decimal arguments.
|
|
532
682
|
* @param {string} pathData - SVG path data string
|
|
533
683
|
* @returns {Array<{command: string, args: Decimal[]}>} Parsed commands
|
|
684
|
+
* @throws {TypeError} If pathData is null or undefined
|
|
534
685
|
*/
|
|
535
686
|
export function parsePath(pathData) {
|
|
687
|
+
if (pathData == null) {
|
|
688
|
+
throw new TypeError("parsePath: pathData cannot be null or undefined");
|
|
689
|
+
}
|
|
536
690
|
return GeometryToPath.parsePathData(pathData);
|
|
537
691
|
}
|
|
538
692
|
|
|
@@ -541,8 +695,19 @@ export function parsePath(pathData) {
|
|
|
541
695
|
* @param {Array<{command: string, args: Decimal[]}>} commands - Path commands
|
|
542
696
|
* @param {number} [precision=6] - Number of decimal places in output
|
|
543
697
|
* @returns {string} SVG path data string
|
|
698
|
+
* @throws {TypeError} If commands is null/undefined, or precision is not a number
|
|
699
|
+
* @throws {RangeError} If precision is negative
|
|
544
700
|
*/
|
|
545
701
|
export function pathToString(commands, precision = DEFAULT_PRECISION) {
|
|
702
|
+
if (commands == null) {
|
|
703
|
+
throw new TypeError("pathToString: commands cannot be null or undefined");
|
|
704
|
+
}
|
|
705
|
+
if (typeof precision !== "number" || !Number.isFinite(precision)) {
|
|
706
|
+
throw new TypeError(`pathToString: precision must be a finite number, got ${typeof precision}`);
|
|
707
|
+
}
|
|
708
|
+
if (precision < 0) {
|
|
709
|
+
throw new RangeError(`pathToString: precision must be non-negative, got ${precision}`);
|
|
710
|
+
}
|
|
546
711
|
return GeometryToPath.pathArrayToString(commands, precision);
|
|
547
712
|
}
|
|
548
713
|
|
|
@@ -550,8 +715,12 @@ export function pathToString(commands, precision = DEFAULT_PRECISION) {
|
|
|
550
715
|
* Convert relative path commands to absolute.
|
|
551
716
|
* @param {string} pathData - SVG path data (may contain relative commands)
|
|
552
717
|
* @returns {string} SVG path data with only absolute commands
|
|
718
|
+
* @throws {TypeError} If pathData is null or undefined
|
|
553
719
|
*/
|
|
554
720
|
export function pathToAbsolute(pathData) {
|
|
721
|
+
if (pathData == null) {
|
|
722
|
+
throw new TypeError("pathToAbsolute: pathData cannot be null or undefined");
|
|
723
|
+
}
|
|
555
724
|
return GeometryToPath.pathToAbsolute(pathData);
|
|
556
725
|
}
|
|
557
726
|
|
|
@@ -560,8 +729,12 @@ export function pathToAbsolute(pathData) {
|
|
|
560
729
|
* Lines become degenerate cubics, quadratics are elevated to cubics.
|
|
561
730
|
* @param {string} pathData - SVG path data
|
|
562
731
|
* @returns {string} SVG path data with only M, C, and Z commands
|
|
732
|
+
* @throws {TypeError} If pathData is null or undefined
|
|
563
733
|
*/
|
|
564
734
|
export function pathToCubics(pathData) {
|
|
735
|
+
if (pathData == null) {
|
|
736
|
+
throw new TypeError("pathToCubics: pathData cannot be null or undefined");
|
|
737
|
+
}
|
|
565
738
|
return GeometryToPath.pathToCubics(pathData);
|
|
566
739
|
}
|
|
567
740
|
|
|
@@ -571,8 +744,22 @@ export function pathToCubics(pathData) {
|
|
|
571
744
|
* @param {Matrix} matrix - 3x3 transformation matrix
|
|
572
745
|
* @param {number} [precision=6] - Number of decimal places in output
|
|
573
746
|
* @returns {string} Transformed SVG path data
|
|
747
|
+
* @throws {TypeError} If pathData or matrix is null/undefined, or precision is not a number
|
|
748
|
+
* @throws {RangeError} If precision is negative
|
|
574
749
|
*/
|
|
575
750
|
export function transformPath(pathData, matrix, precision = DEFAULT_PRECISION) {
|
|
751
|
+
if (pathData == null) {
|
|
752
|
+
throw new TypeError("transformPath: pathData cannot be null or undefined");
|
|
753
|
+
}
|
|
754
|
+
if (matrix == null) {
|
|
755
|
+
throw new TypeError("transformPath: matrix cannot be null or undefined");
|
|
756
|
+
}
|
|
757
|
+
if (typeof precision !== "number" || !Number.isFinite(precision)) {
|
|
758
|
+
throw new TypeError(`transformPath: precision must be a finite number, got ${typeof precision}`);
|
|
759
|
+
}
|
|
760
|
+
if (precision < 0) {
|
|
761
|
+
throw new RangeError(`transformPath: precision must be non-negative, got ${precision}`);
|
|
762
|
+
}
|
|
576
763
|
return GeometryToPath.transformPathData(pathData, matrix, precision);
|
|
577
764
|
}
|
|
578
765
|
|
|
@@ -582,8 +769,19 @@ export function transformPath(pathData, matrix, precision = DEFAULT_PRECISION) {
|
|
|
582
769
|
* @param {Object|Element} element - SVG element or object with tagName and attributes
|
|
583
770
|
* @param {number} [precision=6] - Number of decimal places in output
|
|
584
771
|
* @returns {string|null} SVG path data string, or null if element type not supported
|
|
772
|
+
* @throws {TypeError} If element is null/undefined, or precision is not a number
|
|
773
|
+
* @throws {RangeError} If precision is negative
|
|
585
774
|
*/
|
|
586
775
|
export function elementToPath(element, precision = DEFAULT_PRECISION) {
|
|
776
|
+
if (element == null) {
|
|
777
|
+
throw new TypeError("elementToPath: element cannot be null or undefined");
|
|
778
|
+
}
|
|
779
|
+
if (typeof precision !== "number" || !Number.isFinite(precision)) {
|
|
780
|
+
throw new TypeError(`elementToPath: precision must be a finite number, got ${typeof precision}`);
|
|
781
|
+
}
|
|
782
|
+
if (precision < 0) {
|
|
783
|
+
throw new RangeError(`elementToPath: precision must be non-negative, got ${precision}`);
|
|
784
|
+
}
|
|
587
785
|
return GeometryToPath.convertElementToPath(element, precision);
|
|
588
786
|
}
|
|
589
787
|
|
|
@@ -591,8 +789,18 @@ export function elementToPath(element, precision = DEFAULT_PRECISION) {
|
|
|
591
789
|
* Create an identity matrix of the given size.
|
|
592
790
|
* @param {number} n - Matrix dimension (creates n x n identity matrix)
|
|
593
791
|
* @returns {Matrix} Identity matrix
|
|
792
|
+
* @throws {TypeError} If n is not a number
|
|
793
|
+
* @throws {RangeError} If n is not a positive integer
|
|
594
794
|
*/
|
|
595
795
|
export function identity(n) {
|
|
796
|
+
// Validate n is a number
|
|
797
|
+
if (typeof n !== "number" || !Number.isFinite(n)) {
|
|
798
|
+
throw new TypeError(`identity: n must be a finite number, got ${typeof n}`);
|
|
799
|
+
}
|
|
800
|
+
// Validate n is a positive integer
|
|
801
|
+
if (!Number.isInteger(n) || n < 1) {
|
|
802
|
+
throw new RangeError(`identity: n must be a positive integer, got ${n}`);
|
|
803
|
+
}
|
|
596
804
|
return Matrix.identity(n);
|
|
597
805
|
}
|
|
598
806
|
|
|
@@ -601,8 +809,30 @@ export function identity(n) {
|
|
|
601
809
|
* @param {number} rows - Number of rows
|
|
602
810
|
* @param {number} cols - Number of columns
|
|
603
811
|
* @returns {Matrix} Zero matrix
|
|
812
|
+
* @throws {TypeError} If rows or cols is not a number
|
|
813
|
+
* @throws {RangeError} If rows or cols is not a positive integer
|
|
604
814
|
*/
|
|
605
815
|
export function zeros(rows, cols) {
|
|
816
|
+
// Validate rows is a number
|
|
817
|
+
if (typeof rows !== "number" || !Number.isFinite(rows)) {
|
|
818
|
+
throw new TypeError(
|
|
819
|
+
`zeros: rows must be a finite number, got ${typeof rows}`,
|
|
820
|
+
);
|
|
821
|
+
}
|
|
822
|
+
// Validate cols is a number
|
|
823
|
+
if (typeof cols !== "number" || !Number.isFinite(cols)) {
|
|
824
|
+
throw new TypeError(
|
|
825
|
+
`zeros: cols must be a finite number, got ${typeof cols}`,
|
|
826
|
+
);
|
|
827
|
+
}
|
|
828
|
+
// Validate rows is a positive integer
|
|
829
|
+
if (!Number.isInteger(rows) || rows < 1) {
|
|
830
|
+
throw new RangeError(`zeros: rows must be a positive integer, got ${rows}`);
|
|
831
|
+
}
|
|
832
|
+
// Validate cols is a positive integer
|
|
833
|
+
if (!Number.isInteger(cols) || cols < 1) {
|
|
834
|
+
throw new RangeError(`zeros: cols must be a positive integer, got ${cols}`);
|
|
835
|
+
}
|
|
606
836
|
return Matrix.zeros(rows, cols);
|
|
607
837
|
}
|
|
608
838
|
|
|
@@ -610,8 +840,12 @@ export function zeros(rows, cols) {
|
|
|
610
840
|
* Create a vector from an array of components.
|
|
611
841
|
* @param {Array<number|string|Decimal>} components - Vector components
|
|
612
842
|
* @returns {Vector} New vector instance
|
|
843
|
+
* @throws {TypeError} If components is null or undefined
|
|
613
844
|
*/
|
|
614
845
|
export function vec(components) {
|
|
846
|
+
if (components == null) {
|
|
847
|
+
throw new TypeError("vec: components cannot be null or undefined");
|
|
848
|
+
}
|
|
615
849
|
return Vector.from(components);
|
|
616
850
|
}
|
|
617
851
|
|
|
@@ -619,16 +853,40 @@ export function vec(components) {
|
|
|
619
853
|
* Create a matrix from a 2D array.
|
|
620
854
|
* @param {Array<Array<number|string|Decimal>>} data - 2D array of matrix elements
|
|
621
855
|
* @returns {Matrix} New matrix instance
|
|
856
|
+
* @throws {TypeError} If data is null or undefined
|
|
622
857
|
*/
|
|
623
858
|
export function mat(data) {
|
|
859
|
+
if (data == null) {
|
|
860
|
+
throw new TypeError("mat: data cannot be null or undefined");
|
|
861
|
+
}
|
|
624
862
|
return Matrix.from(data);
|
|
625
863
|
}
|
|
626
864
|
|
|
627
865
|
/**
|
|
628
866
|
* Set the global precision for all Decimal operations.
|
|
629
867
|
* @param {number} precision - Number of significant digits (1 to 1e9)
|
|
868
|
+
* @throws {TypeError} If precision is not a finite number or not an integer
|
|
869
|
+
* @throws {RangeError} If precision is not between 1 and 1e9
|
|
630
870
|
*/
|
|
631
871
|
export function setPrecision(precision) {
|
|
872
|
+
// Validate precision is a number
|
|
873
|
+
if (typeof precision !== "number" || !Number.isFinite(precision)) {
|
|
874
|
+
throw new TypeError(
|
|
875
|
+
`setPrecision: precision must be a finite number, got ${typeof precision}`,
|
|
876
|
+
);
|
|
877
|
+
}
|
|
878
|
+
// Validate precision is an integer
|
|
879
|
+
if (!Number.isInteger(precision)) {
|
|
880
|
+
throw new TypeError(
|
|
881
|
+
`setPrecision: precision must be an integer, got ${precision}`,
|
|
882
|
+
);
|
|
883
|
+
}
|
|
884
|
+
// Validate precision range (Decimal.js requirement: 1 to 1e9)
|
|
885
|
+
if (precision < 1 || precision > 1e9) {
|
|
886
|
+
throw new RangeError(
|
|
887
|
+
`setPrecision: precision must be between 1 and 1e9, got ${precision}`,
|
|
888
|
+
);
|
|
889
|
+
}
|
|
632
890
|
Decimal.set({ precision });
|
|
633
891
|
}
|
|
634
892
|
|