svg-path-simplify 0.4.2 → 0.4.3

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 (44) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +6 -4
  3. package/dist/svg-path-simplify.esm.js +2139 -940
  4. package/dist/svg-path-simplify.esm.min.js +2 -2
  5. package/dist/svg-path-simplify.js +2139 -940
  6. package/dist/svg-path-simplify.min.js +2 -2
  7. package/dist/svg-path-simplify.pathdata.esm.js +127 -85
  8. package/dist/svg-path-simplify.pathdata.esm.min.js +2 -2
  9. package/docs/privacy-webapp.md +24 -0
  10. package/index.html +290 -152
  11. package/package.json +1 -1
  12. package/src/css_parse.js +317 -0
  13. package/src/detect_input.js +34 -4
  14. package/src/pathData_simplify_harmonize_cpts.js +77 -1
  15. package/src/pathSimplify-main.js +242 -269
  16. package/src/pathSimplify-presets.js +243 -0
  17. package/src/poly-fit-curve-schneider.js +14 -7
  18. package/src/simplify_poly_RC.js +102 -0
  19. package/src/simplify_poly_RDP.js +109 -1
  20. package/src/simplify_poly_radial_distance.js +3 -3
  21. package/src/string_helpers.js +130 -4
  22. package/src/svgii/geometry.js +182 -3
  23. package/src/svgii/geometry_length.js +237 -0
  24. package/src/svgii/pathData_convert.js +5 -1
  25. package/src/svgii/pathData_fix_directions.js +6 -0
  26. package/src/svgii/pathData_fromPoly.js +3 -3
  27. package/src/svgii/pathData_getLength.js +86 -0
  28. package/src/svgii/pathData_parse.js +2 -0
  29. package/src/svgii/pathData_parse_els.js +66 -68
  30. package/src/svgii/pathData_split_to_groups.js +168 -0
  31. package/src/svgii/pathData_stringify.js +26 -64
  32. package/src/svgii/pathData_toPolygon.js +3 -4
  33. package/src/svgii/poly_analyze.js +61 -0
  34. package/src/svgii/poly_normalize.js +11 -2
  35. package/src/svgii/poly_to_pathdata.js +85 -24
  36. package/src/svgii/rounding.js +8 -7
  37. package/src/svgii/svg_cleanup.js +374 -620
  38. package/src/svgii/svg_cleanup_convertPathLength.js +32 -0
  39. package/src/svgii/svg_cleanup_general_svg_atts.js +97 -0
  40. package/src/svgii/svg_cleanup_normalize_transforms.js +83 -0
  41. package/src/svgii/svg_cleanup_remove_els_and_atts.js +72 -0
  42. package/src/svgii/svg_cleanup_ungroup.js +36 -0
  43. package/src/svgii/svg_el_parse_style_props.js +65 -43
  44. package/src/svgii/svg_getElementLength.js +67 -0
@@ -5,15 +5,19 @@
5
5
  * https://francoisromain.medium.com/smooth-a-svg-path-with-cubic-bezier-curves-e37b49d46c74
6
6
  */
7
7
 
8
- import { checkLineIntersection, getDistManhattan, interpolate, mirrorCpts } from "./geometry";
8
+ import { checkLineIntersection, getAngle, getDistance, getDistManhattan, getPathDataVertices, getPointOnEllipse, getSquareDistance, interpolate, mirrorCpts, reducePoints, rotatePoint } from "./geometry";
9
9
  import { getPolyBBox } from "./geometry_bbox";
10
10
  import { renderPath, renderPoint, renderPoly } from "./visualize";
11
11
  import { simplifyPolyRDP } from "../simplify_poly_RDP";
12
12
  import { pathDataFromPoly } from "./pathData_fromPoly";
13
13
  import { getPolyChunks } from "./poly_analyze_get_chunks";
14
- import { analyzePoly, isClosedPolygon } from "./poly_analyze";
14
+ import { analyzePoly, detectRegularPolygon, getPolyCentroid, getPolyCentroidWeighted, isClosedPolygon } from "./poly_analyze";
15
15
  import { fitCurveSchneider } from "../poly-fit-curve-schneider";
