svg-path-simplify 0.1.3 → 0.2.1

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.
Files changed (43) hide show
  1. package/README.md +10 -0
  2. package/dist/svg-path-simplify.esm.js +3905 -1533
  3. package/dist/svg-path-simplify.esm.min.js +13 -1
  4. package/dist/svg-path-simplify.js +3923 -1551
  5. package/dist/svg-path-simplify.min.js +13 -1
  6. package/dist/svg-path-simplify.min.js.gz +0 -0
  7. package/index.html +61 -31
  8. package/package.json +3 -5
  9. package/src/constants.js +3 -0
  10. package/src/index-node.js +0 -1
  11. package/src/index.js +26 -0
  12. package/src/pathData_simplify_cubic.js +74 -31
  13. package/src/pathData_simplify_cubicsToArcs.js +566 -0
  14. package/src/pathData_simplify_harmonize_cpts.js +170 -0
  15. package/src/pathData_simplify_revertToquadratics.js +21 -0
  16. package/src/pathSimplify-main.js +253 -86
  17. package/src/poly-fit-curve-schneider.js +570 -0
  18. package/src/simplify_poly_RDP.js +146 -0
  19. package/src/simplify_poly_radial_distance.js +100 -0
  20. package/src/svg_getViewbox.js +1 -1
  21. package/src/svgii/geometry.js +389 -63
  22. package/src/svgii/geometry_area.js +2 -1
  23. package/src/svgii/pathData_analyze.js +259 -212
  24. package/src/svgii/pathData_convert.js +91 -663
  25. package/src/svgii/pathData_fromPoly.js +12 -0
  26. package/src/svgii/pathData_parse.js +90 -89
  27. package/src/svgii/pathData_parse_els.js +3 -0
  28. package/src/svgii/pathData_parse_fontello.js +449 -0
  29. package/src/svgii/pathData_remove_collinear.js +44 -37
  30. package/src/svgii/pathData_reorder.js +2 -1
  31. package/src/svgii/pathData_simplify_redraw.js +343 -0
  32. package/src/svgii/pathData_simplify_refineCorners.js +18 -9
  33. package/src/svgii/pathData_simplify_refineExtremes.js +19 -78
  34. package/src/svgii/pathData_split.js +42 -45
  35. package/src/svgii/pathData_toPolygon.js +130 -4
  36. package/src/svgii/poly_analyze.js +470 -14
  37. package/src/svgii/poly_to_pathdata.js +224 -19
  38. package/src/svgii/rounding.js +55 -112
  39. package/src/svgii/svg_cleanup.js +13 -1
  40. package/src/svgii/visualize.js +8 -3
  41. package/{debug.cjs → tests/debug.cjs} +3 -0
  42. /package/{test.js → tests/test.js} +0 -0
  43. /package/{testSVG.js → tests/testSVG.js} +0 -0
@@ -1,9 +1,9 @@
1
1
  import { detectInputType } from './detect_input';
2
2
  import { simplifyPathDataCubic } from './pathData_simplify_cubic';
3
- import { getPathDataVertices, pointAtT } from './svgii/geometry';
3
+ import { getDistManhattan, getDistance, getPathDataVertices, pointAtT } from './svgii/geometry';
4
4
  import { getPolyBBox } from './svgii/geometry_bbox';
5
5
  import { analyzePathData } from './svgii/pathData_analyze';
6
- import { combineArcs, combineCubicsToArcs, convertPathData, cubicCommandToArc, revertCubicQuadratic } from './svgii/pathData_convert';
6
+ import { convertPathData } from './svgii/pathData_convert';
7
7
  import { parsePathDataNormalized } from './svgii/pathData_parse';
8
8
  import { shapeElToPath } from './svgii/pathData_parse_els';
9
9
  import { pathDataRemoveColinear } from './svgii/pathData_remove_collinear';
@@ -14,8 +14,8 @@ import { reversePathData } from './svgii/pathData_reverse';
14
14
  import { addExtremePoints, splitSubpaths } from './svgii/pathData_split';
15
15
  import { pathDataToD } from './svgii/pathData_stringify';
16
16
  //import { pathDataToPolyPlus, pathDataToPolySingle } from './svgii/pathData_toPolygon';
17
- import { analyzePoly } from './svgii/poly_analyze';
18
- import { getCurvePathData } from './svgii/poly_to_pathdata';
17
+ import { analyzePoly, getPolyChunks } from './svgii/poly_analyze';
18
+ import { simplifyPolyChunks, getCurvePathData, simplifyPolygonToPathData } from './svgii/poly_to_pathdata';
19
19
  import { detectAccuracy } from './svgii/rounding';
