svg-path-simplify 0.1.2 → 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 +3935 -1441
- package/dist/svg-path-simplify.esm.min.js +13 -1
- package/dist/svg-path-simplify.js +3953 -1459
- package/dist/svg-path-simplify.min.js +13 -1
- package/dist/svg-path-simplify.min.js.gz +0 -0
- package/dist/svg-path-simplify.poly.cjs +0 -1
- package/index.html +69 -31
- package/package.json +5 -9
- package/src/constants.js +3 -0
- package/src/index-node.js +0 -1
- package/src/index-poly.js +0 -1
- package/src/index.js +26 -0
- package/src/pathData_simplify_cubic.js +75 -46
- 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 +274 -61
- 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 +28 -15
- 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/pathData_transform_scale.js +51 -0
- 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/{testSVG.js → tests/testSVG.js} +1 -1
- /package/{test.js → tests/test.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';
|
|
@@ -23,6 +23,17 @@ import { renderPoint } from './svgii/visualize';
|
|
|
23
23
|
import { refineRoundedCorners } from './svgii/pathData_simplify_refineCorners';
|
|
24
24
|
import { refineRoundSegments } from './svgii/pathData_refine_round';
|
|
25
25
|
import { refineClosingCommand } from './svgii/pathData_remove_short';
|
|
26
|
+
import { scalePathData } from './svgii/pathData_transform_scale';
|
|
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';
|
|
26
37
|
|
|
27
38
|
//import { installDOMPolyfills } from './dom-polyfill';
|
|
28
39
|
|
|
@@ -61,10 +72,23 @@ export function svgPathSimplify(input = '', {
|
|
|
61
72
|
extrapolateDominant = true,
|
|
62
73
|
keepInflections = false,
|
|
63
74
|
addExtremes = false,
|
|
75
|
+
addSemiExtremes = false,
|
|
76
|
+
|
|
77
|
+
smoothPoly = false,
|
|
78
|
+
harmonizeCpts = false,
|
|
79
|
+
toPolygon = false,
|
|
80
|
+
|
|
81
|
+
|
|
64
82
|
removeOrphanSubpaths = false,
|
|
65
83
|
|
|
66
84
|
simplifyRound = false,
|
|
67
85
|
|
|
86
|
+
//svg scaling
|
|
87
|
+
scale = 1,
|
|
88
|
+
scaleTo = 0,
|
|
89
|
+
crop = false,
|
|
90
|
+
alignToOrigin = false,
|
|
91
|
+
|
|
68
92
|
|
|
69
93
|
// svg path optimizations
|
|
70
94
|
decimals = 3,
|
|
@@ -80,15 +104,21 @@ export function svgPathSimplify(input = '', {
|
|
|
80
104
|
removeUnused = true,
|
|
81
105
|
shapesToPaths = true,
|
|
82
106
|
|
|
107
|
+
tMin = 0,
|
|
108
|
+
tMax = 1,
|
|
109
|
+
|
|
110
|
+
// redraw - for messed up paths
|
|
111
|
+
redraw = false,
|
|
112
|
+
|
|
83
113
|
|
|
84
114
|
} = {}) {
|
|
85
115
|
|
|
86
116
|
|
|
87
|
-
// clamp tolerance
|
|
117
|
+
// clamp tolerance and scale
|
|
88
118
|
tolerance = Math.max(0.1, tolerance);
|
|
119
|
+
scale = Math.max(0.001, scale)
|
|
89
120
|
|
|
90
121
|
let inputType = detectInputType(input);
|
|
91
|
-
|
|
92
122
|
let svg = '';
|
|
93
123
|
let svgSize = 0;
|
|
94
124
|
let svgSizeOpt = 0;
|
|
@@ -106,10 +136,21 @@ export function svgPathSimplify(input = '', {
|
|
|
106
136
|
*/
|
|
107
137
|
|
|
108
138
|
// original size
|
|
109
|
-
//svgSize = new Blob([input]).size;
|
|
110
139
|
svgSize = input.length;
|
|
111
140
|
|
|
112
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
|
+
|
|
113
154
|
// mode:0 – single path
|
|
114
155
|
if (!mode) {
|
|
115
156
|
if (inputType === 'pathDataString') {
|
|
@@ -121,7 +162,6 @@ export function svgPathSimplify(input = '', {
|
|
|
121
162
|
d = input;
|
|
122
163
|
|
|
123
164
|
// stringify to compare lengths
|
|
124
|
-
//let dStr = pathDataToD(d);
|
|
125
165
|
let dStr = d.map(com => { return `${com.type} ${com.values.join(' ')}` }).join(' ');
|
|
126
166
|
svgSize = dStr.length;
|
|
127
167
|
|
|
@@ -146,9 +186,17 @@ export function svgPathSimplify(input = '', {
|
|
|
146
186
|
|
|
147
187
|
// collect paths
|
|
148
188
|
let pathEls = svg.querySelectorAll('path')
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
//if(mergePaths){}
|
|
192
|
+
|
|
149
193
|
pathEls.forEach(path => {
|
|
150
194
|
paths.push({ d: path.getAttribute('d'), el: path })
|
|
151
195
|
})
|
|
196
|
+
|
|
197
|
+
// get viewBox/dimensions
|
|
198
|
+
viewBox = getViewBox(svg, decimals)
|
|
199
|
+
|
|
152
200
|
}
|
|
153
201
|
|
|
154
202
|
|
|
@@ -168,18 +216,56 @@ export function svgPathSimplify(input = '', {
|
|
|
168
216
|
// combinded path data for SVGs with mergePaths enabled
|
|
169
217
|
let pathData_merged = [];
|
|
170
218
|
|
|
219
|
+
|
|
171
220
|
for (let i = 0, l = paths.length; l && i < l; i++) {
|
|
172
221
|
|
|
173
222
|
let path = paths[i];
|
|
174
223
|
let { d, el } = path;
|
|
175
224
|
|
|
225
|
+
|
|
176
226
|
let pathData = parsePathDataNormalized(d, { quadraticToCubic, toAbsolute, arcToCubic });
|
|
177
227
|
|
|
228
|
+
// get polygon bbox
|
|
229
|
+
let bb_poly = smoothPoly || toPolygon ? getPolyBBox(getPathDataVertices(pathData)) : null
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
// scale pathdata and viewBox
|
|
233
|
+
if (scale !== 1 || scaleTo) {
|
|
234
|
+
|
|
235
|
+
// get bbox of viewBox for scaling
|
|
236
|
+
if (scaleTo) {
|
|
237
|
+
|
|
238
|
+
if (viewBox.width && !crop) {
|
|
239
|
+
scale = scaleTo / viewBox.width;
|
|
240
|
+
|
|
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)
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
let scaleW = scaleTo / bb.width
|
|
255
|
+
scale = scaleW;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
//console.log('scale', scale, scaleTo);
|
|
260
|
+
pathData = scalePathData(pathData, scale)
|
|
261
|
+
}
|
|
262
|
+
|
|
178
263
|
// count commands for evaluation
|
|
179
264
|
let comCount = pathData.length
|
|
180
265
|
|
|
181
266
|
if (removeOrphanSubpaths) pathData = removeOrphanedM(pathData);
|
|
182
267
|
|
|
268
|
+
|
|
183
269
|
/**
|
|
184
270
|
* get sub paths
|
|
185
271
|
*/
|
|
@@ -201,15 +287,90 @@ export function svgPathSimplify(input = '', {
|
|
|
201
287
|
let pathDataSub = subPathArr[i];
|
|
202
288
|
|
|
203
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
|
+
|
|
204
355
|
// remove zero length linetos
|
|
205
356
|
if (removeColinear || removeZeroLength) pathDataSub = removeZeroLengthLinetos(pathDataSub)
|
|
206
|
-
//console.log(removeColinear, removeZeroLength);
|
|
207
|
-
|
|
208
357
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
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
|
+
}
|
|
213
374
|
|
|
214
375
|
|
|
215
376
|
// sort to top left
|
|
@@ -219,15 +380,23 @@ export function svgPathSimplify(input = '', {
|
|
|
219
380
|
// Preprocessing: remove colinear - ignore flat beziers (removed later)
|
|
220
381
|
if (removeColinear) pathDataSub = pathDataRemoveColinear(pathDataSub, { tolerance, flatBezierToLinetos: false });
|
|
221
382
|
|
|
383
|
+
if (addExtremes || addSemiExtremes) pathDataSub = addExtremePoints(pathDataSub,
|
|
384
|
+
{ tMin, tMax, addExtremes, addSemiExtremes, angles: [30] })
|
|
385
|
+
|
|
386
|
+
|
|
222
387
|
|
|
223
388
|
// analyze pathdata to add info about signicant properties such as extremes, corners
|
|
224
|
-
let pathDataPlus = analyzePathData(pathDataSub
|
|
389
|
+
let pathDataPlus = analyzePathData(pathDataSub, {
|
|
390
|
+
detectSemiExtremes: addSemiExtremes,
|
|
391
|
+
});
|
|
225
392
|
|
|
226
|
-
//console.log(
|
|
393
|
+
//console.log(pathDataPlus, pathDataPlus);
|
|
227
394
|
|
|
228
395
|
|
|
229
396
|
// simplify beziers
|
|
230
397
|
let { pathData, bb, dimA } = pathDataPlus;
|
|
398
|
+
xArr.push(bb.x, bb.x + bb.width)
|
|
399
|
+
yArr.push(bb.y, bb.y + bb.height)
|
|
231
400
|
|
|
232
401
|
|
|
233
402
|
if (refineClosing) pathData = refineClosingCommand(pathData, { threshold: dimA * 0.001 })
|
|
@@ -235,40 +404,47 @@ export function svgPathSimplify(input = '', {
|
|
|
235
404
|
|
|
236
405
|
pathData = simplifyBezier ? simplifyPathDataCubic(pathData, { simplifyBezier, keepInflections, keepExtremes, keepCorners, extrapolateDominant, revertToQuadratics, tolerance, reverse }) : pathData;
|
|
237
406
|
|
|
407
|
+
|
|
238
408
|
// refine extremes
|
|
239
409
|
if (refineExtremes) {
|
|
240
|
-
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
|
|
241
412
|
pathData = refineAdjacentExtremes(pathData, { threshold: thresholdEx, tolerance })
|
|
242
413
|
}
|
|
243
414
|
|
|
244
415
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
let thresh = 1;
|
|
416
|
+
/**
|
|
417
|
+
* try redrawing
|
|
418
|
+
*/
|
|
249
419
|
|
|
250
|
-
|
|
420
|
+
if (redraw) {
|
|
251
421
|
|
|
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
|
+
*/
|
|
252
433
|
|
|
253
|
-
for (let c = 0, l = pathData.length; c < l; c++) {
|
|
254
|
-
let com = pathData[c]
|
|
255
|
-
let { type, values, p0, cp1 = null, cp2 = null, p = null } = com;
|
|
256
|
-
if (type === 'C') {
|
|
257
|
-
//console.log(com);
|
|
258
|
-
let comA = cubicCommandToArc(p0, cp1, cp2, p, thresh)
|
|
259
|
-
if (comA.isArc) pathData[c] = comA.com;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
434
|
|
|
263
|
-
|
|
264
|
-
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 })
|
|
265
438
|
|
|
266
|
-
|
|
267
|
-
*/
|
|
439
|
+
//simplifyPathDataCubic(pathData, { simplifyBezier, keepInflections, keepExtremes, keepCorners, extrapolateDominant, revertToQuadratics, tolerance, reverse })
|
|
268
440
|
|
|
269
441
|
}
|
|
270
442
|
|
|
271
443
|
|
|
444
|
+
// cubic to arcs
|
|
445
|
+
if (cubicToArc) pathData = pathDataCubicsToArc(pathData, { areaThreshold: 2.5 })
|
|
446
|
+
|
|
447
|
+
|
|
272
448
|
// post processing: remove flat beziers
|
|
273
449
|
if (removeColinear && flatBezierToLinetos) {
|
|
274
450
|
pathData = pathDataRemoveColinear(pathData, { tolerance, flatBezierToLinetos });
|
|
@@ -279,7 +455,7 @@ export function svgPathSimplify(input = '', {
|
|
|
279
455
|
if (simplifyCorners) {
|
|
280
456
|
//pathData = removeZeroLengthLinetos(pathData);
|
|
281
457
|
|
|
282
|
-
let threshold = (bb.width + bb.height)
|
|
458
|
+
let threshold = (bb.width + bb.height) * 0.1
|
|
283
459
|
pathData = refineRoundedCorners(pathData, { threshold, tolerance })
|
|
284
460
|
}
|
|
285
461
|
|
|
@@ -288,24 +464,7 @@ export function svgPathSimplify(input = '', {
|
|
|
288
464
|
|
|
289
465
|
|
|
290
466
|
// simplify to quadratics
|
|
291
|
-
if (revertToQuadratics)
|
|
292
|
-
for (let c = 0, l = pathData.length; c < l; c++) {
|
|
293
|
-
let com = pathData[c]
|
|
294
|
-
let { type, values, p0, cp1 = null, cp2 = null, p = null } = com;
|
|
295
|
-
if (type === 'C') {
|
|
296
|
-
//console.log(com);
|
|
297
|
-
let comQ = revertCubicQuadratic(p0, cp1, cp2, p)
|
|
298
|
-
if (comQ.type === 'Q') {
|
|
299
|
-
comQ.extreme = com.extreme
|
|
300
|
-
comQ.corner = com.corner
|
|
301
|
-
comQ.dimA = com.dimA
|
|
302
|
-
|
|
303
|
-
pathData[c] = comQ
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
467
|
+
if (revertToQuadratics) pathData = pathDataRevertCubicToQuadratic(pathData);
|
|
309
468
|
|
|
310
469
|
// optimize close path
|
|
311
470
|
if (optimizeOrder) pathData = optimizeClosePath(pathData, { autoClose })
|
|
@@ -315,10 +474,25 @@ export function svgPathSimplify(input = '', {
|
|
|
315
474
|
//subPathArr[i]=pathData
|
|
316
475
|
pathDataPlusArr.push({ pathData, bb })
|
|
317
476
|
|
|
318
|
-
}
|
|
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)
|
|
319
484
|
|
|
320
|
-
|
|
321
|
-
|
|
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);
|
|
490
|
+
|
|
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
|
+
}
|
|
322
496
|
|
|
323
497
|
// flatten compound paths
|
|
324
498
|
pathData = [];
|
|
@@ -328,8 +502,6 @@ export function svgPathSimplify(input = '', {
|
|
|
328
502
|
|
|
329
503
|
//pathData = pathDataFlat;
|
|
330
504
|
//pathData = subPathArr.flat();
|
|
331
|
-
|
|
332
|
-
|
|
333
505
|
//console.log('pathData', pathData);
|
|
334
506
|
|
|
335
507
|
if (autoAccuracy) {
|
|
@@ -352,6 +524,19 @@ export function svgPathSimplify(input = '', {
|
|
|
352
524
|
// remove zero-length segments introduced by rounding
|
|
353
525
|
pathData = removeZeroLengthLinetos(pathData);
|
|
354
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
|
+
|
|
355
540
|
// compare command count
|
|
356
541
|
let comCountS = pathData.length
|
|
357
542
|
|
|
@@ -374,7 +559,8 @@ export function svgPathSimplify(input = '', {
|
|
|
374
559
|
// apply new path for svgs
|
|
375
560
|
if (el) el.setAttribute('d', dOpt)
|
|
376
561
|
}
|
|
377
|
-
|
|
562
|
+
|
|
563
|
+
} // end path array
|
|
378
564
|
|
|
379
565
|
/**
|
|
380
566
|
* stringify new SVG
|
|
@@ -405,6 +591,32 @@ export function svgPathSimplify(input = '', {
|
|
|
405
591
|
removeEmptySVGEls(svg);
|
|
406
592
|
}
|
|
407
593
|
|
|
594
|
+
// adjust viewBox and width for 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
|
+
}
|
|
608
|
+
|
|
609
|
+
if (hasViewBox) {
|
|
610
|
+
svg.setAttribute('viewBox', [x, y, width, height].map(val => +(val * scale).toFixed(decimals)).join(' '))
|
|
611
|
+
}
|
|
612
|
+
if (hasWidth) {
|
|
613
|
+
svg.setAttribute('width', +(w * scale).toFixed(decimals) + widthUnit)
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
if (hasHeight) {
|
|
617
|
+
svg.setAttribute('height', +(h * scale).toFixed(decimals) + heightUnit)
|
|
618
|
+
}
|
|
619
|
+
}
|
|
408
620
|
|
|
409
621
|
|
|
410
622
|
svg = stringifySVG(svg);
|
|
@@ -419,7 +631,8 @@ export function svgPathSimplify(input = '', {
|
|
|
419
631
|
report = {
|
|
420
632
|
svgSize,
|
|
421
633
|
svgSizeOpt,
|
|
422
|
-
compression
|
|
634
|
+
compression,
|
|
635
|
+
decimals
|
|
423
636
|
}
|
|
424
637
|
|
|
425
638
|
} else {
|