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.
- package/CHANGELOG.md +10 -0
- package/README.md +6 -4
- package/dist/svg-path-simplify.esm.js +2139 -940
- package/dist/svg-path-simplify.esm.min.js +2 -2
- package/dist/svg-path-simplify.js +2139 -940
- package/dist/svg-path-simplify.min.js +2 -2
- package/dist/svg-path-simplify.pathdata.esm.js +127 -85
- package/dist/svg-path-simplify.pathdata.esm.min.js +2 -2
- package/docs/privacy-webapp.md +24 -0
- package/index.html +290 -152
- package/package.json +1 -1
- package/src/css_parse.js +317 -0
- package/src/detect_input.js +34 -4
- package/src/pathData_simplify_harmonize_cpts.js +77 -1
- package/src/pathSimplify-main.js +242 -269
- package/src/pathSimplify-presets.js +243 -0
- package/src/poly-fit-curve-schneider.js +14 -7
- package/src/simplify_poly_RC.js +102 -0
- package/src/simplify_poly_RDP.js +109 -1
- package/src/simplify_poly_radial_distance.js +3 -3
- package/src/string_helpers.js +130 -4
- package/src/svgii/geometry.js +182 -3
- package/src/svgii/geometry_length.js +237 -0
- package/src/svgii/pathData_convert.js +5 -1
- package/src/svgii/pathData_fix_directions.js +6 -0
- package/src/svgii/pathData_fromPoly.js +3 -3
- package/src/svgii/pathData_getLength.js +86 -0
- package/src/svgii/pathData_parse.js +2 -0
- package/src/svgii/pathData_parse_els.js +66 -68
- package/src/svgii/pathData_split_to_groups.js +168 -0
- package/src/svgii/pathData_stringify.js +26 -64
- package/src/svgii/pathData_toPolygon.js +3 -4
- package/src/svgii/poly_analyze.js +61 -0
- package/src/svgii/poly_normalize.js +11 -2
- package/src/svgii/poly_to_pathdata.js +85 -24
- package/src/svgii/rounding.js +8 -7
- package/src/svgii/svg_cleanup.js +374 -620
- package/src/svgii/svg_cleanup_convertPathLength.js +32 -0
- package/src/svgii/svg_cleanup_general_svg_atts.js +97 -0
- package/src/svgii/svg_cleanup_normalize_transforms.js +83 -0
- package/src/svgii/svg_cleanup_remove_els_and_atts.js +72 -0
- package/src/svgii/svg_cleanup_ungroup.js +36 -0
- package/src/svgii/svg_el_parse_style_props.js +65 -43
- 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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
//
|
|
54
|
-
|
|
55
|
-
|
|
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 (
|
|
60
|
-
|
|
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
|
-
|
|
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
|
|
package/src/svgii/rounding.js
CHANGED
|
@@ -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 /
|
|
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 =
|
|
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>
|
|
108
|
+
else if(val>integerThresh){
|
|
110
109
|
decimals=1
|
|
111
110
|
}else{
|
|
112
|
-
decimals=Math.ceil(
|
|
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
|
}
|