@emasoft/svg-matrix 1.0.4 → 1.0.6

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/src/index.js CHANGED
@@ -1,15 +1,18 @@
1
1
  /**
2
2
  * @emasoft/svg-matrix - Arbitrary-precision matrix, vector and affine transformation library.
3
3
  *
4
- * This library provides Decimal-backed Matrix and Vector classes along with
5
- * 2D (3x3) and 3D (4x4) transform helpers for geometry operations requiring high precision.
4
+ * A comprehensive toolkit for high-precision geometry and vector manipulation,
5
+ * SVG path conversion, and 2D/3D affine transformations using Decimal.js.
6
6
  *
7
7
  * @module @emasoft/svg-matrix
8
+ * @version 1.0.6
9
+ * @license MIT
8
10
  *
9
11
  * @example
10
- * import { Decimal, Matrix, Vector, Transforms2D, Transforms3D } from '@emasoft/svg-matrix';
12
+ * // ES Module import
13
+ * import { Decimal, Matrix, Vector, Transforms2D, GeometryToPath } from '@emasoft/svg-matrix';
11
14
  *
12
- * // Set precision for all operations
15
+ * // Set global precision (default is 20, max is 1e9)
13
16
  * Decimal.set({ precision: 80 });
14
17
  *
15
18
  * // Create and compose 2D transforms
@@ -19,7 +22,9 @@
19
22
  *
20
23
  * // Apply to a point
21
24
  * const [x, y] = Transforms2D.applyTransform(M, 1, 0);
22
- * console.log('Transformed:', x.toString(), y.toString());
25
+ *
26
+ * // Convert SVG shapes to paths with arbitrary precision
27
+ * const path = GeometryToPath.circleToPathData(100, 100, 50, 15);
23
28
  */
24
29
 
25
30
  import Decimal from 'decimal.js';
@@ -27,6 +32,408 @@ import { Matrix } from './matrix.js';
27
32
  import { Vector } from './vector.js';
28
33
  import * as Transforms2D from './transforms2d.js';
29
34
  import * as Transforms3D from './transforms3d.js';
35
+ import * as GeometryToPath from './geometry-to-path.js';
36
+ import * as PolygonClip from './polygon-clip.js';
30
37
  import * as SVGFlatten from './svg-flatten.js';
