svg-path-simplify 0.4.5 → 0.4.6
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 +9 -0
- package/README.md +8 -0
- package/dist/svg-path-simplify.esm.js +1617 -1219
- package/dist/svg-path-simplify.esm.min.js +2 -2
- package/dist/svg-path-simplify.js +1617 -1218
- package/dist/svg-path-simplify.min.js +2 -2
- package/dist/svg-path-simplify.pathdata.esm.js +293 -665
- package/dist/svg-path-simplify.pathdata.esm.min.js +2 -2
- package/dist/svg-path-simplify.poly.cjs +8 -9
- package/drawing.svg +62 -0
- package/index.html +11 -5
- package/package.json +1 -1
- package/src/index.js +3 -1
- package/src/pathData_get_intersections.js +777 -0
- package/src/pathData_offset.js +201 -0
- package/src/pathData_simplify_cubic.js +14 -34
- package/src/pathData_simplify_cubic_extrapolate.js +147 -8
- package/src/pathData_simplify_cubicsToArcs.js +65 -21
- package/src/pathSimplify-main.js +256 -59
- package/src/pathSimplify-presets.js +1 -0
- package/src/poly-fit-curve-schneider.js +171 -132
- package/src/poly-fit-curve-schneider_check_bulge.js +131 -0
- package/src/poly-offset.js +133 -0
- package/src/simplify_poly_RC.js +29 -7
- package/src/svgii/geometry.js +130 -27
- package/src/svgii/geometry_bbox.js +1 -1
- package/src/svgii/pathData_analyze.js +6 -28
- package/src/svgii/pathData_convert.js +63 -15
- package/src/svgii/pathData_remove_collinear.js +32 -36
- package/src/svgii/pathData_simplify_refineExtremes.js +1 -3
- package/src/svgii/pathData_stringify.js +132 -6
- package/src/svgii/pathData_toPolygon.js +33 -23
- package/src/svgii/poly_analyze.js +272 -125
- package/src/svgii/poly_analyze_cleanup.js +311 -0
- package/src/svgii/poly_analyze_getTangents.js +125 -0
- package/src/svgii/poly_analyze_get_chunks.js +3 -1
- package/src/svgii/poly_normalize.js +12 -0
- package/src/svgii/poly_to_pathdata.js +477 -8
- package/src/svgii/rounding.js +29 -39
- package/src/svgii/svg_cleanup.js +42 -54
- package/src/svgii/svg_cleanup_normalize_transforms.js +1 -1
- package/src/svgii/visualize.js +33 -2
- package/v/0.4.5/index.html +1040 -0
- package/v/0.4.5/svg-path-simplify.js +13227 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { findSplitT, getExtrapolatedCommand } from "../pathData_simplify_cubic";
|
|
2
|
-
import { getCombinedByDominant } from "../pathData_simplify_cubic_extrapolate";
|
|
2
|
+
import { getCombinedByDominant, getCombinedByDominant_back } from "../pathData_simplify_cubic_extrapolate";
|
|
3
3
|
import { bezierhasExtreme, checkLineIntersection, getDistAv, getDistManhattan, getSquareDistance, interpolate } from "./geometry";
|
|
4
4
|
import { getPathArea, getPolygonArea } from "./geometry_area";
|
|
5
5
|
import { getPathDataBBox } from "./geometry_bbox";
|
|
@@ -58,9 +58,7 @@ export function refineAdjacentExtremes(pathData, {
|
|
|
58
58
|
if (comEx.length === 1) {
|
|
59
59
|
|
|
60
60
|
comEx = comEx[0]
|
|
61
|
-
|
|
62
61
|
pathData[i + 1] = null;
|
|
63
|
-
|
|
64
62
|
pathData[i + 2].values = [comEx.cp1.x, comEx.cp1.y, comEx.cp2.x, comEx.cp2.y, comEx.p.x, comEx.p.y]
|
|
65
63
|
pathData[i + 2].cp1 = comEx.cp1
|
|
66
64
|
pathData[i + 2].cp2 = comEx.cp2
|
|
@@ -4,7 +4,129 @@
|
|
|
4
4
|
* d attribute string
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
export function pathDataToD(pathData, mode = 0) {
|
|
7
|
+
export function pathDataToD(pathData = [], mode = 0) {
|
|
8
|
+
|
|
9
|
+
mode = parseFloat(mode)
|
|
10
|
+
/*
|
|
11
|
+
0 = max minification
|
|
12
|
+
0.5 = safe
|
|
13
|
+
1 = verbose
|
|
14
|
+
2 = beautify
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
let len = pathData.length;
|
|
18
|
+
let d = ''
|
|
19
|
+
|
|
20
|
+
// group same types
|
|
21
|
+
let pathDataGrouped = mode >0.5 ? JSON.parse(JSON.stringify(pathData)) : [];
|
|
22
|
+
let typePrev = 'M'
|
|
23
|
+
|
|
24
|
+
if (mode < 1) {
|
|
25
|
+
pathDataGrouped = [pathData[0]];
|
|
26
|
+
//pathDataGrouped = [{type:pathData[0].type, values:[...pathData[0].values]}];
|
|
27
|
+
let idx = 0;
|
|
28
|
+
|
|
29
|
+
for (let i = 1; i < len; i++) {
|
|
30
|
+
let com = pathData[i];
|
|
31
|
+
let { type } = com;
|
|
32
|
+
// decouple from object
|
|
33
|
+
let values = [...com.values]
|
|
34
|
+
|
|
35
|
+
// new type
|
|
36
|
+
if (type !== typePrev) {
|
|
37
|
+
pathDataGrouped.push({type, values})
|
|
38
|
+
idx++
|
|
39
|
+
} else {
|
|
40
|
+
pathDataGrouped[idx].values.push(...values)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// update type
|
|
44
|
+
typePrev = type
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// stringify grouped
|
|
49
|
+
len = pathDataGrouped.length;
|
|
50
|
+
let separator_type = mode < 1 ? '' : ' ';
|
|
51
|
+
let separator_command = mode < 1 ? '' : (mode === 1 ? ' ' : `\n`);
|
|
52
|
+
|
|
53
|
+
typePrev = 'M'
|
|
54
|
+
|
|
55
|
+
for (let i = 0; i < len; i++) {
|
|
56
|
+
let com = pathDataGrouped[i];
|
|
57
|
+
let { type, values } = com;
|
|
58
|
+
|
|
59
|
+
// we're always starting a path with absolute M!
|
|
60
|
+
let omitType = mode < 1 && ((typePrev === 'M' && type === 'L') || (typePrev === 'm' && type === 'l'))
|
|
61
|
+
|
|
62
|
+
// add type
|
|
63
|
+
if (!omitType) d += type + separator_type;
|
|
64
|
+
|
|
65
|
+
// add values
|
|
66
|
+
let wasSmallFloat = false;
|
|
67
|
+
let separatorVal = ' ';
|
|
68
|
+
|
|
69
|
+
for (let v = 0, vlen = values.length; vlen && v < vlen; v++) {
|
|
70
|
+
let val = values[v];
|
|
71
|
+
let valAbs = Math.abs(val);
|
|
72
|
+
let valStr = val.toString();
|
|
73
|
+
let isNegative = val < 0;
|
|
74
|
+
let sign = isNegative ? '-' : ''
|
|
75
|
+
let isSmallFloat = mode > 0.5 ? false : (val && valAbs < 1);
|
|
76
|
+
let idxSub = isSmallFloat ? (isNegative ? 2 : 1) : 0
|
|
77
|
+
|
|
78
|
+
// we don't need whitespace for first value
|
|
79
|
+
separatorVal = v === 0 || isNegative ? '' : ' '
|
|
80
|
+
|
|
81
|
+
if (mode < 1) {
|
|
82
|
+
// omit leading zero
|
|
83
|
+
if (isSmallFloat) valStr = sign + valStr.substring(idxSub)
|
|
84
|
+
|
|
85
|
+
// omit whitespace for subsequent small floats
|
|
86
|
+
separatorVal = (v === 0 && !omitType) || (wasSmallFloat && isSmallFloat) ?
|
|
87
|
+
(!mode ? '' : (isNegative ? '' : ' '))
|
|
88
|
+
: (isNegative ? '' : ' ');
|
|
89
|
+
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// omit separator between large Arc sweep and final x in minify mode
|
|
93
|
+
if (!mode && (type === 'a' || type === 'A')) {
|
|
94
|
+
let pos = (v % 7)
|
|
95
|
+
if (pos > 3 && pos < 6) separatorVal = ''
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
d += `${separatorVal}${valStr}`
|
|
99
|
+
wasSmallFloat = isSmallFloat;
|
|
100
|
+
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// add command separator
|
|
104
|
+
if (mode) d += separator_command;
|
|
105
|
+
|
|
106
|
+
// update previous type
|
|
107
|
+
typePrev = type
|
|
108
|
+
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
//console.log('d', d, mode);
|
|
112
|
+
//console.log('pathDataGrouped', pathDataGrouped);
|
|
113
|
+
//console.log(pathData);
|
|
114
|
+
|
|
115
|
+
return d;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
export function pathDataToD__(pathData, mode = 0) {
|
|
8
130
|
|
|
9
131
|
mode = parseFloat(mode)
|
|
10
132
|
/*
|
|
@@ -79,7 +201,7 @@ export function pathDataToD(pathData, mode = 0) {
|
|
|
79
201
|
valsString = values.join(' ')
|
|
80
202
|
}
|
|
81
203
|
|
|
82
|
-
if(i===len-1) separator_command=''
|
|
204
|
+
if (i === len - 1) separator_command = ''
|
|
83
205
|
d += `${type}${separator_type}${valsString}${separator_command}`;
|
|
84
206
|
}
|
|
85
207
|
|
|
@@ -87,10 +209,14 @@ export function pathDataToD(pathData, mode = 0) {
|
|
|
87
209
|
if (mode < 1) {
|
|
88
210
|
d = d
|
|
89
211
|
.replace(/[A-Za-z]0(?=\.)/g, m => m[0])
|
|
90
|
-
|
|
91
|
-
.replace(/
|
|
92
|
-
|
|
93
|
-
.replace(/
|
|
212
|
+
//Space before small decimals
|
|
213
|
+
.replace(/ 0\./g, " .")
|
|
214
|
+
// Remove space before negatives
|
|
215
|
+
.replace(/ -/g, "-")
|
|
216
|
+
// Remove leading zero from negative decimals
|
|
217
|
+
.replace(/-0\./g, "-.")
|
|
218
|
+
// Convert uppercase 'Z' to lowercase
|
|
219
|
+
.replace(/Z/g, "z")
|
|
94
220
|
}
|
|
95
221
|
|
|
96
222
|
//console.log(`"${d}"`);
|
|
@@ -4,8 +4,8 @@ import { simplifyPolyRD } from "../simplify_poly_radial_distance";
|
|
|
4
4
|
import { getDistAv, getDistManhattan, getSquareDistance, getTatAngles, interpolate, pointAtT } from "./geometry";
|
|
5
5
|
import { getBezierArea, getPolygonArea } from "./geometry_area";
|
|
6
6
|
import { getPolyBBox } from "./geometry_bbox";
|
|
7
|
-
import { addDimensionData, analyzePathData } from "./pathData_analyze";
|
|
8
|
-
import { arcToBezier } from "./pathData_convert";
|
|
7
|
+
import { addDimensionData, analyzePathData, getPathDataVerbose } from "./pathData_analyze";
|
|
8
|
+
import { arcToBezier, convertPathData, pathDataToVerbose } from "./pathData_convert";
|
|
9
9
|
import { pathDataFromPoly } from "./pathData_fromPoly";
|
|
10
10
|
import { addExtremePoints } from "./pathData_split";
|
|
11
11
|
import { pathDataToD } from "./pathData_stringify";
|
|
@@ -23,15 +23,24 @@ import { renderPoint } from "./visualize";
|
|
|
23
23
|
*/
|
|
24
24
|
export function pathDataToPolygonOpt(pathData, {
|
|
25
25
|
precisionPoly = 1,
|
|
26
|
-
autoAccuracy=false,
|
|
27
|
-
polyFormat='
|
|
28
|
-
decimals
|
|
29
|
-
simplifyRD=1,
|
|
30
|
-
simplifyRDP=1,
|
|
26
|
+
autoAccuracy = false,
|
|
27
|
+
polyFormat = 'object',
|
|
28
|
+
decimals = -1,
|
|
29
|
+
simplifyRD = 1,
|
|
30
|
+
simplifyRDP = 1,
|
|
31
31
|
} = {}) {
|
|
32
32
|
|
|
33
33
|
//console.log(pathData);
|
|
34
34
|
|
|
35
|
+
pathData = convertPathData(pathData, {toAbsolute:true, toLonghands:true, arcToCubic:true});
|
|
36
|
+
pathData = addExtremePoints(pathData);
|
|
37
|
+
|
|
38
|
+
//let d2 = pathDataToD(pathData)
|
|
39
|
+
//console.log(d2);
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
pathData = getPathDataVerbose(pathData);
|
|
43
|
+
|
|
35
44
|
let l = pathData.length;
|
|
36
45
|
let M = { x: pathData[0].values[0], y: pathData[0].values[1] }
|
|
37
46
|
let p0 = M
|
|
@@ -59,11 +68,10 @@ simplifyRDP=1,
|
|
|
59
68
|
pts.push(p)
|
|
60
69
|
}
|
|
61
70
|
|
|
62
|
-
|
|
63
71
|
let pts2 = [pts[0]]
|
|
64
72
|
|
|
65
73
|
// adjustments for very small or large paths
|
|
66
|
-
dims = dims.filter(Boolean).sort()
|
|
74
|
+
dims = dims.filter(Boolean).sort((a,b)=>a-b)
|
|
67
75
|
let dimMax = dims[dims.length - 1]
|
|
68
76
|
|
|
69
77
|
let scale = dimMax > 2 && dimMax < 25 ? 1 : (20 / dimMax);
|
|
@@ -104,42 +112,44 @@ simplifyRDP=1,
|
|
|
104
112
|
|
|
105
113
|
|
|
106
114
|
// simplify polygon
|
|
107
|
-
if(simplifyRD>0){
|
|
108
|
-
pts2 = simplifyPolyRD(pts2, {quality:simplifyRD})
|
|
115
|
+
if (simplifyRD > 0) {
|
|
116
|
+
pts2 = simplifyPolyRD(pts2, { quality: simplifyRD })
|
|
109
117
|
}
|
|
110
118
|
|
|
111
119
|
|
|
112
|
-
if(simplifyRDP>0){
|
|
113
|
-
pts2 = simplifyPolyRDP(pts2, {quality:simplifyRDP})
|
|
120
|
+
if (simplifyRDP > 0) {
|
|
121
|
+
pts2 = simplifyPolyRDP(pts2, { quality: simplifyRDP })
|
|
114
122
|
}
|
|
115
123
|
|
|
116
124
|
|
|
117
125
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if(autoAccuracy){
|
|
126
|
+
|
|
127
|
+
if (autoAccuracy) {
|
|
122
128
|
decimals = detectAccuracyPoly(pts)
|
|
123
129
|
}
|
|
124
130
|
|
|
125
|
-
let poly = decimals
|
|
131
|
+
let poly = decimals > -1 ? pts2.map(pt => { return { x: roundTo(pt.x, decimals), y: roundTo(pt.y, decimals) } }) : pts2.map(pt => { return { x: pt.x, y: pt.y } })
|
|
126
132
|
|
|
127
|
-
|
|
133
|
+
pathDataPoly = pathDataFromPoly(poly)
|
|
134
|
+
pathData = pathDataPoly
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
if (polyFormat === 'array') {
|
|
128
139
|
poly = poly.map(pt => { return [pt.x, pt.y] })
|
|
129
140
|
}
|
|
130
|
-
else if(polyFormat==='string'){
|
|
141
|
+
else if (polyFormat === 'string') {
|
|
131
142
|
poly = poly.map(pt => { return [pt.x, pt.y].join(',') }).flat().join(' ')
|
|
132
143
|
}
|
|
133
144
|
|
|
134
|
-
|
|
145
|
+
let d= pathDataToD(pathData)
|
|
135
146
|
|
|
136
|
-
return { pathData, poly }
|
|
147
|
+
return { pathData, poly, d }
|
|
137
148
|
|
|
138
149
|
}
|
|
139
150
|
|
|
140
151
|
|
|
141
152
|
|
|
142
|
-
|
|
143
153
|
/**
|
|
144
154
|
* creates precise polygon
|
|
145
155
|
* from command end points
|