16
16
  import { simplifyPolyRD } from "../simplify_poly_radial_distance";
17
+ import { simplifyRC } from "../simplify_poly_RC";
18
+ import { getPolygonArea } from "./geometry_area";
19
+ import { pathDataToD } from "./pathData_stringify";
20
+ import { fixIntersectingCpts } from "../pathData_simplify_harmonize_cpts";
17
21
 
18
22
 
19
23
 
@@ -34,34 +38,89 @@ export function simplifyPolygonToPathData(pts, {
34
38
  } = {}) {
35
39
 
36
40
 
41
+ let polyPath = [];
42
+ let l = pts.length;
43
+ let M = pts[0]
44
+ let Z = pts[l - 1]
45
+
46
+
47
+ // triangle
48
+ if (pts.length === 3) {
49
+
50
+ let pM1 = interpolate(M, pts[1], 0.5)
51
+ let pM2 = interpolate(pts[1], Z, 0.5)
52
+ let pM3 = interpolate(Z, pts[0], 0.5)
53
+
54
+ /*
55
+ console.log('triangle');
56
+ renderPoint(markers, M)
57
+ renderPoint(markers, pM1)
58
+ renderPoint(markers, pM2)
59
+ renderPoint(markers, pM3)
60
+ */
61
+
62
+ if (closed) {
63
+ let t = 0.6666
64
+ let cp1_1 = interpolate(pM1, pts[1], t)
65
+ let cp2_1 = interpolate(pM2, pts[1], t)
66
+ let cp1_2 = interpolate(pM2, Z, t)
67
+ let cp2_2 = interpolate(pM3, Z, t)
68
+ let cp1_3 = interpolate(pM3, M, t)
69
+ let cp2_3 = interpolate(pM1, M, t)
70
+
71
+ polyPath = [
72
+ { type: 'M', values: [pM1.x, pM1.y] },
73
+ { type: 'C', values: [cp1_1.x, cp1_1.y, cp2_1.x, cp2_1.y, pM2.x, pM2.y] },
74
+ { type: 'C', values: [cp1_2.x, cp1_2.y, cp2_2.x, cp2_2.y, pM3.x, pM3.y] },
75
+ { type: 'C', values: [cp1_3.x, cp1_3.y, cp2_3.x, cp2_3.y, pM1.x, pM1.y] },
76
+ { type: 'Z', values: [] },
77
+ ]
37
78
 
38
- /*
39
- // denoise via RDP
40
- if (denoise && denoise !== 1) {
41
- pts = simplifyPolyRDP(pts, {
42
- width,
43
- height,
44
- quality: denoise,
45
- manhattan,
46
- absolute
47
- })
79
+ } else {
80
+ polyPath = [
81
+ //{ type: 'M', values: [pM1.x, pM1.y] },
82
+ { type: 'M', values: [M.x, M.y] },
83
+ { type: 'C', values: [pts[1].x, pts[1].y, pts[1].x, pts[1].y, Z.x, Z.y] },
84
+ ]
85
+ }
86
+ return polyPath;
48
87
  }
49
- */
50
88
 
51
89
 
52
- /*
53
- // simplify polygon
54
- if (simplifyRD != 1) {
55
- pts = simplifyPolyRD(pts, { quality: simplifyRD+'px' })
56
- }
90
+
91
+ // remove colinear
92
+ //pts = simplifyRC(pts)
93
+
94
+ /**
95
+ * detect regular polygon
96
+ * curved path is a circle
97
+ */
98
+ let centroid = getPolyCentroid(simplifyRC(pts))
99
+ let isRegularPolygon = detectRegularPolygon(pts, centroid)
57
100
 
58
101
 
59
- if (simplifyRDP != 1) {
60
- pts = simplifyPolyRDP(pts, { quality: simplifyRDP+'px' })
102
+ if (isRegularPolygon) {
103
+ //renderPoint(markers, centroid)
104
+ //let r = getDistance(centroid, pts[0])
105
+ let ptAd = rotatePoint(pts[0], centroid.x, centroid.y, Math.PI)
106
+ let sweep = getPolygonArea(pts) > 0 ? 1 : 0;
107
+
108
+ polyPath = [
109
+ { type: 'M', values: [pts[0].x, pts[0].y] },
110
+ { type: 'A', values: [1, 1, 0, 0, sweep, ptAd.x, ptAd.y] },
111
+ { type: 'A', values: [1, 1, 0, 0, sweep, pts[0].x, pts[0].y] }
112
+ ]
113
+
114
+ if (closed) {
115
+ polyPath.push({ type: 'Z', values: [] })
116
+ }
117
+ return polyPath;
61
118
  }
62
- */
63
119
 
64
120
 
121
+ // remove colinear
122
+ //pts = simplifyRC(pts)
123
+
65
124
  // get topology of poly
66
125
  let polyAnalyzed = !keepExtremes && !keepCorners ? pts : analyzePoly(pts, {
67
126
  debug: false
@@ -70,7 +129,6 @@ export function simplifyPolygonToPathData(pts, {
70
129
  })
71
130
 
72
131
  //console.log(polyAnalyzed, polyAnalyzed2);
73
- //return
74
132
 
75
133
  // split into segment chunks
76
134
  let chunks = !keepExtremes && !keepCorners ? [polyAnalyzed] : getPolyChunks(polyAnalyzed, { keepCorners, keepExtremes, keepInflections });
@@ -81,12 +139,15 @@ export function simplifyPolygonToPathData(pts, {
81
139
 
82
140
  //threshold = 2
83
141
 
84
- let polyPath = simplifyPolyChunks(chunks, {
142
+ polyPath = simplifyPolyChunks(chunks, {
85
143
  closed,
86
144
  tolerance: threshold,
87
- keepCorners
145
+ keepCorners,
146
+ keepExtremes: true,
88
147
  });
89
148
 
149
+ polyPath = fixIntersectingCpts(polyPath);
150
+
90
151
  return polyPath;
91
152
  }
92
153
 
@@ -72,7 +72,7 @@ export function detectAccuracy(pathData) {
72
72
  let dim_min = dims.sort()
73
73
  //console.log('dim_min', dim_min);
74
74
 
75
- let sliceIdx = Math.ceil(dim_min.length / 8);
75
+ let sliceIdx = Math.ceil(dim_min.length / 6);
76
76
  dim_min = dim_min.slice(0, sliceIdx);
77
77
  let minVal = dim_min.reduce((a, b) => a + b, 0) / sliceIdx;
78
78
 
@@ -88,6 +88,7 @@ export function detectAccuracy(pathData) {
88
88
 
89
89
 
90
90
  export function roundTo(num = 0, decimals = 3) {
91
+ if(decimals<=-1) return num;
91
92
  if (!decimals) return Math.round(num);
92
93
  let factor = 10 ** decimals;
93
94
  return Math.round(num * factor) / factor;
@@ -98,20 +99,20 @@ export function roundTo(num = 0, decimals = 3) {
98
99
  * floating point accuracy
99
100
  * based on numeric value
100
101
  */
101
- export function autoRound(val, integerThresh = 10){
102
+ export function autoRound(val, integerThresh = 50){
102
103
  let decimals=8;
103
-
104
- //console.log('val', val);
105
104
 
106
- if(val>integerThresh){
105
+ if(val>integerThresh*2){
107
106
  decimals=0
108
107
  }
109
- else if(val>5){
108
+ else if(val>integerThresh){
110
109
  decimals=1
111
110
  }else{
112
- decimals=Math.ceil(integerThresh/val).toString().length
111
+ decimals=Math.ceil(500/val).toString().length
112
+ //console.log('decimals small', val, decimals);
113
113
  }
114
114
 
115
+ //console.log(val, decimals);
115
116
  let factor = 10 ** decimals;
116
117
  return Math.round(val * factor) / factor;
117
118
  }