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,5 +1,5 @@
1
1
  import { getCombinedByDominant } from "./pathData_simplify_cubic_extrapolate";
2
- import { getDistance, getSquareDistance, checkLineIntersection, pointAtT, getDistAv, interpolate } from "./svgii/geometry";
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
- //console.log('!error', error);
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 && comN.directionChange) ||
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
- if (combined.length === 1) {
75
- // add cumulative error to prevent distortions
76
- //console.log('combined', combined);
77
- error += combined[0].error * 0.5;
78
- //error += combined[0].error * 1;
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,8 +137,11 @@ 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
- let distAv1 = getDistAv(com1.p0, com1.p);
122
- let distAv2 = getDistAv(com2.p0, com2.p);
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
 
@@ -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 = getDistAv(com1.p, pt)
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;
@@ -155,7 +177,7 @@ export function combineCubicPairs(com1, com2, {
155
177
  // simplified path
156
178
  let t3 = (1 + t) * 0.5;
157
179
  let ptS_2 = pointAtT([comS.p0, comS.cp1, comS.cp2, comS.p], t3)
158
- dist1 = getDistAv(pt_2, ptS_2)
180
+ dist1 = getDistManhattan(pt_2, ptS_2)
159
181
 
160
182
  error += dist1;
161
183
 
@@ -166,16 +188,13 @@ export function combineCubicPairs(com1, com2, {
166
188
 
167
189
  // 1st segment mid
168
190
  let pt_1 = pointAtT([com1.p0, com1.cp1, com1.cp2, com1.p], 0.5)
169
- //let pt_1_2 = pointAtT([com1.p0, com1.cp1, com1.cp2, com1.p], 1)
170
-
171
191
 
172
192
  let t2 = t * 0.5;
173
193
  let ptS_1 = pointAtT([comS.p0, comS.cp1, comS.cp2, comS.p], t2)
174
- dist2 = getDistAv(pt_1, ptS_1)
175
-
194
+ dist2 = getDistManhattan(pt_1, ptS_1)
176
195
 
177
196
  error += dist2;
178
-
197
+
179
198
  if (error < maxDist) success = true;
180
199
 
181
200
  }
@@ -191,10 +210,11 @@ export function combineCubicPairs(com1, com2, {
191
210
  comS.p0 = com1.p0
192
211
  comS.p = com2.p
193
212
 
194
- comS.dimA = getDistAv(comS.p0, comS.p);
213
+ comS.dimA = getDistManhattan(comS.p0, comS.p);
195
214
  comS.type = 'C';
196
215
  comS.extreme = com2.extreme;
197
216
  comS.directionChange = com2.directionChange;
217
+ //comS.directionChange = com1.directionChange ? true : (com2.directionChange);
198
218
  comS.corner = com2.corner;
199
219
 
200
220
  comS.values = [comS.cp1.x, comS.cp1.y, comS.cp2.x, comS.cp2.y, comS.p.x, comS.p.y]
@@ -264,14 +284,35 @@ export function getBezierCommandArea(commands = [com1, com2], absolute = true) {
264
284
  }
265
285
 
266
286
 
287
+
267
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)
268
291
 
269
- let len3 = getDistance(com1.cp2, com1.p)
270
- let len4 = getDistance(com1.cp2, com2.cp1)
292
+ // exit for zero length control point vectors
293
+ if (l1 === 0) {
294
+ //console.log('!quit1');
295
+ return 0;
296
+ }
271
297
 
272
- let t = Math.min(len3) / len4
298
+ let l2 = getDistManhattan(com1.p, com2.cp1)
299
+ if (l2 === 0) {
300
+ //console.log('!quit2');
301
+ return 0;
302
+ }
273
303
 
274
- return t
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
+ */
314
+
315
+ return l1 / l3
275
316
  }
276
317
 
277
318
 
@@ -279,3 +320,5 @@ export function findSplitT(com1, com2) {
279
320
 
280
321
 
281
322
 
323
+
324
+