38
+ import * as BrowserVerify from './browser-verify.js';
39
+ import * as ClipPathResolver from './clip-path-resolver.js';
40
+ import * as MaskResolver from './mask-resolver.js';
41
+ import * as PatternResolver from './pattern-resolver.js';
42
+ import * as UseSymbolResolver from './use-symbol-resolver.js';
43
+ import * as MarkerResolver from './marker-resolver.js';
44
+ import * as MeshGradient from './mesh-gradient.js';
45
+ import * as TextToPath from './text-to-path.js';
46
+
47
+ /**
48
+ * Library version
49
+ * @constant {string}
50
+ */
51
+ export const VERSION = '1.0.5';
52
+
53
+ /**
54
+ * Default precision for path output (decimal places)
55
+ * @constant {number}
56
+ */
57
+ export const DEFAULT_PRECISION = 6;
58
+
59
+ // ============================================================================
60
+ // CORE: Arbitrary-Precision Primitives
61
+ // ============================================================================
62
+
63
+ export { Decimal, Matrix, Vector };
64
+
65
+ // ============================================================================
66
+ // TRANSFORMS: 2D and 3D Affine Transformations
67
+ // ============================================================================
68
+
69
+ export { Transforms2D, Transforms3D };
70
+
71
+ // ============================================================================
72
+ // GEOMETRY: Shape Conversion and Path Manipulation
73
+ // ============================================================================
74
+
75
+ export { GeometryToPath, PolygonClip };
76
+
77
+ // ============================================================================
78
+ // SVG: Document Processing and Element Resolution
79
+ // ============================================================================
80
+
81
+ export { SVGFlatten, BrowserVerify };
82
+ export { ClipPathResolver, MaskResolver, PatternResolver };
83
+ export { UseSymbolResolver, MarkerResolver };
84
+ export { MeshGradient, TextToPath };
85
+
86
+ // ============================================================================
87
+ // CONVENIENCE FUNCTIONS: Quick access to common operations
88
+ // ============================================================================
89
+
90
+ /**
91
+ * Create a 2D translation matrix.
92
+ * Convenience wrapper for Transforms2D.translation().
93
+ * @param {number|string|Decimal} tx - X translation
94
+ * @param {number|string|Decimal} ty - Y translation
95
+ * @returns {Matrix} 3x3 translation matrix
96
+ */
97
+ export function translate2D(tx, ty) {
98
+ return Transforms2D.translation(tx, ty);
99
+ }
100
+
101
+ /**
102
+ * Create a 2D rotation matrix.
103
+ * Convenience wrapper for Transforms2D.rotate().
104
+ * @param {number|string|Decimal} angle - Rotation angle in radians
105
+ * @returns {Matrix} 3x3 rotation matrix
106
+ */
107
+ export function rotate2D(angle) {
108
+ return Transforms2D.rotate(angle);
109
+ }
110
+
111
+ /**
112
+ * Create a 2D scale matrix.
113
+ * Convenience wrapper for Transforms2D.scale().
114
+ * @param {number|string|Decimal} sx - X scale factor
115
+ * @param {number|string|Decimal} [sy=sx] - Y scale factor (defaults to sx for uniform scaling)
116
+ * @returns {Matrix} 3x3 scale matrix
117
+ */
118
+ export function scale2D(sx, sy = null) {
119
+ return Transforms2D.scale(sx, sy);
120
+ }
121
+
122
+ /**
123
+ * Apply a 2D transformation matrix to a point.
124
+ * Convenience wrapper for Transforms2D.applyTransform().
125
+ * @param {Matrix} matrix - 3x3 transformation matrix
126
+ * @param {number|string|Decimal} x - X coordinate
127
+ * @param {number|string|Decimal} y - Y coordinate
128
+ * @returns {[Decimal, Decimal]} Transformed [x, y] coordinates
129
+ */
130
+ export function transform2D(matrix, x, y) {
131
+ return Transforms2D.applyTransform(matrix, x, y);
132
+ }
133
+
134
+ /**
135
+ * Create a 3D translation matrix.
136
+ * Convenience wrapper for Transforms3D.translation().
137
+ * @param {number|string|Decimal} tx - X translation
138
+ * @param {number|string|Decimal} ty - Y translation
139
+ * @param {number|string|Decimal} tz - Z translation
140
+ * @returns {Matrix} 4x4 translation matrix
141
+ */
142
+ export function translate3D(tx, ty, tz) {
143
+ return Transforms3D.translation(tx, ty, tz);
144
+ }
145
+
146
+ /**
147
+ * Create a 3D scale matrix.
148
+ * Convenience wrapper for Transforms3D.scale().
149
+ * @param {number|string|Decimal} sx - X scale factor
150
+ * @param {number|string|Decimal} [sy=sx] - Y scale factor
151
+ * @param {number|string|Decimal} [sz=sx] - Z scale factor
152
+ * @returns {Matrix} 4x4 scale matrix
153
+ */
154
+ export function scale3D(sx, sy = null, sz = null) {
155
+ return Transforms3D.scale(sx, sy, sz);
156
+ }
157
+
158
+ /**
159
+ * Apply a 3D transformation matrix to a point.
160
+ * Convenience wrapper for Transforms3D.applyTransform().
161
+ * @param {Matrix} matrix - 4x4 transformation matrix
162
+ * @param {number|string|Decimal} x - X coordinate
163
+ * @param {number|string|Decimal} y - Y coordinate
164
+ * @param {number|string|Decimal} z - Z coordinate
165
+ * @returns {[Decimal, Decimal, Decimal]} Transformed [x, y, z] coordinates
166
+ */
167
+ export function transform3D(matrix, x, y, z) {
168
+ return Transforms3D.applyTransform(matrix, x, y, z);
169
+ }
170
+
171
+ /**
172
+ * Convert a circle to SVG path data with arbitrary precision.
173
+ * Uses the exact kappa constant: 4 * (sqrt(2) - 1) / 3.
174
+ * @param {number|string|Decimal} cx - Center X coordinate
175
+ * @param {number|string|Decimal} cy - Center Y coordinate
176
+ * @param {number|string|Decimal} r - Radius
177
+ * @param {number} [precision=6] - Number of decimal places in output
178
+ * @returns {string} SVG path data string
179
+ */
180
+ export function circleToPath(cx, cy, r, precision = DEFAULT_PRECISION) {
181
+ return GeometryToPath.circleToPathData(cx, cy, r, precision);
182
+ }
183
+
184
+ /**
185
+ * Convert an ellipse to SVG path data with arbitrary precision.
186
+ * @param {number|string|Decimal} cx - Center X coordinate
187
+ * @param {number|string|Decimal} cy - Center Y coordinate
188
+ * @param {number|string|Decimal} rx - X-axis radius
189
+ * @param {number|string|Decimal} ry - Y-axis radius
190
+ * @param {number} [precision=6] - Number of decimal places in output
191
+ * @returns {string} SVG path data string
192
+ */
193
+ export function ellipseToPath(cx, cy, rx, ry, precision = DEFAULT_PRECISION) {
194
+ return GeometryToPath.ellipseToPathData(cx, cy, rx, ry, precision);
195
+ }
196
+
197
+ /**
198
+ * Convert a rectangle to SVG path data with arbitrary precision.
199
+ * @param {number|string|Decimal} x - Top-left X coordinate
200
+ * @param {number|string|Decimal} y - Top-left Y coordinate
201
+ * @param {number|string|Decimal} width - Rectangle width
202
+ * @param {number|string|Decimal} height - Rectangle height
203
+ * @param {number|string|Decimal} [rx=0] - Corner X radius
204
+ * @param {number|string|Decimal} [ry=rx] - Corner Y radius
205
+ * @param {number} [precision=6] - Number of decimal places in output
206
+ * @returns {string} SVG path data string
207
+ */
208
+ export function rectToPath(x, y, width, height, rx = 0, ry = null, precision = DEFAULT_PRECISION) {
209
+ return GeometryToPath.rectToPathData(x, y, width, height, rx, ry, false, precision);
210
+ }
211
+
212
+ /**
213
+ * Convert a line to SVG path data with arbitrary precision.
214
+ * @param {number|string|Decimal} x1 - Start X coordinate
215
+ * @param {number|string|Decimal} y1 - Start Y coordinate
216
+ * @param {number|string|Decimal} x2 - End X coordinate
217
+ * @param {number|string|Decimal} y2 - End Y coordinate
218
+ * @param {number} [precision=6] - Number of decimal places in output
219
+ * @returns {string} SVG path data string
220
+ */
221
+ export function lineToPath(x1, y1, x2, y2, precision = DEFAULT_PRECISION) {
222
+ return GeometryToPath.lineToPathData(x1, y1, x2, y2, precision);
223
+ }
224
+
225
+ /**
226
+ * Convert a polygon to SVG path data with arbitrary precision.
227
+ * @param {string|Array<[number, number]>} points - SVG points attribute or array of [x, y] pairs
228
+ * @param {number} [precision=6] - Number of decimal places in output
229
+ * @returns {string} SVG path data string (closed)
230
+ */
231
+ export function polygonToPath(points, precision = DEFAULT_PRECISION) {
232
+ return GeometryToPath.polygonToPathData(points, precision);
233
+ }
234
+
235
+ /**
236
+ * Convert a polyline to SVG path data with arbitrary precision.
237
+ * @param {string|Array<[number, number]>} points - SVG points attribute or array of [x, y] pairs
238
+ * @param {number} [precision=6] - Number of decimal places in output
239
+ * @returns {string} SVG path data string (open)
240
+ */
241
+ export function polylineToPath(points, precision = DEFAULT_PRECISION) {
242
+ return GeometryToPath.polylineToPathData(points, precision);
243
+ }
244
+
245
+ /**
246
+ * Get the exact kappa constant for Bezier circle approximation.
247
+ * kappa = 4 * (sqrt(2) - 1) / 3 ≈ 0.5522847498307936
248
+ * @returns {Decimal} The kappa constant with full precision
249
+ */
250
+ export function getKappa() {
251
+ return GeometryToPath.getKappa();
252
+ }
253
+
254
+ /**
255
+ * Parse SVG path data into an array of commands with Decimal arguments.
256
+ * @param {string} pathData - SVG path data string
257
+ * @returns {Array<{command: string, args: Decimal[]}>} Parsed commands
258
+ */
259
+ export function parsePath(pathData) {
260
+ return GeometryToPath.parsePathData(pathData);
261
+ }
262
+
263
+ /**
264
+ * Convert path commands array back to SVG path data string.
265
+ * @param {Array<{command: string, args: Decimal[]}>} commands - Path commands
266
+ * @param {number} [precision=6] - Number of decimal places in output
267
+ * @returns {string} SVG path data string
268
+ */
269
+ export function pathToString(commands, precision = DEFAULT_PRECISION) {
270
+ return GeometryToPath.pathArrayToString(commands, precision);
271
+ }
272
+
273
+ /**
274
+ * Convert relative path commands to absolute.
275
+ * @param {string} pathData - SVG path data (may contain relative commands)
276
+ * @returns {string} SVG path data with only absolute commands
277
+ */
278
+ export function pathToAbsolute(pathData) {
279
+ return GeometryToPath.pathToAbsolute(pathData);
280
+ }
281
+
282
+ /**
283
+ * Convert all path commands to cubic Bezier curves.
284
+ * Lines become degenerate cubics, quadratics are elevated to cubics.
285
+ * @param {string} pathData - SVG path data
286
+ * @returns {string} SVG path data with only M, C, and Z commands
287
+ */
288
+ export function pathToCubics(pathData) {
289
+ return GeometryToPath.pathToCubics(pathData);
290
+ }
291
+
292
+ /**
293
+ * Transform path data by applying an affine matrix.
294
+ * @param {string} pathData - SVG path data
295
+ * @param {Matrix} matrix - 3x3 transformation matrix
296
+ * @param {number} [precision=6] - Number of decimal places in output
297
+ * @returns {string} Transformed SVG path data
298
+ */
299
+ export function transformPath(pathData, matrix, precision = DEFAULT_PRECISION) {
300
+ return GeometryToPath.transformPathData(pathData, matrix, precision);
301
+ }
302
+
303
+ /**
304
+ * Convert any SVG geometry element to path data.
305
+ * Supports: circle, ellipse, rect, line, polyline, polygon.
306
+ * @param {Object|Element} element - SVG element or object with tagName and attributes
307
+ * @param {number} [precision=6] - Number of decimal places in output
308
+ * @returns {string|null} SVG path data string, or null if element type not supported
309
+ */
310
+ export function elementToPath(element, precision = DEFAULT_PRECISION) {
311
+ return GeometryToPath.convertElementToPath(element, precision);
312
+ }
313
+
314
+ /**
315
+ * Create an identity matrix of the given size.
316
+ * @param {number} n - Matrix dimension (creates n x n identity matrix)
317
+ * @returns {Matrix} Identity matrix
318
+ */
319
+ export function identity(n) {
320
+ return Matrix.identity(n);
321
+ }
322
+
323
+ /**
324
+ * Create a zero matrix of the given size.
325
+ * @param {number} rows - Number of rows
326
+ * @param {number} cols - Number of columns
327
+ * @returns {Matrix} Zero matrix
328
+ */
329
+ export function zeros(rows, cols) {
330
+ return Matrix.zeros(rows, cols);
331
+ }
332
+
333
+ /**
334
+ * Create a vector from an array of components.
335
+ * @param {Array<number|string|Decimal>} components - Vector components
336
+ * @returns {Vector} New vector instance
337
+ */
338
+ export function vec(components) {
339
+ return Vector.from(components);
340
+ }
341
+
342
+ /**
343
+ * Create a matrix from a 2D array.
344
+ * @param {Array<Array<number|string|Decimal>>} data - 2D array of matrix elements
345
+ * @returns {Matrix} New matrix instance
346
+ */
347
+ export function mat(data) {
348
+ return Matrix.from(data);
349
+ }
350
+
351
+ /**
352
+ * Set the global precision for all Decimal operations.
353
+ * @param {number} precision - Number of significant digits (1 to 1e9)
354
+ */
355
+ export function setPrecision(precision) {
356
+ Decimal.set({ precision });
357
+ }
358
+
359
+ /**
360
+ * Get the current global precision setting.
361
+ * @returns {number} Current precision value
362
+ */
363
+ export function getPrecision() {
364
+ return Decimal.precision;
365
+ }
366
+
367
+ // ============================================================================
368
+ // DEFAULT EXPORT: Unified namespace for browser/CDN usage
369
+ // ============================================================================
370
+
371
+ /**
372
+ * Default export provides the complete library as a single namespace.
373
+ * Ideal for browser usage via CDN or UMD bundles.
374
+ *
375
+ * @example
376
+ * // Browser usage with CDN
377
+ * <script src="https://cdn.jsdelivr.net/npm/@emasoft/svg-matrix/dist/svg-matrix.umd.js"></script>
378
+ * <script>
379
+ * const { Matrix, Vector, Transforms2D, circleToPath } = SVGMatrix;
380
+ * const path = SVGMatrix.circleToPath(100, 100, 50, 10);
381
+ * </script>
382
+ */
383
+ export default {
384
+ // Version
385
+ VERSION,
386
+ DEFAULT_PRECISION,
387
+
388
+ // Core primitives
389
+ Decimal,
390
+ Matrix,
391
+ Vector,
392
+
393
+ // Transform modules
394
+ Transforms2D,
395
+ Transforms3D,
396
+
397
+ // Geometry modules
398
+ GeometryToPath,
399
+ PolygonClip,
400
+
401
+ // SVG processing modules
402
+ SVGFlatten,
403
+ BrowserVerify,
404
+ ClipPathResolver,
405
+ MaskResolver,
406
+ PatternResolver,
407
+ UseSymbolResolver,
408
+ MarkerResolver,
409
+ MeshGradient,
410
+ TextToPath,
31
411
 
32
- export { Decimal, Matrix, Vector, Transforms2D, Transforms3D, SVGFlatten };
412
+ // Convenience functions
413
+ translate2D,
414
+ rotate2D,
415
+ scale2D,
416
+ transform2D,
417
+ translate3D,
418
+ scale3D,
419
+ transform3D,
420
+ circleToPath,
421
+ ellipseToPath,
422
+ rectToPath,
423
+ lineToPath,
424
+ polygonToPath,
425
+ polylineToPath,
426
+ getKappa,
427
+ parsePath,
428
+ pathToString,
429
+ pathToAbsolute,
430
+ pathToCubics,
431
+ transformPath,
432
+ elementToPath,
433
+ identity,
434
+ zeros,
435
+ vec,
436
+ mat,
437
+ setPrecision,
438
+ getPrecision,
439
+ };