20
20
  import { refineAdjacentExtremes } from './svgii/pathData_simplify_refineExtremes';
21
21
  import { cleanUpSVG, removeEmptySVGEls, stringifySVG } from './svgii/svg_cleanup';
@@ -25,6 +25,15 @@ import { refineRoundSegments } from './svgii/pathData_refine_round';
25
25
  import { refineClosingCommand } from './svgii/pathData_remove_short';
26
26
  import { scalePathData } from './svgii/pathData_transform_scale';
27
27
  import { getViewBox } from './svg_getViewbox';
28
+ import { redrawPathData } from './svgii/pathData_simplify_redraw';
29
+ import { getPolygonArea } from './svgii/geometry_area';
30
+ import { pathDataRevertCubicToQuadratic } from './pathData_simplify_revertToquadratics';
31
+ import { pathDataCubicsToArc } from './pathData_simplify_cubicsToArcs';
32
+ import { simplifyRD } from './simplify_poly_radial_distance';
33
+ import { pathDataFromPoly } from './svgii/pathData_fromPoly';
34
+ import { simplifyRDP } from './simplify_poly_RDP';
35
+ import { harmonizeCubicCpts } from './pathData_simplify_harmonize_cpts';
36
+ import { pathDataToPolygon } from './svgii/pathData_toPolygon';
28
37
 
29
38
  //import { installDOMPolyfills } from './dom-polyfill';
30
39
 
