@emasoft/svg-matrix 1.0.5 → 1.0.7

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