svg-path-simplify 0.4.2 → 0.4.4
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 +21 -0
- package/README.md +7 -4
- package/dist/svg-path-simplify.esm.js +3593 -1279
- package/dist/svg-path-simplify.esm.min.js +2 -2
- package/dist/svg-path-simplify.js +3594 -1278
- package/dist/svg-path-simplify.min.js +2 -2
- package/dist/svg-path-simplify.pathdata.esm.js +1017 -538
- package/dist/svg-path-simplify.pathdata.esm.min.js +2 -2
- package/dist/svg-path-simplify.poly.cjs +9 -8
- package/docs/privacy-webapp.md +24 -0
- package/index.html +331 -152
- package/package.json +1 -1
- package/src/constants.js +4 -0
- package/src/css_parse.js +317 -0
- package/src/detect_input.js +76 -28
- package/src/index.js +8 -0
- package/src/pathData_simplify_cubic.js +26 -16
- package/src/pathData_simplify_harmonize_cpts.js +77 -1
- package/src/pathData_simplify_revertToquadratics.js +0 -1
- package/src/pathSimplify-main.js +304 -276
- package/src/pathSimplify-only-pathdata.js +7 -2
- package/src/pathSimplify-presets.js +254 -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/svg-getAttributes.js +4 -2
- package/src/svgii/convert_units.js +1 -1
- package/src/svgii/geometry.js +322 -5
- package/src/svgii/geometry_bbox_element.js +1 -1
- package/src/svgii/geometry_deduceRadius.js +116 -27
- package/src/svgii/geometry_length.js +253 -0
- package/src/svgii/pathData_analyze.js +18 -0
- package/src/svgii/pathData_convert.js +193 -89
- package/src/svgii/pathData_fix_directions.js +12 -14
- 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_reorder.js +122 -16
- package/src/svgii/pathData_simplify_refineCorners.js +130 -35
- package/src/svgii/pathData_simplify_refine_round.js +420 -0
- 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 +80 -78
- package/src/svgii/svg_cleanup.js +421 -619
- package/src/svgii/svg_cleanup_convertPathLength.js +39 -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 +77 -0
- package/src/svgii/svg_cleanup_ungroup.js +36 -0
- package/src/svgii/svg_el_parse_style_props.js +72 -47
- package/src/svgii/svg_getElementLength.js +67 -0
- package/src/svgii/svg_validate.js +220 -0
- package/tests/testSVG.js +14 -1
- package/src/svgii/pathData_refine_round.js +0 -222
package/src/pathSimplify-main.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { detectInputType } from './detect_input';
|
|
2
2
|
import { simplifyPathDataCubic } from './pathData_simplify_cubic';
|
|
3
|
-
import { getDistManhattan, getDistance, getPathDataVertices, interpolate, pointAtT } from './svgii/geometry';
|
|
3
|
+
import { getDistManhattan, getDistance, getPathDataVertices, getSquareDistance, interpolate, pointAtT, reducePoints, svgArcToCenterParam, toParametricAngle } from './svgii/geometry';
|
|
4
4
|
import { getPolyBBox } from './svgii/geometry_bbox';
|
|
5
|
-
import { analyzePathData } from './svgii/pathData_analyze';
|
|
5
|
+
import { analyzePathData, getPathDataVerbose } from './svgii/pathData_analyze';
|
|
6
6
|
import { normalizePathData, parsePathDataNormalized, convertPathData } from './svgii/pathData_convert';
|
|
7
7
|
import { shapeElToPath } from './svgii/pathData_parse_els';
|
|
8
8
|
import { pathDataRemoveColinear } from './svgii/pathData_remove_collinear';
|
|
@@ -12,164 +12,97 @@ import { optimizeClosePath, pathDataToTopLeft } from './svgii/pathData_reorder';
|
|
|
12
12
|
import { reversePathData } from './svgii/pathData_reverse';
|
|
13
13
|
import { addExtremePoints, splitSubpaths } from './svgii/pathData_split';
|
|
14
14
|
import { pathDataToD } from './svgii/pathData_stringify';
|
|
15
|
-
import { detectAccuracy, roundPathData } from './svgii/rounding';
|
|
15
|
+
import { detectAccuracy, roundPathData, roundTo } from './svgii/rounding';
|
|
16
16
|
import { refineAdjacentExtremes } from './svgii/pathData_simplify_refineExtremes';
|
|
17
|
-
import { cleanUpSVG, removeEmptySVGEls
|
|
17
|
+
import { cleanUpSVG, removeEmptySVGEls } from './svgii/svg_cleanup';
|
|
18
18
|
import { refineRoundedCorners } from './svgii/pathData_simplify_refineCorners';
|
|
19
|
-
import { refineRoundSegments } from './svgii/
|
|
19
|
+
import { refineRoundSegments, simplifyAdjacentRound } from './svgii/pathData_simplify_refine_round';
|
|
20
20
|
import { refineClosingCommand } from './svgii/pathData_remove_short';
|
|
21
21
|
import { scalePathData } from './svgii/pathData_transform_scale';
|
|
22
22
|
import { getViewBox } from './svg_getViewbox';
|
|
23
23
|
import { pathDataRevertCubicToQuadratic } from './pathData_simplify_revertToquadratics';
|
|
24
24
|
import { pathDataCubicsToArc } from './pathData_simplify_cubicsToArcs';
|
|
25
25
|
import { harmonizeCubicCpts } from './pathData_simplify_harmonize_cpts';
|
|
26
|
-
import {
|
|
26
|
+
import { pathDataToPolygonOpt } from './svgii/pathData_toPolygon';
|
|
27
27
|
import { pathDataLineToCubic } from './svgii/pathData_line_to_cubic';
|
|
28
28
|
import { fixPathDataDirections } from './svgii/pathData_fix_directions';
|
|
29
29
|
import { simplifyPolyChunks, getCurvePathData, simplifyPolygonToPathData } from './svgii/poly_to_pathdata';
|
|
30
30
|
import { pathDataFromPoly } from './svgii/pathData_fromPoly';
|
|
31
|
-
import { normalizePoly } from './svgii/poly_normalize';
|
|
31
|
+
import { normalizePoly, polyPtsToArray } from './svgii/poly_normalize';
|
|
32
32
|
import { simplifyPolyRD } from './simplify_poly_radial_distance';
|
|
33
|
-
import { simplifyPolyRDP } from './simplify_poly_RDP';
|
|
33
|
+
import { simplifyPolyRDP, simplifyPolyRDP__, simplifyRDP_rel } from './simplify_poly_RDP';
|
|
34
|
+
import { getEllipseLengthLG, getLegendreGaussValues, getLength, waArr_global } from './svgii/geometry_length';
|
|
35
|
+
import { deg2rad, dummySVG } from './constants';
|
|
36
|
+
import { getPathDataLength } from './svgii/pathData_getLength';
|
|
37
|
+
import { stringifySVG } from './string_helpers';
|
|
38
|
+
import { presetSettings, settingsDefaults } from './pathSimplify-presets';
|
|
39
|
+
import { splitCompundGroups } from './svgii/pathData_split_to_groups';
|
|
34
40
|
//import { getPolyChunks } from "./svgii/poly_analyze_get_chunks";
|
|
35
41
|
|
|
36
42
|
|
|
37
43
|
//import { installDOMPolyfills } from './dom-polyfill';
|
|
38
44
|
|
|
39
|
-
export function svgPathSimplify(input = '', {
|
|
45
|
+
export function svgPathSimplify(input = '', settings = {}) {
|
|
40
46
|
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
let preset = settings['preset'] !== undefined && settings['preset'] ? settings['preset'] : null;
|
|
48
|
+
let defaults = preset && presetSettings[preset] !== undefined ? presetSettings[preset] : presetSettings['default'];
|
|
43
49
|
|
|
44
|
-
toAbsolute = false,
|
|
45
|
-
toRelative = true,
|
|
46
|
-
toMixed = false,
|
|
47
|
-
toShorthands = true,
|
|
48
|
-
toLonghands = false,
|
|
49
|
-
|
|
50
|
-
//optimize = 0,
|
|
51
|
-
|
|
52
|
-
// not necessary unless you need cubics only
|
|
53
|
-
quadraticToCubic = true,
|
|
54
|
-
|
|
55
|
-
// mostly a fallback if arc calculations fail
|
|
56
|
-
arcToCubic = false,
|
|
57
|
-
cubicToArc = false,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
simplifyBezier = true,
|
|
61
|
-
optimizeOrder = true,
|
|
62
|
-
autoClose = false,
|
|
63
|
-
removeZeroLength = true,
|
|
64
|
-
refineClosing = true,
|
|
65
|
-
removeColinear = true,
|
|
66
|
-
flatBezierToLinetos = true,
|
|
67
|
-
revertToQuadratics = true,
|
|
68
|
-
|
|
69
|
-
refineExtremes = true,
|
|
70
|
-
simplifyCorners = false,
|
|
71
|
-
removeDimensions = false,
|
|
72
|
-
removeIds = false,
|
|
73
|
-
removeClassNames = false,
|
|
74
|
-
omitNamespace = false,
|
|
75
|
-
|
|
76
|
-
fixDirections = false,
|
|
77
|
-
|
|
78
|
-
keepExtremes = true,
|
|
79
|
-
keepCorners = true,
|
|
80
|
-
extrapolateDominant = true,
|
|
81
|
-
keepInflections = false,
|
|
82
|
-
addExtremes = false,
|
|
83
|
-
addSemiExtremes = false,
|
|
84
|
-
|
|
85
|
-
toPolygon = false,
|
|
86
|
-
smoothPoly = false,
|
|
87
|
-
polyFormat = 'points',
|
|
88
|
-
precisionPoly = 1,
|
|
89
|
-
|
|
90
|
-
simplifyRD = 1,
|
|
91
|
-
simplifyRDP = 1,
|
|
92
|
-
|
|
93
|
-
harmonizeCpts = false,
|
|
94
|
-
|
|
95
|
-
removeOrphanSubpaths = false,
|
|
96
|
-
simplifyRound = false,
|
|
97
|
-
|
|
98
|
-
//svg scaling
|
|
99
|
-
scale = 1,
|
|
100
|
-
scaleTo = 0,
|
|
101
|
-
crop = false,
|
|
102
|
-
alignToOrigin = false,
|
|
103
|
-
|
|
104
|
-
// flatten transforms
|
|
105
|
-
convertTransforms = false,
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
//svg path optimizations
|
|
110
|
-
decimals = 3,
|
|
111
|
-
autoAccuracy = true,
|
|
112
|
-
|
|
113
|
-
// experimental
|
|
114
|
-
//roundSub = false,
|
|
115
|
-
|
|
116
|
-
minifyD = 0,
|
|
117
|
-
tolerance = 1,
|
|
118
|
-
reversePath = false,
|
|
119
|
-
|
|
120
|
-
//svg cleanup options
|
|
121
|
-
minifyRgbColors = true,
|
|
122
|
-
removePrologue = true,
|
|
123
|
-
removeHidden = true,
|
|
124
|
-
removeUnused = true,
|
|
125
|
-
cleanupDefs = true,
|
|
126
|
-
cleanupClip = true,
|
|
127
|
-
cleanupSVGAtts = true,
|
|
128
|
-
|
|
129
|
-
stylesToAttributes = false,
|
|
130
|
-
fixHref = false,
|
|
131
|
-
legacyHref = false,
|
|
132
|
-
removeNameSpaced = true,
|
|
133
|
-
|
|
134
|
-
//meta
|
|
135
|
-
allowMeta = false,
|
|
136
|
-
allowDataAtts = true,
|
|
137
|
-
allowAriaAtts = true,
|
|
138
50
|
|
|
51
|
+
// merge settings
|
|
52
|
+
settings = {
|
|
53
|
+
...defaults,
|
|
54
|
+
...settings
|
|
55
|
+
}
|
|
139
56
|
|
|
140
|
-
attributesToGroup = false,
|
|
141
|
-
removeOffCanvas = false,
|
|
142
|
-
unGroup = false,
|
|
143
|
-
mergePaths = false,
|
|
144
57
|
|
|
145
|
-
|
|
146
|
-
shapesToPaths = false,
|
|
58
|
+
let { getObject = false, removeComments, removeOffCanvas, unGroup, mergePaths, removeElements, removeDimensions, removeIds, removeClassNames, omitNamespace, cleanUpStrokes, addViewBox, addDimensions, removePrologue, removeHidden, removeUnused, cleanupDefs, cleanupClip, cleanupSVGAtts, removeNameSpaced, removeNameSpacedAtts, attributesToGroup, minifyRgbColors, stylesToAttributes, fixHref, legacyHref, allowMeta, allowDataAtts, allowAriaAtts, removeSVGAttributes, removeElAttributes, shapesToPaths, shapeConvert, convertShapes, simplifyBezier, optimizeOrder, autoClose, removeZeroLength, refineClosing, removeColinear, flatBezierToLinetos, revertToQuadratics, refineExtremes, simplifyCorners, fixDirections, keepExtremes, keepCorners, keepInflections, addExtremes, reversePath, toAbsolute, toRelative, toMixed, toShorthands, toLonghands, quadraticToCubic, arcToCubic, cubicToArc, lineToCubic, decimals, autoAccuracy, minifyD, tolerance, toPolygon, smoothPoly, polyFormat, precisionPoly, simplifyRD, simplifyRDP, harmonizeCpts, removeOrphanSubpaths, simplifyRound, simplifyQuadraticCorners, scale, scaleTo, crop, alignToOrigin, convertTransforms, keepSmaller, splitCompound, convertPathLength, toAbsoluteUnits } = settings;
|
|
147
59
|
|
|
60
|
+
//toAbsolute = !toRelative;
|
|
148
61
|
|
|
149
|
-
//
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
62
|
+
// clamp tolerance and scale
|
|
63
|
+
tolerance = Math.max(0.1, tolerance);
|
|
64
|
+
scale = Math.max(0.001, scale)
|
|
65
|
+
if (fixDirections) keepSmaller = false;
|
|
66
|
+
if (scale !== 1 || scaleTo || crop || alignToOrigin) {
|
|
67
|
+
convertTransforms = true;
|
|
68
|
+
settings.convertTransforms = true
|
|
69
|
+
}
|
|
155
70
|
|
|
156
71
|
|
|
72
|
+
/**
|
|
73
|
+
* intercept
|
|
74
|
+
* invalid inputs
|
|
75
|
+
*/
|
|
157
76
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
77
|
+
let inputDetection = detectInputType(input);
|
|
78
|
+
let { inputType, log } = inputDetection
|
|
79
|
+
|
|
80
|
+
// invalid file
|
|
81
|
+
if (inputType === 'invalid' || input === dummySVG) {
|
|
82
|
+
// return dummy SVG to continue processing
|
|
83
|
+
//input = dummySVG;
|
|
84
|
+
//inputType = 'invalid';
|
|
85
|
+
|
|
86
|
+
//console.warn(`Input is not valid!\n ${log}`);
|
|
87
|
+
//console.log(input);
|
|
88
|
+
//return false
|
|
89
|
+
|
|
90
|
+
let report = {
|
|
91
|
+
original: 0,
|
|
92
|
+
new: 0,
|
|
93
|
+
saved: 0,
|
|
94
|
+
svgSize:0,
|
|
95
|
+
svgSizeOpt:0,
|
|
96
|
+
compression:0,
|
|
97
|
+
decimals:0,
|
|
98
|
+
invalid:true
|
|
99
|
+
}
|
|
162
100
|
|
|
163
|
-
|
|
101
|
+
return { svg: dummySVG, d: '', polys: [], report, pathDataPlusArr: [], pathDataPlusArr_global: [], inputType: 'invalid', dOriginal: '' };
|
|
164
102
|
|
|
165
|
-
}
|
|
103
|
+
}
|
|
166
104
|
|
|
167
105
|
|
|
168
|
-
// clamp tolerance and scale
|
|
169
|
-
tolerance = Math.max(0.1, tolerance);
|
|
170
|
-
scale = Math.max(0.001, scale)
|
|
171
|
-
|
|
172
|
-
let inputType = detectInputType(input);
|
|
173
106
|
let svg = '';
|
|
174
107
|
let svgSize = 0;
|
|
175
108
|
let svgSizeOpt = 0;
|
|
@@ -181,9 +114,12 @@ export function svgPathSimplify(input = '', {
|
|
|
181
114
|
|
|
182
115
|
// pathdata superset array - containing additional data
|
|
183
116
|
let pathDataPlusArr_global = []
|
|
184
|
-
let paths = []
|
|
185
|
-
let
|
|
117
|
+
let paths = [];
|
|
118
|
+
let isPoly = false;
|
|
119
|
+
let polys = [];
|
|
120
|
+
let poly = [];
|
|
186
121
|
let dStr = '';
|
|
122
|
+
let dOriginal = '';
|
|
187
123
|
|
|
188
124
|
/**
|
|
189
125
|
* normalize input
|
|
@@ -207,29 +143,66 @@ export function svgPathSimplify(input = '', {
|
|
|
207
143
|
arcToCubic = toPolygon ? true : arcToCubic;
|
|
208
144
|
autoClose = false;
|
|
209
145
|
let accuracyArr = []
|
|
210
|
-
|
|
146
|
+
//console.log(inputType);
|
|
147
|
+
|
|
148
|
+
// validate point JSON
|
|
149
|
+
if (inputType === 'json') {
|
|
150
|
+
let pts = [];
|
|
151
|
+
let needsQuotes = /([{,]\s*)(x|y)(\s*:)/.test(input)
|
|
152
|
+
if (needsQuotes) input = input.replaceAll('x:', '"x":').replaceAll('y:', '"y":')
|
|
153
|
+
|
|
154
|
+
try {
|
|
155
|
+
pts = JSON.parse(input)
|
|
156
|
+
} catch {
|
|
157
|
+
console.warn('No valid JSON');
|
|
158
|
+
}
|
|
159
|
+
if (pts.length) {
|
|
160
|
+
inputType = 'polyArray'
|
|
161
|
+
input = normalizePoly(pts);
|
|
162
|
+
isPoly = true;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
211
165
|
|
|
212
166
|
//console.log('inputType', inputType);
|
|
213
167
|
|
|
168
|
+
|
|
214
169
|
// single path or polys
|
|
215
|
-
if (inputType !== 'svgMarkup') {
|
|
170
|
+
if (inputType !== 'svgMarkup' && inputType !== 'symbol') {
|
|
216
171
|
if (inputType === 'pathDataString') {
|
|
217
172
|
d = input
|
|
218
173
|
} else if (inputType === 'polyString') {
|
|
219
|
-
|
|
174
|
+
splitCompound = false;
|
|
175
|
+
isPoly = true;
|
|
176
|
+
poly = normalizePoly(input)
|
|
177
|
+
d = pathDataFromPoly(poly, closed)
|
|
178
|
+
//console.log(poly);
|
|
179
|
+
|
|
220
180
|
}
|
|
221
181
|
|
|
222
182
|
else if (inputType === 'polyArray' || inputType === 'polyObjectArray' || inputType === 'polyComplexArray' || inputType === 'polyComplexObjectArray') {
|
|
183
|
+
splitCompound = false;
|
|
223
184
|
|
|
224
185
|
// normalize poly input to object array
|
|
225
|
-
|
|
186
|
+
poly = normalizePoly(input)
|
|
226
187
|
|
|
227
188
|
// convert to pathdata
|
|
228
|
-
|
|
189
|
+
let closed = true;
|
|
190
|
+
|
|
191
|
+
isPoly = true;
|
|
192
|
+
//polys.push(poly)
|
|
229
193
|
|
|
230
194
|
// calculate size
|
|
195
|
+
d = pathDataFromPoly(poly, closed)
|
|
231
196
|
dStr = d.map(com => { return `${com.type} ${com.values.join(' ')}` }).join(' ');
|
|
197
|
+
dOriginal = dStr;
|
|
232
198
|
svgSize = dStr.length;
|
|
199
|
+
|
|
200
|
+
/*
|
|
201
|
+
d=''
|
|
202
|
+
dOriginal = '';
|
|
203
|
+
svgSize = input.length;
|
|
204
|
+
*/
|
|
205
|
+
|
|
233
206
|
}
|
|
234
207
|
|
|
235
208
|
else if (inputType === 'pathData') {
|
|
@@ -238,6 +211,12 @@ export function svgPathSimplify(input = '', {
|
|
|
238
211
|
// stringify to compare lengths
|
|
239
212
|
dStr = Array.from(d).map(com => { return `${com.type} ${com.values.join(' ')}` }).join(' ');
|
|
240
213
|
svgSize = dStr.length;
|
|
214
|
+
isPoly = false;
|
|
215
|
+
|
|
216
|
+
}
|
|
217
|
+
// not valid - set dummy path data
|
|
218
|
+
else {
|
|
219
|
+
d = 'M0 0 h0'
|
|
241
220
|
}
|
|
242
221
|
|
|
243
222
|
paths.push({ d, el: null })
|
|
@@ -246,40 +225,45 @@ export function svgPathSimplify(input = '', {
|
|
|
246
225
|
// mode:1 – process complete svg DOM
|
|
247
226
|
else {
|
|
248
227
|
|
|
228
|
+
|
|
229
|
+
// convert symbol temporarily to SVG
|
|
230
|
+
if (inputType === 'symbol') {
|
|
231
|
+
input = input.replaceAll('<symbol', '<svg').replaceAll('</symbol', '</svg')
|
|
232
|
+
// ids are mandatory for symbols
|
|
233
|
+
removeIds = false
|
|
234
|
+
removeDimensions = true
|
|
235
|
+
}
|
|
236
|
+
|
|
249
237
|
// convert all shapes to paths
|
|
250
238
|
if (shapesToPaths) {
|
|
251
239
|
shapeConvert = 'toPaths'
|
|
252
|
-
|
|
253
|
-
convert_ellipses = true
|
|
254
|
-
convert_poly = true
|
|
255
|
-
convert_lines = true
|
|
240
|
+
convertShapes = ['rect', 'polygon', 'polyline', 'line', 'circle', 'ellipse']
|
|
256
241
|
}
|
|
257
242
|
|
|
258
243
|
//console.log('shapesToPaths', shapesToPaths, 'shapeConvert', shapeConvert, convert_rects, convert_ellipses, convert_poly);
|
|
259
244
|
|
|
260
|
-
//sanitize
|
|
261
|
-
let svgPropObject = cleanUpSVG(input,
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
}
|
|
266
|
-
);
|
|
245
|
+
// sanitize SVG - clone/decouple settings
|
|
246
|
+
let svgPropObject = cleanUpSVG(input, JSON.parse(JSON.stringify(settings)));
|
|
247
|
+
|
|
248
|
+
//console.log('settings', settings);
|
|
249
|
+
//console.log('svgPropObject', svgPropObject);
|
|
267
250
|
|
|
268
251
|
let { svgElProps } = svgPropObject
|
|
269
252
|
svg = svgPropObject.svg;
|
|
270
|
-
|
|
253
|
+
//console.log(svgPropObject);
|
|
271
254
|
|
|
272
255
|
|
|
273
256
|
// collect paths
|
|
274
257
|
let pathEls = svg.querySelectorAll('path')
|
|
275
258
|
//let pathEls2 = svg.getElementsByTagName('path')
|
|
276
|
-
//console.log(
|
|
259
|
+
//console.log(pathEls);
|
|
277
260
|
|
|
278
261
|
pathEls.forEach((path, i) => {
|
|
279
|
-
|
|
262
|
+
let d = path.getAttribute('d');
|
|
263
|
+
//console.log(d, path.nodeName, path.id);
|
|
264
|
+
paths.push({ d, el: path, idx: i })
|
|
280
265
|
})
|
|
281
266
|
|
|
282
|
-
|
|
283
267
|
// get viewBox/dimensions
|
|
284
268
|
viewBox = getViewBox(svg, decimals)
|
|
285
269
|
|
|
@@ -296,14 +280,13 @@ export function svgPathSimplify(input = '', {
|
|
|
296
280
|
let pathOptions = {
|
|
297
281
|
toRelative,
|
|
298
282
|
toMixed,
|
|
299
|
-
toAbsolute,
|
|
300
|
-
toLonghands,
|
|
301
283
|
toShorthands,
|
|
302
284
|
decimals,
|
|
303
285
|
}
|
|
286
|
+
//console.log('pathOptions', pathOptions);
|
|
304
287
|
|
|
305
|
-
|
|
306
|
-
let
|
|
288
|
+
let comCount = 0
|
|
289
|
+
let comCountS = 0
|
|
307
290
|
|
|
308
291
|
|
|
309
292
|
for (let i = 0, l = paths.length; l && i < l; i++) {
|
|
@@ -312,10 +295,14 @@ export function svgPathSimplify(input = '', {
|
|
|
312
295
|
let path = paths[i];
|
|
313
296
|
let { d, el } = path;
|
|
314
297
|
let dN = ''
|
|
298
|
+
let isPoly = false;
|
|
315
299
|
|
|
316
|
-
|
|
300
|
+
// if polygon we already heave absolute coordinates
|
|
301
|
+
//let isPolyPath = !mode && isPoly && Array.isArray(d)
|
|
302
|
+
//let pathData = !isPolyPath ? parsePathDataNormalized(d, { quadraticToCubic, arcToCubic }) : d;
|
|
317
303
|
let pathData = parsePathDataNormalized(d, { quadraticToCubic, arcToCubic });
|
|
318
304
|
//console.log('!!!pathData', pathData, arcToCubic);
|
|
305
|
+
//console.log(isPoly);
|
|
319
306
|
|
|
320
307
|
// get polygon bbox
|
|
321
308
|
let bb_poly = smoothPoly || toPolygon ? getPolyBBox(getPathDataVertices(pathData)) : null
|
|
@@ -352,9 +339,10 @@ export function svgPathSimplify(input = '', {
|
|
|
352
339
|
}
|
|
353
340
|
|
|
354
341
|
// count commands for evaluation
|
|
355
|
-
|
|
342
|
+
comCount += pathData.length
|
|
343
|
+
|
|
344
|
+
if (!isPoly && removeOrphanSubpaths) pathData = removeOrphanedM(pathData);
|
|
356
345
|
|
|
357
|
-
if (removeOrphanSubpaths) pathData = removeOrphanedM(pathData);
|
|
358
346
|
|
|
359
347
|
|
|
360
348
|
/**
|
|
@@ -362,7 +350,6 @@ export function svgPathSimplify(input = '', {
|
|
|
362
350
|
*/
|
|
363
351
|
let subPathArr = splitSubpaths(pathData);
|
|
364
352
|
let lenSub = subPathArr.length;
|
|
365
|
-
|
|
366
353
|
//console.log('subPathArr', subPathArr);
|
|
367
354
|
|
|
368
355
|
|
|
@@ -372,27 +359,29 @@ export function svgPathSimplify(input = '', {
|
|
|
372
359
|
//let { pathData, bb } = subPathArr[i];
|
|
373
360
|
let pathDataSub = subPathArr[i];
|
|
374
361
|
let poly = []
|
|
375
|
-
|
|
376
362
|
let coms = Array.from(new Set(pathDataSub.map(com => com.type))).join('')
|
|
377
|
-
|
|
378
|
-
let closed =
|
|
363
|
+
isPoly = !(/[acqts]/gi).test(coms)
|
|
364
|
+
let closed = isPoly ? true : false;
|
|
379
365
|
|
|
380
|
-
if (isPoly) {
|
|
366
|
+
if (isPoly && !mode) {
|
|
381
367
|
|
|
382
368
|
poly = getPathDataVertices(pathDataSub);
|
|
383
|
-
|
|
369
|
+
let bb = getPolyBBox(reducePoints(poly, 64))
|
|
370
|
+
//console.log(poly, bb);
|
|
384
371
|
|
|
385
372
|
// simplify polygon
|
|
386
373
|
if (simplifyRD > 0) {
|
|
387
|
-
poly = simplifyPolyRD(poly, { quality: simplifyRD
|
|
374
|
+
poly = simplifyPolyRD(poly, { quality: simplifyRD, width: bb.width, height: bb.height })
|
|
388
375
|
}
|
|
389
376
|
|
|
390
377
|
if (simplifyRDP > 0) {
|
|
391
|
-
poly = simplifyPolyRDP(poly, { quality: simplifyRDP
|
|
378
|
+
poly = simplifyPolyRDP(poly, { quality: simplifyRDP, width: bb.width, height: bb.height })
|
|
379
|
+
//poly = simplifyRDP_rel(poly, simplifyRDP, bb.width, bb.height)
|
|
392
380
|
}
|
|
393
381
|
|
|
382
|
+
toPolygon = false;
|
|
394
383
|
pathDataSub = pathDataFromPoly(poly, closed)
|
|
395
|
-
|
|
384
|
+
//pathDataSub[0].bb = bb
|
|
396
385
|
}
|
|
397
386
|
|
|
398
387
|
|
|
@@ -405,33 +394,25 @@ export function svgPathSimplify(input = '', {
|
|
|
405
394
|
smoothPoly = false;
|
|
406
395
|
harmonizeCpts = false;
|
|
407
396
|
|
|
408
|
-
|
|
409
|
-
//console.log(pathDataSub);
|
|
410
|
-
|
|
411
|
-
let pathDataSubPlus = analyzePathData(pathDataSub)
|
|
412
|
-
let { bb, pathData } = pathDataSubPlus;
|
|
413
|
-
pathDataSub = pathData;
|
|
414
|
-
|
|
397
|
+
pathDataSub = getPathDataVerbose(pathDataSub);
|
|
415
398
|
|
|
416
|
-
let polyData =
|
|
399
|
+
let polyData = pathDataToPolygonOpt(pathDataSub, {
|
|
417
400
|
precisionPoly,
|
|
418
401
|
autoAccuracy,
|
|
419
|
-
polyFormat,
|
|
420
|
-
decimals,
|
|
402
|
+
//polyFormat,
|
|
403
|
+
//decimals,
|
|
421
404
|
simplifyRD,
|
|
422
405
|
simplifyRDP
|
|
423
406
|
})
|
|
424
407
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
//poly.push(polyData.poly)
|
|
428
|
-
polys.push(polyData.poly)
|
|
408
|
+
//console.log('toPolygon');
|
|
409
|
+
//polys.push(polyData.poly)
|
|
429
410
|
pathDataSub = polyData.pathData
|
|
411
|
+
isPoly = true;
|
|
430
412
|
|
|
431
413
|
}
|
|
432
414
|
|
|
433
415
|
|
|
434
|
-
|
|
435
416
|
/**
|
|
436
417
|
* poly to beziers via
|
|
437
418
|
* Philip J. Schneider's
|
|
@@ -459,21 +440,22 @@ export function svgPathSimplify(input = '', {
|
|
|
459
440
|
simplifyRD,
|
|
460
441
|
simplifyRDP,
|
|
461
442
|
}
|
|
443
|
+
|
|
444
|
+
//console.log('smooth');
|
|
462
445
|
pathDataSub = simplifyPolygonToPathData(poly, optionsPoly)
|
|
446
|
+
// flag as non poly as we're smoothing to curves
|
|
447
|
+
//isPoly = false
|
|
463
448
|
}
|
|
464
449
|
}
|
|
465
450
|
|
|
466
451
|
|
|
467
|
-
|
|
468
452
|
// harmonize cpts
|
|
469
453
|
// if (harmonizeCpts) pathDataSub = harmonizeCubicCpts(pathDataSub)
|
|
470
454
|
|
|
471
|
-
|
|
472
455
|
// remove zero length linetos
|
|
473
456
|
if (removeColinear || removeZeroLength) pathDataSub = removeZeroLengthLinetos(pathDataSub)
|
|
474
457
|
|
|
475
458
|
|
|
476
|
-
|
|
477
459
|
// sort to top left
|
|
478
460
|
if (optimizeOrder) pathDataSub = pathDataToTopLeft(pathDataSub);
|
|
479
461
|
|
|
@@ -482,8 +464,8 @@ export function svgPathSimplify(input = '', {
|
|
|
482
464
|
if (removeColinear) pathDataSub = pathDataRemoveColinear(pathDataSub, { tolerance, flatBezierToLinetos: false });
|
|
483
465
|
|
|
484
466
|
let tMin = 0, tMax = 1;
|
|
485
|
-
if (addExtremes
|
|
486
|
-
{ tMin, tMax, addExtremes,
|
|
467
|
+
if (addExtremes) pathDataSub = addExtremePoints(pathDataSub,
|
|
468
|
+
{ tMin, tMax, addExtremes, angles: [30] })
|
|
487
469
|
|
|
488
470
|
|
|
489
471
|
|
|
@@ -492,23 +474,38 @@ export function svgPathSimplify(input = '', {
|
|
|
492
474
|
pathDataSub = reversePathData(pathDataSub)
|
|
493
475
|
}
|
|
494
476
|
|
|
477
|
+
// analyze pathdata to add info about significant properties such as extremes, corners
|
|
478
|
+
let pathDataPlus = { bb: {}, dimA: 0, pathData: [] }
|
|
479
|
+
|
|
480
|
+
if (!isPoly) {
|
|
481
|
+
pathDataPlus = analyzePathData(pathDataSub);
|
|
482
|
+
}
|
|
483
|
+
// we skip detailed analysis for native polygons
|
|
484
|
+
else {
|
|
485
|
+
if (!poly.length) {
|
|
486
|
+
let pathDataCubic = convertPathData(JSON.parse(JSON.stringify(pathDataSub)), { toLonghands: true, toAbsolute: true, arcToCubic: true, testTypes: true })
|
|
487
|
+
pathDataPlus.bb = getPolyBBox(getPathDataVertices(pathDataCubic))
|
|
488
|
+
}
|
|
489
|
+
pathDataPlus.dimA = pathDataPlus.bb.width + pathDataPlus.bb.height;
|
|
490
|
+
pathDataPlus.pathData = getPathDataVerbose(pathDataSub, {
|
|
491
|
+
addSquareLength: false,
|
|
492
|
+
addArea: false,
|
|
493
|
+
addAverageDim: false
|
|
494
|
+
})
|
|
495
|
+
}
|
|
495
496
|
|
|
496
|
-
// analyze pathdata to add info about signicant properties such as extremes, corners
|
|
497
|
-
let pathDataPlus = analyzePathData(pathDataSub, {
|
|
498
|
-
detectSemiExtremes: addSemiExtremes,
|
|
499
|
-
});
|
|
500
497
|
|
|
501
498
|
|
|
502
499
|
// simplify beziers
|
|
503
500
|
let { pathData, bb, dimA } = pathDataPlus;
|
|
501
|
+
|
|
504
502
|
xArr.push(bb.x, bb.x + bb.width)
|
|
505
503
|
yArr.push(bb.y, bb.y + bb.height)
|
|
506
504
|
|
|
507
505
|
|
|
508
506
|
if (refineClosing) pathData = refineClosingCommand(pathData, { threshold: dimA * 0.001 })
|
|
509
507
|
|
|
510
|
-
|
|
511
|
-
pathData = simplifyBezier ? simplifyPathDataCubic(pathData, { simplifyBezier, keepInflections, keepExtremes, keepCorners, extrapolateDominant, revertToQuadratics, tolerance }) : pathData;
|
|
508
|
+
pathData = simplifyBezier ? simplifyPathDataCubic(pathData, { simplifyBezier, keepInflections, keepExtremes, keepCorners, revertToQuadratics, tolerance }) : pathData;
|
|
512
509
|
|
|
513
510
|
|
|
514
511
|
// refine extremes
|
|
@@ -533,12 +530,14 @@ export function svgPathSimplify(input = '', {
|
|
|
533
530
|
//pathData = removeZeroLengthLinetos(pathData);
|
|
534
531
|
|
|
535
532
|
let threshold = (bb.width + bb.height) * 0.1
|
|
536
|
-
pathData = refineRoundedCorners(pathData, { threshold, tolerance })
|
|
533
|
+
pathData = refineRoundedCorners(pathData, { threshold, tolerance, simplifyQuadraticCorners })
|
|
537
534
|
}
|
|
538
535
|
|
|
539
536
|
// refine round segment sequences
|
|
540
|
-
if (simplifyRound)
|
|
541
|
-
|
|
537
|
+
if (simplifyRound) {
|
|
538
|
+
pathData = refineRoundSegments(pathData);
|
|
539
|
+
pathData = simplifyAdjacentRound(pathData);
|
|
540
|
+
}
|
|
542
541
|
|
|
543
542
|
// simplify to quadratics
|
|
544
543
|
if (revertToQuadratics) pathData = pathDataRevertCubicToQuadratic(pathData, tolerance);
|
|
@@ -555,10 +554,6 @@ export function svgPathSimplify(input = '', {
|
|
|
555
554
|
//let decimalsSub = Math.max(2, detectAccuracy(pathData));
|
|
556
555
|
let decimalsSub = detectAccuracy(pathData);
|
|
557
556
|
accuracyArr.push(decimalsSub);
|
|
558
|
-
//let decimalsSub = detectAccuracy(pathData);
|
|
559
|
-
|
|
560
|
-
// pre round sub path
|
|
561
|
-
//if(roundSub) pathData = roundPathData(pathData, decimalsSub);
|
|
562
557
|
|
|
563
558
|
}
|
|
564
559
|
|
|
@@ -567,6 +562,7 @@ export function svgPathSimplify(input = '', {
|
|
|
567
562
|
|
|
568
563
|
} // end sup paths
|
|
569
564
|
|
|
565
|
+
|
|
570
566
|
// sort subpaths to top left
|
|
571
567
|
let xMin = Math.min(...xArr)
|
|
572
568
|
let yMin = Math.min(...yArr)
|
|
@@ -580,23 +576,42 @@ export function svgPathSimplify(input = '', {
|
|
|
580
576
|
//console.log(i, pathDataPlusArr);
|
|
581
577
|
|
|
582
578
|
|
|
579
|
+
// fix path directions - before reordering
|
|
580
|
+
if (fixDirections) {
|
|
581
|
+
pathDataPlusArr = fixPathDataDirections(pathDataPlusArr);
|
|
582
|
+
}
|
|
583
|
+
|
|
583
584
|
|
|
584
585
|
// prefer top to bottom priority for portrait aspect ratios
|
|
585
586
|
if (optimizeOrder) {
|
|
587
|
+
/*
|
|
586
588
|
pathDataPlusArr = isPortrait ? pathDataPlusArr.sort((a, b) => a.bb.y - b.bb.y || a.bb.x - b.bb.x) : pathDataPlusArr.sort((a, b) => a.bb.x - b.bb.x || a.bb.y - b.bb.y)
|
|
587
|
-
|
|
589
|
+
*/
|
|
590
|
+
|
|
591
|
+
// add missin bbox
|
|
592
|
+
pathDataPlusArr.forEach(p => {
|
|
593
|
+
if (p.bb.x === undefined) {
|
|
594
|
+
p.bb = getPolyBBox(getPathDataVertices(p.pathData))
|
|
595
|
+
}
|
|
596
|
+
})
|
|
597
|
+
|
|
598
|
+
try {
|
|
599
|
+
pathDataPlusArr = pathDataPlusArr.sort((a, b) => +a.bb.x.toFixed(2) - (+b.bb.x.toFixed(2)) || a.bb.y - b.bb.y);
|
|
600
|
+
//console.log(pathDataPlusArr);
|
|
601
|
+
|
|
602
|
+
} catch {
|
|
603
|
+
}
|
|
588
604
|
|
|
589
605
|
|
|
590
|
-
// fix path directions
|
|
591
|
-
if (fixDirections) {
|
|
592
|
-
pathDataPlusArr = fixPathDataDirections(pathDataPlusArr);
|
|
593
606
|
}
|
|
594
607
|
|
|
595
608
|
|
|
596
609
|
|
|
610
|
+
|
|
597
611
|
// flatten compound paths
|
|
598
612
|
pathData = [];
|
|
599
613
|
|
|
614
|
+
|
|
600
615
|
// add to global array - including multiple path elements
|
|
601
616
|
pathDataPlusArr_global.push(pathDataPlusArr);
|
|
602
617
|
|
|
@@ -614,99 +629,88 @@ export function svgPathSimplify(input = '', {
|
|
|
614
629
|
pathOptions.decimals = decimals
|
|
615
630
|
}
|
|
616
631
|
|
|
632
|
+
// add simplified poly - if not populated by toPoly conversion
|
|
633
|
+
if (isPoly) {
|
|
634
|
+
//console.log('5. isPoly', isPoly);
|
|
635
|
+
|
|
636
|
+
pathDataPlusArr.forEach(sub => {
|
|
637
|
+
let poly = getPathDataVertices(sub.pathData, false, decimals)
|
|
638
|
+
if (polyFormat === 'array') {
|
|
639
|
+
poly = polyPtsToArray(poly)
|
|
640
|
+
}
|
|
641
|
+
polys.push(poly)
|
|
642
|
+
})
|
|
617
643
|
|
|
618
|
-
// collect for merged svg paths
|
|
619
|
-
mergePaths = false
|
|
620
|
-
if (el && mergePaths) {
|
|
621
|
-
pathData_merged.push(...pathData)
|
|
622
644
|
}
|
|
623
|
-
// single output
|
|
624
|
-
else {
|
|
625
645
|
|
|
626
|
-
// clone pathdata
|
|
627
|
-
//pathData = pathData.map(com => ({ type: com.type, values: [...com.values] }));
|
|
628
|
-
pathData = JSON.parse(JSON.stringify(pathData));
|
|
629
646
|
|
|
630
|
-
|
|
631
|
-
|
|
647
|
+
// split into sub paths - returns svg with multiple paths
|
|
648
|
+
if (splitCompound && !mode && pathDataPlusArr.length > 1) {
|
|
649
|
+
let pathDataSplit = splitCompundGroups(pathDataPlusArr, { toRelative, toShorthands, decimals, addDimensions });
|
|
650
|
+
svg = new DOMParser().parseFromString(pathDataSplit.svg, 'image/svg+xml').querySelector('svg');
|
|
651
|
+
// switch output type
|
|
652
|
+
mode = 1;
|
|
653
|
+
inputType = 'splitPath'
|
|
654
|
+
}
|
|
632
655
|
|
|
633
|
-
// remove zero-length segments introduced by rounding
|
|
634
|
-
if (removeZeroLength) pathData = removeZeroLengthLinetos(pathData);
|
|
635
656
|
|
|
636
|
-
|
|
637
|
-
|
|
657
|
+
// clone pathdata
|
|
658
|
+
pathData = JSON.parse(JSON.stringify(pathData));
|
|
638
659
|
|
|
639
|
-
|
|
640
|
-
|
|
660
|
+
// optimize path data
|
|
661
|
+
pathData = convertPathData(pathData, pathOptions)
|
|
641
662
|
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
}
|
|
663
|
+
// remove zero-length segments introduced by rounding
|
|
664
|
+
if (removeZeroLength) pathData = removeZeroLengthLinetos(pathData);
|
|
645
665
|
|
|
666
|
+
// realign path to zero origin
|
|
667
|
+
if (alignToOrigin) {
|
|
646
668
|
|
|
647
|
-
|
|
648
|
-
|
|
669
|
+
pathData[0].values[0] = roundTo((pathData[0].values[0] - bb_global.x), decimals)
|
|
670
|
+
pathData[0].values[1] = roundTo((pathData[0].values[1] - bb_global.y), decimals)
|
|
649
671
|
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
672
|
+
bb_global.x = 0
|
|
673
|
+
bb_global.y = 0
|
|
674
|
+
}
|
|
653
675
|
|
|
654
|
-
compression = +(100 / svgSize * (svgSizeOpt)).toFixed(2)
|
|
655
676
|
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
original: comCount,
|
|
659
|
-
new: comCountS,
|
|
660
|
-
saved: comCount - comCountS,
|
|
661
|
-
compression,
|
|
662
|
-
decimals,
|
|
663
|
-
//success: comCountS < comCount
|
|
664
|
-
}
|
|
677
|
+
// compare command count
|
|
678
|
+
comCountS += pathData.length
|
|
665
679
|
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
680
|
+
let dOpt = pathDataToD(pathData, minifyD)
|
|
681
|
+
//svgSizeOpt = new Blob([dOpt]).size;
|
|
682
|
+
svgSizeOpt = dOpt.length
|
|
683
|
+
|
|
684
|
+
compression = +(100 / svgSize * (svgSizeOpt)).toFixed(2)
|
|
685
|
+
|
|
686
|
+
path.d = dOpt
|
|
687
|
+
path.report = {
|
|
688
|
+
original: comCount,
|
|
689
|
+
new: comCountS,
|
|
690
|
+
saved: comCount - comCountS,
|
|
691
|
+
compression,
|
|
692
|
+
decimals,
|
|
693
|
+
//success: comCountS < comCount
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
// apply new path for svgs
|
|
697
|
+
if (el) {
|
|
698
|
+
el.setAttribute('d', dOpt)
|
|
671
699
|
}
|
|
672
700
|
|
|
701
|
+
|
|
673
702
|
} // end path array
|
|
674
703
|
|
|
675
704
|
/**
|
|
676
705
|
* stringify new SVG
|
|
677
706
|
*/
|
|
678
|
-
if (mode) {
|
|
679
|
-
|
|
680
|
-
//console.log(pathData_merged);
|
|
681
|
-
if (pathData_merged.length) {
|
|
682
|
-
|
|
683
|
-
// optimize path data
|
|
684
|
-
let pathData = convertPathData(pathData_merged, pathOptions)
|
|
685
|
-
|
|
686
|
-
// remove zero-length segments introduced by rounding
|
|
687
|
-
pathData = removeZeroLengthLinetos(pathData);
|
|
688
|
-
|
|
689
|
-
let dOpt = pathDataToD(pathData, minifyD)
|
|
707
|
+
if (mode || inputType === 'symbol') {
|
|
690
708
|
|
|
691
|
-
|
|
692
|
-
paths[0].el.setAttribute('d', dOpt)
|
|
693
|
-
|
|
694
|
-
// remove other paths
|
|
695
|
-
for (let i = 1; i < paths.length; i++) {
|
|
696
|
-
let pathEl = paths[i].el
|
|
697
|
-
if (pathEl) pathEl.remove()
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
// remove empty groups e.g groups
|
|
701
|
-
removeEmptySVGEls(svg);
|
|
702
|
-
}
|
|
709
|
+
//console.log('process', inputType);
|
|
703
710
|
|
|
704
711
|
// adjust viewBox and width for scale
|
|
705
712
|
if (scale) {
|
|
706
|
-
|
|
707
713
|
let { x, y, width, height, w, h, hasViewBox, hasWidth, hasHeight, widthUnit, heightUnit } = viewBox;
|
|
708
|
-
//console.log('bb_global', bb_global);
|
|
709
|
-
|
|
710
714
|
if (crop) {
|
|
711
715
|
x = bb_global.x
|
|
712
716
|
y = bb_global.y
|
|
@@ -717,14 +721,14 @@ export function svgPathSimplify(input = '', {
|
|
|
717
721
|
}
|
|
718
722
|
|
|
719
723
|
if (hasViewBox) {
|
|
720
|
-
svg.setAttribute('viewBox', [x, y, width, height].map(val =>
|
|
724
|
+
svg.setAttribute('viewBox', [x, y, width, height].map(val => roundTo(val * scale, decimals)).join(' '))
|
|
721
725
|
}
|
|
722
726
|
if (hasWidth) {
|
|
723
|
-
svg.setAttribute('width',
|
|
727
|
+
svg.setAttribute('width', roundTo(w * scale, decimals) + widthUnit)
|
|
724
728
|
}
|
|
725
729
|
|
|
726
730
|
if (hasHeight) {
|
|
727
|
-
svg.setAttribute('height',
|
|
731
|
+
svg.setAttribute('height', roundTo(h * scale, decimals) + heightUnit)
|
|
728
732
|
}
|
|
729
733
|
}
|
|
730
734
|
|
|
@@ -737,9 +741,12 @@ export function svgPathSimplify(input = '', {
|
|
|
737
741
|
})
|
|
738
742
|
}
|
|
739
743
|
|
|
744
|
+
//console.log(svg);
|
|
745
|
+
if (removeSVGAttributes.includes('xmlns')) omitNamespace = true;
|
|
740
746
|
|
|
741
|
-
svg = stringifySVG(svg, { omitNamespace, removeComments });
|
|
742
747
|
|
|
748
|
+
svg = stringifySVG(svg, { omitNamespace, removeComments, format: minifyD });
|
|
749
|
+
//console.log('!!!svg', svg);
|
|
743
750
|
|
|
744
751
|
//svgSizeOpt = new Blob([svg]).size
|
|
745
752
|
svgSizeOpt = svg.length;
|
|
@@ -749,13 +756,25 @@ export function svgPathSimplify(input = '', {
|
|
|
749
756
|
svgSize = +(svgSize / 1024).toFixed(3)
|
|
750
757
|
svgSizeOpt = +(svgSizeOpt / 1024).toFixed(3)
|
|
751
758
|
|
|
759
|
+
|
|
752
760
|
report = {
|
|
761
|
+
original: comCount,
|
|
762
|
+
new: comCountS,
|
|
763
|
+
saved: comCount - comCountS,
|
|
753
764
|
svgSize,
|
|
754
765
|
svgSizeOpt,
|
|
755
766
|
compression,
|
|
756
|
-
decimals
|
|
767
|
+
decimals,
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
if (keepSmaller && svgSize < svgSizeOpt && !splitCompound) {
|
|
771
|
+
//console.log('Original is smaller!');
|
|
772
|
+
svg = input
|
|
773
|
+
report.node = 'Original is smaller!'
|
|
757
774
|
}
|
|
758
775
|
|
|
776
|
+
|
|
777
|
+
|
|
759
778
|
} else {
|
|
760
779
|
({ d, report } = paths[0]);
|
|
761
780
|
}
|
|
@@ -764,7 +783,16 @@ export function svgPathSimplify(input = '', {
|
|
|
764
783
|
polys = polys[0]
|
|
765
784
|
}
|
|
766
785
|
|
|
767
|
-
|
|
786
|
+
|
|
787
|
+
//console.log('---simplify', input);
|
|
788
|
+
//console.log('5. svg', svg);
|
|
789
|
+
|
|
790
|
+
if (polyFormat === 'string' && polys.length) {
|
|
791
|
+
polys = polys.flat().map(pt => `${pt.x},${pt.y}`).join(' ')
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
|
|
795
|
+
return !getObject ? (d ? d : svg) : { svg, d, polys, report, pathDataPlusArr: pathDataPlusArr_global, inputType, dOriginal };
|
|
768
796
|
|
|
769
797
|
}
|
|
770
798
|
|