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.
- package/README.md +10 -0
- package/dist/svg-path-simplify.esm.js +3905 -1533
- package/dist/svg-path-simplify.esm.min.js +13 -1
- package/dist/svg-path-simplify.js +3923 -1551
- package/dist/svg-path-simplify.min.js +13 -1
- package/dist/svg-path-simplify.min.js.gz +0 -0
- package/index.html +61 -31
- package/package.json +3 -5
- package/src/constants.js +3 -0
- package/src/index-node.js +0 -1
- package/src/index.js +26 -0
- package/src/pathData_simplify_cubic.js +74 -31
- package/src/pathData_simplify_cubicsToArcs.js +566 -0
- package/src/pathData_simplify_harmonize_cpts.js +170 -0
- package/src/pathData_simplify_revertToquadratics.js +21 -0
- package/src/pathSimplify-main.js +253 -86
- package/src/poly-fit-curve-schneider.js +570 -0
- package/src/simplify_poly_RDP.js +146 -0
- package/src/simplify_poly_radial_distance.js +100 -0
- package/src/svg_getViewbox.js +1 -1
- package/src/svgii/geometry.js +389 -63
- package/src/svgii/geometry_area.js +2 -1
- package/src/svgii/pathData_analyze.js +259 -212
- package/src/svgii/pathData_convert.js +91 -663
- package/src/svgii/pathData_fromPoly.js +12 -0
- package/src/svgii/pathData_parse.js +90 -89
- package/src/svgii/pathData_parse_els.js +3 -0
- package/src/svgii/pathData_parse_fontello.js +449 -0
- package/src/svgii/pathData_remove_collinear.js +44 -37
- package/src/svgii/pathData_reorder.js +2 -1
- package/src/svgii/pathData_simplify_redraw.js +343 -0
- package/src/svgii/pathData_simplify_refineCorners.js +18 -9
- package/src/svgii/pathData_simplify_refineExtremes.js +19 -78
- package/src/svgii/pathData_split.js +42 -45
- package/src/svgii/pathData_toPolygon.js +130 -4
- package/src/svgii/poly_analyze.js +470 -14
- package/src/svgii/poly_to_pathdata.js +224 -19
- package/src/svgii/rounding.js +55 -112
- package/src/svgii/svg_cleanup.js +13 -1
- package/src/svgii/visualize.js +8 -3
- package/{debug.cjs → tests/debug.cjs} +3 -0
- /package/{test.js → tests/test.js} +0 -0
- /package/{testSVG.js → tests/testSVG.js} +0 -0
package/src/pathSimplify-main.js
CHANGED
|
@@ -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 {
|
|
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
|
-
|
|
191
|
-
|
|
192
|
-
let poly = getPathDataVertices(pathDataExtr)
|
|
193
|
-
let bb = getPolyBBox(poly);
|
|
238
|
+
if (viewBox.width && !crop) {
|
|
239
|
+
scale = scaleTo / viewBox.width;
|
|
194
240
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
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
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
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(
|
|
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
|
-
|
|
273
|
-
|
|
416
|
+
/**
|
|
417
|
+
* try redrawing
|
|
418
|
+
*/
|
|
274
419
|
|
|
275
|
-
|
|
420
|
+
if (redraw) {
|
|
276
421
|
|
|
277
|
-
//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
|
-
|
|
281
|
-
|
|
282
|
-
|
|
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)
|
|
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
|
-
|
|
348
|
-
|
|
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
|
-
|
|
439
|
-
|
|
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 {
|