@@ -63,13 +72,22 @@ export function svgPathSimplify(input = '', {
63
72
  extrapolateDominant = true,
64
73
  keepInflections = false,
65
74
  addExtremes = false,
75
+ addSemiExtremes = false,
76
+
77
+ smoothPoly = false,
78
+ harmonizeCpts = false,
79
+ toPolygon = false,
80
+
81
+
66
82
  removeOrphanSubpaths = false,
67
83
 
68
84
  simplifyRound = false,
69
85
 
70
86
  //svg scaling
71
- scale=1,
72
- scaleTo=0,
87
+ scale = 1,
88
+ scaleTo = 0,
89
+ crop = false,
90
+ alignToOrigin = false,
73
91
 
74
92
 
75
93
  // svg path optimizations
@@ -86,15 +104,21 @@ export function svgPathSimplify(input = '', {
86
104
  removeUnused = true,
87
105
  shapesToPaths = true,
88
106
 
107
+ tMin = 0,
108
+ tMax = 1,
109
+
110
+ // redraw - for messed up paths
111
+ redraw = false,
112
+
89
113
 
90
114
  } = {}) {
91
115
 
92
116
 
93
- // clamp tolerance
117
+ // clamp tolerance and scale
94
118
  tolerance = Math.max(0.1, tolerance);
119
+ scale = Math.max(0.001, scale)
95
120
 
96
121
  let inputType = detectInputType(input);
97
-
98
122
  let svg = '';
99
123
  let svgSize = 0;
100
124
  let svgSizeOpt = 0;
@@ -112,10 +136,21 @@ export function svgPathSimplify(input = '', {
112
136
  */
113
137
 
114
138
  // original size
115
- //svgSize = new Blob([input]).size;
116
139
  svgSize = input.length;
117
140
 
118
141
 
142
+
143
+ /**
144
+ * global bbox and viewBox for
145
+ * path scaling
146
+ * sorting and cropping
147
+ */
148
+ let viewBox = { x: 0, y: 0, width: 0, height: 0 }
149
+ let bb_global = { x: 0, y: 0, width: 0, height: 0 }
150
+ let xArr = []
151
+ let yArr = []
152
+
153
+
119
154
  // mode:0 – single path
120
155
  if (!mode) {
121
156
  if (inputType === 'pathDataString') {
@@ -127,7 +162,6 @@ export function svgPathSimplify(input = '', {
127
162
  d = input;
128
163
 
129
164
  // stringify to compare lengths
130
- //let dStr = pathDataToD(d);
131
165
  let dStr = d.map(com => { return `${com.type} ${com.values.join(' ')}` }).join(' ');
132
166
  svgSize = dStr.length;
133
167
 
@@ -152,9 +186,17 @@ export function svgPathSimplify(input = '', {
152
186
 
153
187
  // collect paths
154
188
  let pathEls = svg.querySelectorAll('path')
189
+
190
+
191
+ //if(mergePaths){}
192
+
155
193
  pathEls.forEach(path => {
156
194
  paths.push({ d: path.getAttribute('d'), el: path })
157
195
  })
196
+
197
+ // get viewBox/dimensions
198
+ viewBox = getViewBox(svg, decimals)
199
+
158
200
  }
159
201
 
160
202
 
@@ -174,31 +216,47 @@ export function svgPathSimplify(input = '', {
174
216
  // combinded path data for SVGs with mergePaths enabled
175
217
  let pathData_merged = [];
176
218
 
219
+
177
220
  for (let i = 0, l = paths.length; l && i < l; i++) {
178
221
 
179
222
  let path = paths[i];
180
223
  let { d, el } = path;
181
224
 
225
+
182
226
  let pathData = parsePathDataNormalized(d, { quadraticToCubic, toAbsolute, arcToCubic });
183
227
 
228
+ // get polygon bbox
229
+ let bb_poly = smoothPoly || toPolygon ? getPolyBBox(getPathDataVertices(pathData)) : null
230
+
231
+
184
232
  // scale pathdata and viewBox
185
- if(scale!==1 || scaleTo){
233
+ if (scale !== 1 || scaleTo) {
186
234
 
187
- // get bbox for scaling
188
- if(scaleTo){
235
+ // get bbox of viewBox for scaling
236
+ if (scaleTo) {
189
237
 
190
- let pathDataExtr = pathData.map(com=>{return {type:com.type, values:com.values}})
191
- pathDataExtr = addExtremePoints(pathDataExtr);
192
- let poly = getPathDataVertices(pathDataExtr)
193
- let bb = getPolyBBox(poly);
238
+ if (viewBox.width && !crop) {
239
+ scale = scaleTo / viewBox.width;
194
240
 
195
- let scaleW = scaleTo/bb.width
196
- scale = scaleW;
197
- //console.log('scaleW', scaleW);
198
- }
241
+ } else {
242
+
243
+ // convert arcs to cubics, add extreme to get precise bounding box
244
+ let pathDataExtr = pathData.map(com => { return { type: com.type, values: com.values } })
245
+ pathDataExtr = convertPathData(pathDataExtr, { arcToCubic: true })
246
+ pathDataExtr = addExtremePoints(pathDataExtr);
247
+
248
+ let poly = getPathDataVertices(pathDataExtr)
249
+ let bb = getPolyBBox(poly);
250
+ xArr.push(bb.x, bb.x + bb.width)
251
+ yArr.push(bb.y, bb.y + bb.height)
199
252
 
200
253
 
254
+ let scaleW = scaleTo / bb.width
255
+ scale = scaleW;
256
+ }
257
+ }
201
258
 
259
+ //console.log('scale', scale, scaleTo);
202
260
  pathData = scalePathData(pathData, scale)
203
261
  }
204
262
 
@@ -207,6 +265,7 @@ export function svgPathSimplify(input = '', {
207
265
 
208
266
  if (removeOrphanSubpaths) pathData = removeOrphanedM(pathData);
209
267
 
268
+
210
269
  /**
211
270
  * get sub paths
212
271
  */
@@ -228,15 +287,90 @@ export function svgPathSimplify(input = '', {
228
287
  let pathDataSub = subPathArr[i];
229
288
 
230
289
 
290
+
291
+ /**
292
+ * convert cureves to polygon
293
+ * flattening
294
+ */
295
+ if (toPolygon) {
296
+ simplifyBezier = false
297
+ smoothPoly = false
298
+ harmonizeCpts = false
299
+
300
+ //pathDataSub = pathDataToTopLeft(pathDataSub);
301
+ //pathDataSub = refineClosingCommand(pathDataSub)
302
+ pathDataSub = pathDataRemoveColinear(pathDataSub);
303
+
304
+ let pathDataSubPlus = analyzePathData(pathDataSub)
305
+ let { bb, pathData } = pathDataSubPlus;
306
+ pathDataSub = pathData;
307
+
308
+ pathDataSub = pathDataToPolygon(pathDataSub, {
309
+ angles: [],
310
+ split: 1,
311
+ width: bb_poly.width,
312
+ height: bb_poly.height,
313
+ getPathData: true
314
+ })
315
+
316
+ }
317
+
318
+
319
+ /**
320
+ * poly to beziers via
321
+ * Philip J. Schneider's
322
+ * "Algorithm for Automatically Fitting Digitized Curves"
323
+ */
324
+ if (smoothPoly) {
325
+ let coms = Array.from(new Set(pathDataSub.map(com => com.type))).join('')
326
+ let isPoly = !(/[acqts]/gi).test(coms)
327
+ let closed = (/[z]/gi).test(coms)
328
+ //flatBezierToLinetos=false
329
+
330
+ if (isPoly) {
331
+ pathDataSub = removeZeroLengthLinetos(pathDataSub)
332
+ let poly = getPathDataVertices(pathDataSub)
333
+
334
+ // options for poly simplification
335
+ let optionsPoly = {
336
+ denoise: 0.8,
337
+ tolerance,
338
+ width: bb_poly.width,
339
+ height: bb_poly.height,
340
+ manhattan: false,
341
+ absolute: false,
342
+ keepCorners,
343
+ keepExtremes,
344
+ keepInflections,
345
+ closed
346
+ }
347
+ pathDataSub = simplifyPolygonToPathData(poly, optionsPoly)
348
+ }
349
+ }
350
+
351
+ // harmonize cpts
352
+ if (harmonizeCpts) pathDataSub = harmonizeCubicCpts(pathDataSub)
353
+
354
+
231
355
  // remove zero length linetos
232
356
  if (removeColinear || removeZeroLength) pathDataSub = removeZeroLengthLinetos(pathDataSub)
233
- //console.log(removeColinear, removeZeroLength);
234
-
235
357
 
236
- // add extremes
237
- //let tMin=0.2, tMax=0.8;
238
- let tMin = 0, tMax = 1;
239
- if (addExtremes) pathDataSub = addExtremePoints(pathDataSub, tMin, tMax)
358
+ /**
359
+ * try to redraw messed up paths
360
+ * based on significant points suchas
361
+ * extremes, semi-extremes and corners
362
+ */
363
+ if (redraw) {
364
+ addExtremes = true
365
+ addSemiExtremes = true
366
+ simplifyCorners = false
367
+ keepCorners = true
368
+ keepExtremes = true
369
+ optimizeOrder = true
370
+ //simplifyBezier = false
371
+ tMin = 0
372
+ tMax = 0
373
+ }
240
374
 
241
375
 
242
376
  // sort to top left
@@ -246,15 +380,23 @@ export function svgPathSimplify(input = '', {
246
380
  // Preprocessing: remove colinear - ignore flat beziers (removed later)
247
381
  if (removeColinear) pathDataSub = pathDataRemoveColinear(pathDataSub, { tolerance, flatBezierToLinetos: false });
248
382
 
383
+ if (addExtremes || addSemiExtremes) pathDataSub = addExtremePoints(pathDataSub,
384
+ { tMin, tMax, addExtremes, addSemiExtremes, angles: [30] })
385
+
386
+
249
387
 
250
388
  // analyze pathdata to add info about signicant properties such as extremes, corners
251
- let pathDataPlus = analyzePathData(pathDataSub);
389
+ let pathDataPlus = analyzePathData(pathDataSub, {
390
+ detectSemiExtremes: addSemiExtremes,
391
+ });
252
392
 
253
- //console.log('pathDataPlus', pathDataPlus);
393
+ //console.log(pathDataPlus, pathDataPlus);
254
394
 
255
395
 
256
396
  // simplify beziers
257
397
  let { pathData, bb, dimA } = pathDataPlus;
398
+ xArr.push(bb.x, bb.x + bb.width)
399
+ yArr.push(bb.y, bb.y + bb.height)
258
400
 
259
401
 
260
402
  if (refineClosing) pathData = refineClosingCommand(pathData, { threshold: dimA * 0.001 })
@@ -262,40 +404,47 @@ export function svgPathSimplify(input = '', {
262
404
 
263
405
  pathData = simplifyBezier ? simplifyPathDataCubic(pathData, { simplifyBezier, keepInflections, keepExtremes, keepCorners, extrapolateDominant, revertToQuadratics, tolerance, reverse }) : pathData;
264
406
 
407
+
265
408
  // refine extremes
266
409
  if (refineExtremes) {
267
- let thresholdEx = (bb.width + bb.height) / 2 * 0.05
410
+ //let thresholdEx = (bb.width + bb.height) / 2 * 0.05
411
+ let thresholdEx = (bb.width + bb.height) * 0.05
268
412
  pathData = refineAdjacentExtremes(pathData, { threshold: thresholdEx, tolerance })
269
413
  }
270
414
 
271
415
 
272
- // cubic to arcs
273
- if (cubicToArc) {
416
+ /**
417
+ * try redrawing
418
+ */
274
419
 
275
- let thresh = 1;
420
+ if (redraw) {
276
421
 
277
- //pathData = combineCubicsToArcs(pathData)
422
+ //pathData = pathDataRemoveColinear(pathData, { tolerance, flatBezierToLinetos: false });
423
+ /*
424
+ pathData = addExtremePoints(pathData,
425
+ { tMin: 0, tMax: 1, addExtremes: true, addSemiExtremes: true })
426
+
427
+ pathData = analyzePathData(pathDataSub, {
428
+ detectSemiExtremes: true,
429
+ detectExtremes: true,
430
+ }).pathData;
431
+
432
+ */
278
433
 
279
434
 
280
- for (let c = 0, l = pathData.length; c < l; c++) {
281
- let com = pathData[c]
282
- let { type, values, p0, cp1 = null, cp2 = null, p = null } = com;
283
- if (type === 'C') {
284
- //console.log(com);
285
- let comA = cubicCommandToArc(p0, cp1, cp2, p, thresh)
286
- if (comA.isArc) pathData[c] = comA.com;
287
- }
288
- }
289
-
290
- // combine adjacent cubics
291
- pathData = combineArcs(pathData)
435
+ let thresholdEx = (bb.width + bb.height) * 0.1
436
+ //pathData = refineAdjacentExtremes(pathData, { threshold: thresholdEx, tolerance })
437
+ pathData = redrawPathData(pathData, { tolerance, threshold: dimA * 0.001 })
292
438
 
293
- /*
294
- */
439
+ //simplifyPathDataCubic(pathData, { simplifyBezier, keepInflections, keepExtremes, keepCorners, extrapolateDominant, revertToQuadratics, tolerance, reverse })
295
440
 
296
441
  }
297
442
 
298
443
 
444
+ // cubic to arcs
445
+ if (cubicToArc) pathData = pathDataCubicsToArc(pathData, { areaThreshold: 2.5 })
446
+
447
+
299
448
  // post processing: remove flat beziers
300
449
  if (removeColinear && flatBezierToLinetos) {
301
450
  pathData = pathDataRemoveColinear(pathData, { tolerance, flatBezierToLinetos });
@@ -306,7 +455,7 @@ export function svgPathSimplify(input = '', {
306
455
  if (simplifyCorners) {
307
456
  //pathData = removeZeroLengthLinetos(pathData);
308
457
 
309
- let threshold = (bb.width + bb.height) / 2 * 0.1
458
+ let threshold = (bb.width + bb.height) * 0.1
310
459
  pathData = refineRoundedCorners(pathData, { threshold, tolerance })
311
460
  }
312
461
 
@@ -315,24 +464,7 @@ export function svgPathSimplify(input = '', {
315
464
 
316
465
 
317
466
  // simplify to quadratics
318
- if (revertToQuadratics) {
319
- for (let c = 0, l = pathData.length; c < l; c++) {
320
- let com = pathData[c]
321
- let { type, values, p0, cp1 = null, cp2 = null, p = null } = com;
322
- if (type === 'C') {
323
- //console.log(com);
324
- let comQ = revertCubicQuadratic(p0, cp1, cp2, p)
325
- if (comQ.type === 'Q') {
326
- comQ.extreme = com.extreme
327
- comQ.corner = com.corner
328
- comQ.dimA = com.dimA
329
-
330
- pathData[c] = comQ
331
- }
332
- }
333
- }
334
- }
335
-
467
+ if (revertToQuadratics) pathData = pathDataRevertCubicToQuadratic(pathData);
336
468
 
337
469
  // optimize close path
338
470
  if (optimizeOrder) pathData = optimizeClosePath(pathData, { autoClose })
@@ -342,10 +474,25 @@ export function svgPathSimplify(input = '', {
342
474
  //subPathArr[i]=pathData
343
475
  pathDataPlusArr.push({ pathData, bb })
344
476
 
345
- }
477
+ } // end sup paths
478
+
479
+ // sort subpaths to top left
480
+ let xMin = Math.min(...xArr)
481
+ let yMin = Math.min(...yArr)
482
+ let xMax = Math.max(...xArr)
483
+ let yMax = Math.max(...yArr)
484
+
485
+ bb_global = { x: xMin, y: yMin, width: xMax - xMin, height: yMax - yMin }
486
+ let isPortrait = bb_global.height > bb_global.width;
487
+
488
+ //console.log(xMin, xMax, 'y:', yMin, yMax, 'bb_global', bb_global);
489
+ //console.log(i, pathDataPlusArr);
346
490
 
347
- // sort to top left
348
- if (optimizeOrder) pathDataPlusArr = pathDataPlusArr.sort((a, b) => a.bb.y - b.bb.y || a.bb.x - b.bb.x)
491
+
492
+ // prefer top to bottom priority for portrait aspect ratios
493
+ if (optimizeOrder) {
494
+ pathDataPlusArr = isPortrait ? pathDataPlusArr.sort((a, b) => a.bb.y - b.bb.y || a.bb.x - b.bb.x) : pathDataPlusArr.sort((a, b) => a.bb.x - b.bb.x || a.bb.y - b.bb.y)
495
+ }
349
496
 
350
497
  // flatten compound paths
351
498
  pathData = [];
@@ -355,8 +502,6 @@ export function svgPathSimplify(input = '', {
355
502
 
356
503
  //pathData = pathDataFlat;
357
504
  //pathData = subPathArr.flat();
358
-
359
-
360
505
  //console.log('pathData', pathData);
361
506
 
362
507
  if (autoAccuracy) {
@@ -379,6 +524,19 @@ export function svgPathSimplify(input = '', {
379
524
  // remove zero-length segments introduced by rounding
380
525
  pathData = removeZeroLengthLinetos(pathData);
381
526
 
527
+
528
+ // realign path to zero origin
529
+ if (alignToOrigin) {
530
+ console.log(bb_global);
531
+
532
+ pathData[0].values[0] = (pathData[0].values[0] - bb_global.x).toFixed(decimals)
533
+ pathData[0].values[1] = (pathData[0].values[1] - bb_global.y).toFixed(decimals)
534
+
535
+ bb_global.x = 0
536
+ bb_global.y = 0
537
+ }
538
+
539
+
382
540
  // compare command count
383
541
  let comCountS = pathData.length
384
542
 
@@ -401,7 +559,8 @@ export function svgPathSimplify(input = '', {
401
559
  // apply new path for svgs
402
560
  if (el) el.setAttribute('d', dOpt)
403
561
  }
404
- };
562
+
563
+ } // end path array
405
564
 
406
565
  /**
407
566
  * stringify new SVG
@@ -433,23 +592,30 @@ export function svgPathSimplify(input = '', {
433
592
  }
434
593
 
435
594
  // adjust viewBox and width for scale
436
- if(scale){
595
+ if (scale) {
596
+
597
+ let { x, y, width, height, w, h, hasViewBox, hasWidth, hasHeight, widthUnit, heightUnit } = viewBox;
598
+ //console.log('bb_global', bb_global);
599
+
600
+ if (crop) {
601
+ x = bb_global.x
602
+ y = bb_global.y
603
+ width = bb_global.width
604
+ height = bb_global.height
605
+ w = width;
606
+ h = height;
607
+ }
437
608
 
438
- let vB = getViewBox(svg, decimals)
439
- let {x,y, width, height, w, h, hasViewBox, hasWidth, hasHeight, widthUnit, heightUnit} = vB;
440
-
441
- if(hasViewBox){
442
- svg.setAttribute('viewBox', [x, y, width, height].map(val=>+(val*scale).toFixed(decimals)).join(' ') )
609
+ if (hasViewBox) {
610
+ svg.setAttribute('viewBox', [x, y, width, height].map(val => +(val * scale).toFixed(decimals)).join(' '))
443
611
  }
444
- if(hasWidth){
445
- svg.setAttribute('width', +(w*scale).toFixed(decimals)+widthUnit )
612
+ if (hasWidth) {
613
+ svg.setAttribute('width', +(w * scale).toFixed(decimals) + widthUnit)
446
614
  }
447
615
 
448
- if(hasHeight){
449
- svg.setAttribute('height', +(h*scale).toFixed(decimals)+heightUnit )
616
+ if (hasHeight) {
617
+ svg.setAttribute('height', +(h * scale).toFixed(decimals) + heightUnit)
450
618
  }
451
- //console.log(vB);
452
-
453
619
  }
454
620
 
455
621
 
@@ -465,7 +631,8 @@ export function svgPathSimplify(input = '', {
465
631
  report = {
466
632
  svgSize,
467
633
  svgSizeOpt,
468
- compression
634
+ compression,
635
+ decimals
469
636
  }
470
637
 
471
638
  } else {