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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getCombinedByDominant } from "./pathData_simplify_cubic_extrapolate";
|
|
2
|
-
import { getDistance, getSquareDistance, checkLineIntersection, pointAtT,
|
|
2
|
+
import { getDistance, getSquareDistance, checkLineIntersection, pointAtT, interpolate, getDistManhattan } from "./svgii/geometry";
|
|
3
3
|
import { getBezierArea, getPolygonArea } from "./svgii/geometry_area";
|
|
4
4
|
import { renderPoint } from "./svgii/visualize";
|
|
5
5
|
|
|
@@ -22,10 +22,11 @@ export function simplifyPathDataCubic(pathData, {
|
|
|
22
22
|
let typeN = comN?.type || null;
|
|
23
23
|
//let isCornerN = comN?.corner || null;
|
|
24
24
|
//let isExtremeN = comN?.extreme || null;
|
|
25
|
-
let isDirChange = com?.directionChange || null;
|
|
26
|
-
let isDirChangeN = comN?.directionChange || null;
|
|
27
25
|
|
|
28
|
-
let { type, values, p0, p, cp1 = null, cp2 = null, extreme = false, corner = false, dimA = 0 } = com;
|
|
26
|
+
let { type, values, p0, p, cp1 = null, cp2 = null, extreme = false, directionChange = false, corner = false, dimA = 0 } = com;
|
|
27
|
+
|
|
28
|
+
//let isDirChange = com?.directionChange || null;
|
|
29
|
+
//let isDirChangeN = comN?.directionChange || null;
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
// next is also cubic
|
|
@@ -33,9 +34,10 @@ export function simplifyPathDataCubic(pathData, {
|
|
|
33
34
|
|
|
34
35
|
// cannot be combined as crossing extremes or corners
|
|
35
36
|
if (
|
|
36
|
-
(keepInflections && isDirChangeN) ||
|
|
37
|
+
//(keepInflections && isDirChangeN) ||
|
|
37
38
|
(keepCorners && corner) ||
|
|
38
|
-
(!isDirChange && keepExtremes && extreme)
|
|
39
|
+
//(!isDirChange && keepExtremes && extreme)
|
|
40
|
+
(keepExtremes && extreme)
|
|
39
41
|
) {
|
|
40
42
|
//renderPoint(markers, p, 'red', '1%')
|
|
41
43
|
pathDataN.push(com)
|
|
@@ -44,9 +46,12 @@ export function simplifyPathDataCubic(pathData, {
|
|
|
44
46
|
// try simplification
|
|
45
47
|
else {
|
|
46
48
|
//renderPoint(markers, p, 'magenta', '1%')
|
|
47
|
-
let combined = combineCubicPairs(com, comN, {tolerance})
|
|
49
|
+
let combined = combineCubicPairs(com, comN, { tolerance })
|
|
48
50
|
let error = 0;
|
|
49
51
|
|
|
52
|
+
//!count simplification success or failure - just for debugging
|
|
53
|
+
//let log = [];
|
|
54
|
+
|
|
50
55
|
// combining successful! try next segment
|
|
51
56
|
if (combined.length === 1) {
|
|
52
57
|
com = combined[0]
|
|
@@ -54,15 +59,16 @@ export function simplifyPathDataCubic(pathData, {
|
|
|
54
59
|
|
|
55
60
|
// add cumulative error to prevent distortions
|
|
56
61
|
error += com.error;
|
|
57
|
-
|
|
62
|
+
|
|
63
|
+
//!log.push(`success1: ${i} and ${i + 1}`)
|
|
58
64
|
|
|
59
65
|
// find next candidates
|
|
60
|
-
//offset<2 &&
|
|
61
66
|
for (let n = i + 1; error < tolerance && n < l; n++) {
|
|
62
67
|
let comN = pathData[n]
|
|
68
|
+
|
|
63
69
|
if (comN.type !== 'C' ||
|
|
64
70
|
(
|
|
65
|
-
(keepInflections &&
|
|
71
|
+
(keepInflections && com.directionChange) ||
|
|
66
72
|
(keepCorners && com.corner) ||
|
|
67
73
|
(keepExtremes && com.extreme)
|
|
68
74
|
)
|
|
@@ -70,20 +76,33 @@ export function simplifyPathDataCubic(pathData, {
|
|
|
70
76
|
break
|
|
71
77
|
}
|
|
72
78
|
|
|
73
|
-
let combined = combineCubicPairs(com, comN, {tolerance})
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
offset++
|
|
79
|
+
let combined = combineCubicPairs(com, comN, { tolerance })
|
|
80
|
+
|
|
81
|
+
// failure - could not be combined - exit loop
|
|
82
|
+
if (combined.length > 1) {
|
|
83
|
+
//log.push(`fail: ${i} and ${n}`)
|
|
84
|
+
break
|
|
80
85
|
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* success
|
|
89
|
+
* add cumulative error to prevent distortions
|
|
90
|
+
*/
|
|
91
|
+
error += combined[0].error * 0.5;
|
|
92
|
+
offset++
|
|
93
|
+
|
|
94
|
+
//!log.push(`success2: ${i} and ${n}`)
|
|
95
|
+
|
|
96
|
+
// return combined
|
|
81
97
|
com = combined[0]
|
|
82
98
|
}
|
|
83
99
|
|
|
100
|
+
//console.log('tests', log, offset);
|
|
101
|
+
|
|
84
102
|
//com.opt = true
|
|
85
103
|
pathDataN.push(com)
|
|
86
104
|
|
|
105
|
+
// skip to next candidates
|
|
87
106
|
if (i < l) {
|
|
88
107
|
i += offset
|
|
89
108
|
}
|
|
@@ -118,12 +137,15 @@ export function combineCubicPairs(com1, com2, {
|
|
|
118
137
|
// assume 2 segments are result of a segment split
|
|
119
138
|
let t = findSplitT(com1, com2);
|
|
120
139
|
|
|
121
|
-
|
|
122
|
-
|
|
140
|
+
// quit if t is start
|
|
141
|
+
if (!t) return commands;
|
|
142
|
+
|
|
143
|
+
let distAv1 = getDistManhattan(com1.p0, com1.p);
|
|
144
|
+
let distAv2 = getDistManhattan(com2.p0, com2.p);
|
|
123
145
|
let distMin = Math.max(0, Math.min(distAv1, distAv2))
|
|
124
146
|
|
|
125
147
|
|
|
126
|
-
let distScale = 0.
|
|
148
|
+
let distScale = 0.08
|
|
127
149
|
let maxDist = distMin * distScale * tolerance
|
|
128
150
|
|
|
129
151
|
// get hypothetical combined command
|
|
@@ -133,7 +155,7 @@ export function combineCubicPairs(com1, com2, {
|
|
|
133
155
|
let pt = pointAtT([comS.p0, comS.cp1, comS.cp2, comS.p], t)
|
|
134
156
|
|
|
135
157
|
|
|
136
|
-
let dist0 =
|
|
158
|
+
let dist0 = getDistManhattan(com1.p, pt)
|
|
137
159
|
let dist1 = 0, dist2 = 0;
|
|
138
160
|
let close = dist0 < maxDist;
|
|
139
161
|
let success = false;
|
|
@@ -142,7 +164,6 @@ export function combineCubicPairs(com1, com2, {
|
|
|
142
164
|
let error = dist0;
|
|
143
165
|
|
|
144
166
|
|
|
145
|
-
|
|
146
167
|
if (close) {
|
|
147
168
|
|
|
148
169
|
/**
|
|
@@ -156,15 +177,10 @@ export function combineCubicPairs(com1, com2, {
|
|
|
156
177
|
// simplified path
|
|
157
178
|
let t3 = (1 + t) * 0.5;
|
|
158
179
|
let ptS_2 = pointAtT([comS.p0, comS.cp1, comS.cp2, comS.p], t3)
|
|
159
|
-
dist1 =
|
|
180
|
+
dist1 = getDistManhattan(pt_2, ptS_2)
|
|
160
181
|
|
|
161
182
|
error += dist1;
|
|
162
183
|
|
|
163
|
-
|
|
164
|
-
// quit - paths not congruent
|
|
165
|
-
//if (dist2 > tolerance) return commands;
|
|
166
|
-
|
|
167
|
-
|
|
168
184
|
if (dist1 < maxDist) {
|
|
169
185
|
|
|
170
186
|
//renderPoint(markers, pt_2, 'magenta')
|
|
@@ -175,22 +191,11 @@ export function combineCubicPairs(com1, com2, {
|
|
|
175
191
|
|
|
176
192
|
let t2 = t * 0.5;
|
|
177
193
|
let ptS_1 = pointAtT([comS.p0, comS.cp1, comS.cp2, comS.p], t2)
|
|
178
|
-
dist2 =
|
|
179
|
-
|
|
180
|
-
/*
|
|
181
|
-
if(dist1>tolerance){
|
|
182
|
-
renderPoint(markers, pt_1, 'blue')
|
|
183
|
-
renderPoint(markers, ptS_1, 'orange', '0.5%')
|
|
184
|
-
}
|
|
185
|
-
*/
|
|
194
|
+
dist2 = getDistManhattan(pt_1, ptS_1)
|
|
186
195
|
|
|
187
|
-
// quit - paths not congruent
|
|
188
|
-
if (dist1 + dist2 < maxDist) success = true;
|
|
189
|
-
|
|
190
|
-
// collect error data
|
|
191
196
|
error += dist2;
|
|
192
197
|
|
|
193
|
-
|
|
198
|
+
if (error < maxDist) success = true;
|
|
194
199
|
|
|
195
200
|
}
|
|
196
201
|
|
|
@@ -205,10 +210,11 @@ export function combineCubicPairs(com1, com2, {
|
|
|
205
210
|
comS.p0 = com1.p0
|
|
206
211
|
comS.p = com2.p
|
|
207
212
|
|
|
208
|
-
comS.dimA =
|
|
213
|
+
comS.dimA = getDistManhattan(comS.p0, comS.p);
|
|
209
214
|
comS.type = 'C';
|
|
210
215
|
comS.extreme = com2.extreme;
|
|
211
216
|
comS.directionChange = com2.directionChange;
|
|
217
|
+
//comS.directionChange = com1.directionChange ? true : (com2.directionChange);
|
|
212
218
|
comS.corner = com2.corner;
|
|
213
219
|
|
|
214
220
|
comS.values = [comS.cp1.x, comS.cp1.y, comS.cp2.x, comS.cp2.y, comS.p.x, comS.p.y]
|
|
@@ -278,14 +284,35 @@ export function getBezierCommandArea(commands = [com1, com2], absolute = true) {
|
|
|
278
284
|
}
|
|
279
285
|
|
|
280
286
|
|
|
287
|
+
|
|
281
288
|
export function findSplitT(com1, com2) {
|
|
289
|
+
// distances between 1st and 2nd segment cpt to mid point
|
|
290
|
+
let l1 = getDistManhattan(com1.cp2, com1.p)
|
|
282
291
|
|
|
283
|
-
|
|
284
|
-
|
|
292
|
+
// exit for zero length control point vectors
|
|
293
|
+
if (l1 === 0) {
|
|
294
|
+
//console.log('!quit1');
|
|
295
|
+
return 0;
|
|
296
|
+
}
|
|
285
297
|
|
|
286
|
-
let
|
|
298
|
+
let l2 = getDistManhattan(com1.p, com2.cp1)
|
|
299
|
+
if (l2 === 0) {
|
|
300
|
+
//console.log('!quit2');
|
|
301
|
+
return 0;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// dist between both segments' control points
|
|
305
|
+
let l3 = getDistManhattan(com1.cp2, com2.cp1)
|
|
306
|
+
|
|
307
|
+
/*
|
|
308
|
+
// exit for zero length control point vectors
|
|
309
|
+
if(l1===0 || l2===0 || l1===l3 || l2===l3) {
|
|
310
|
+
console.log('!quit');
|
|
311
|
+
return 0;
|
|
312
|
+
}
|
|
313
|
+
*/
|
|
287
314
|
|
|
288
|
-
return
|
|
315
|
+
return l1 / l3
|
|
289
316
|
}
|
|
290
317
|
|
|
291
318
|
|
|
@@ -293,3 +320,5 @@ export function findSplitT(com1, com2) {
|
|
|
293
320
|
|
|
294
321
|
|
|
295
322
|
|
|
323
|
+
|
|
324
|
+
|