svg-path-simplify 0.4.3 → 0.4.5
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 +2 -1
- package/dist/svg-path-simplify.esm.js +1670 -509
- package/dist/svg-path-simplify.esm.min.js +2 -2
- package/dist/svg-path-simplify.js +1671 -508
- package/dist/svg-path-simplify.min.js +2 -2
- package/dist/svg-path-simplify.pathdata.esm.js +936 -463
- package/dist/svg-path-simplify.pathdata.esm.min.js +2 -2
- package/dist/svg-path-simplify.poly.cjs +9 -8
- package/index.html +60 -20
- package/package.json +1 -1
- package/src/constants.js +4 -0
- package/src/detect_input.js +47 -29
- package/src/index.js +8 -0
- package/src/pathData_simplify_cubic.js +46 -18
- package/src/pathData_simplify_revertToquadratics.js +0 -1
- package/src/pathSimplify-main.js +81 -20
- package/src/pathSimplify-only-pathdata.js +7 -2
- package/src/pathSimplify-presets.js +14 -4
- package/src/svg-getAttributes.js +5 -3
- package/src/svgii/convert_units.js +1 -1
- package/src/svgii/geometry.js +140 -2
- package/src/svgii/geometry_bbox_element.js +1 -1
- package/src/svgii/geometry_deduceRadius.js +116 -27
- package/src/svgii/geometry_length.js +18 -2
- package/src/svgii/pathData_analyze.js +18 -0
- package/src/svgii/pathData_convert.js +188 -88
- package/src/svgii/pathData_fix_directions.js +10 -18
- package/src/svgii/pathData_reorder.js +123 -16
- package/src/svgii/pathData_simplify_refineCorners.js +130 -35
- package/src/svgii/pathData_simplify_refine_round.js +420 -0
- package/src/svgii/poly_normalize.js +9 -8
- package/src/svgii/rounding.js +112 -80
- package/src/svgii/svg_cleanup.js +75 -22
- package/src/svgii/svg_cleanup_convertPathLength.js +27 -15
- package/src/svgii/svg_cleanup_normalize_transforms.js +1 -1
- package/src/svgii/svg_cleanup_remove_els_and_atts.js +6 -1
- package/src/svgii/svg_el_parse_style_props.js +13 -10
- package/src/svgii/svg_validate.js +220 -0
- package/tests/testSVG.js +14 -1
- package/src/svgii/pathData_refine_round.js +0 -222
|
@@ -5,7 +5,7 @@ export function normalizePoly(pts, {
|
|
|
5
5
|
} = {}) {
|
|
6
6
|
|
|
7
7
|
// is stringified flat point attribute
|
|
8
|
-
if(typeof pts === 'string' && !isNaN(pts[0])){
|
|
8
|
+
if (typeof pts === 'string' && !isNaN(pts[0])) {
|
|
9
9
|
pts = toPointArray(pts.split(/,| /).filter(Boolean).map(Number));
|
|
10
10
|
return pts
|
|
11
11
|
}
|
|
@@ -16,8 +16,9 @@ export function normalizePoly(pts, {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
export function polyArrayToObject(pts) {
|
|
20
|
-
|
|
19
|
+
export function polyArrayToObject(pts = []) {
|
|
20
|
+
//console.log(pts);
|
|
21
|
+
if (!pts.length) return [];
|
|
21
22
|
// is point object array
|
|
22
23
|
if (pts[0].x !== undefined && pts[0].y !== undefined) return pts
|
|
23
24
|
|
|
@@ -35,7 +36,7 @@ export function polyArrayToObject(pts) {
|
|
|
35
36
|
return poly
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
else if(pts.length>3){
|
|
39
|
+
else if (pts.length > 3) {
|
|
39
40
|
pts = toPointArray(pts)
|
|
40
41
|
return pts
|
|
41
42
|
}
|
|
@@ -65,13 +66,13 @@ export function polyPtsToArray(pts) {
|
|
|
65
66
|
export function toPointArray(pts) {
|
|
66
67
|
let ptArr = [];
|
|
67
68
|
|
|
68
|
-
if(pts[0].length===2){
|
|
69
|
-
for (let i = 0, l = pts.length; i < l; i
|
|
69
|
+
if (pts[0].length === 2) {
|
|
70
|
+
for (let i = 0, l = pts.length; i < l; i++) {
|
|
70
71
|
let pt = pts[i]
|
|
71
|
-
ptArr.push({ x: pt[0], y:pt[1] });
|
|
72
|
+
ptArr.push({ x: pt[0], y: pt[1] });
|
|
72
73
|
}
|
|
73
74
|
|
|
74
|
-
}else{
|
|
75
|
+
} else {
|
|
75
76
|
for (let i = 1, l = pts.length; i < l; i += 2) {
|
|
76
77
|
ptArr.push({ x: pts[i - 1], y: pts[i] });
|
|
77
78
|
}
|
package/src/svgii/rounding.js
CHANGED
|
@@ -8,6 +8,42 @@ import { getDistAv, getDistManhattan } from "./geometry";
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* round path data
|
|
13
|
+
* either by explicit decimal value or
|
|
14
|
+
* based on suggested accuracy in path data
|
|
15
|
+
*/
|
|
16
|
+
export function roundPathData(pathData, decimalsGlobal = -1) {
|
|
17
|
+
|
|
18
|
+
if (decimalsGlobal < 0) return pathData;
|
|
19
|
+
|
|
20
|
+
let len = pathData.length;
|
|
21
|
+
let decimals = decimalsGlobal
|
|
22
|
+
let decimalsArc = decimals < 3 ? decimals + 2 : decimals
|
|
23
|
+
//decimalsArc = decimals
|
|
24
|
+
//console.log(decimalsArc);
|
|
25
|
+
|
|
26
|
+
for (let c = 0; c < len; c++) {
|
|
27
|
+
let com = pathData[c];
|
|
28
|
+
let { type, values } = com
|
|
29
|
+
let valLen = values.length;
|
|
30
|
+
if (!valLen) continue
|
|
31
|
+
|
|
32
|
+
let isArc = type.toLowerCase() === 'a'
|
|
33
|
+
|
|
34
|
+
for (let v = 0; v < valLen; v++) {
|
|
35
|
+
// allow higher accuracy for arc radii (... it's always arcs)
|
|
36
|
+
pathData[c].values[v] = isArc && v < 2 ? roundTo(values[v], decimalsArc) : roundTo(values[v], decimals);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
//console.log(pathData);
|
|
41
|
+
return pathData;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
11
47
|
export function detectAccuracyPoly(pts) {
|
|
12
48
|
|
|
13
49
|
let minDim = Infinity
|
|
@@ -20,7 +56,7 @@ export function detectAccuracyPoly(pts) {
|
|
|
20
56
|
let { p0 = null, p = null, dimA = 0 } = pt;
|
|
21
57
|
|
|
22
58
|
// use existing averave dimension value or calculate
|
|
23
|
-
if (
|
|
59
|
+
if (p && p0) {
|
|
24
60
|
dimA = dimA ? dimA : getDistManhattan(p0, p);
|
|
25
61
|
|
|
26
62
|
if (dimA) dims.push(dimA);
|
|
@@ -62,33 +98,90 @@ export function detectAccuracy(pathData) {
|
|
|
62
98
|
//let dimA = +getDistAv(p0, p).toFixed(8)
|
|
63
99
|
//console.log('dimA', dimA, com.dimA, type);
|
|
64
100
|
|
|
65
|
-
if (dimA) dims.push(dimA);
|
|
101
|
+
if (dimA) dims.push(+dimA.toFixed(8));
|
|
102
|
+
//if (dimA) dims.push(dimA);
|
|
66
103
|
if (dimA && dimA < minDim) minDim = dimA;
|
|
67
104
|
//if (dimA && dimA > maxDim) maxDim = dimA;
|
|
68
105
|
}
|
|
69
106
|
|
|
70
107
|
}
|
|
71
108
|
|
|
109
|
+
|
|
110
|
+
dims = dims.sort()
|
|
111
|
+
let len = dims.length;
|
|
112
|
+
let dim_mid = dims[Math.floor(len*0.5)]
|
|
113
|
+
|
|
114
|
+
// smallest 25% of values
|
|
115
|
+
let idx_q = Math.ceil(len*0.25);
|
|
116
|
+
let dims_min = dims.slice(0, idx_q);
|
|
117
|
+
|
|
118
|
+
// average smallest values with mid value
|
|
119
|
+
let dim_min = ((dims_min.reduce((a, b) => a + b, 0) / idx_q) + dim_mid) * 0.5;
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
let threshold = 75
|
|
123
|
+
let decimalsAuto = dim_min > threshold * 1.5 ? 0 : Math.floor(threshold / dim_min).toString().length
|
|
124
|
+
|
|
125
|
+
// clamp
|
|
126
|
+
return Math.min(Math.max(0, decimalsAuto), 8)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
/*
|
|
72
131
|
let dim_min = dims.sort()
|
|
73
132
|
//console.log('dim_min', dim_min);
|
|
74
133
|
|
|
75
|
-
let
|
|
134
|
+
let dim_mid = dim_min[Math.floor(dim_min.length*0.5)]
|
|
135
|
+
|
|
136
|
+
let sliceIdx = Math.ceil(dim_min.length / 4);
|
|
76
137
|
dim_min = dim_min.slice(0, sliceIdx);
|
|
77
138
|
let minVal = dim_min.reduce((a, b) => a + b, 0) / sliceIdx;
|
|
78
139
|
|
|
140
|
+
// average with mid value
|
|
141
|
+
minVal = (minVal+dim_mid)*0.5
|
|
142
|
+
//console.log('minVal', minVal, dim_mid);
|
|
143
|
+
|
|
144
|
+
|
|
79
145
|
let threshold = 75
|
|
80
146
|
let decimalsAuto = minVal > threshold * 1.5 ? 0 : Math.floor(threshold / minVal).toString().length
|
|
81
147
|
|
|
82
148
|
// clamp
|
|
83
149
|
return Math.min(Math.max(0, decimalsAuto), 8)
|
|
150
|
+
*/
|
|
84
151
|
|
|
85
152
|
}
|
|
86
153
|
|
|
154
|
+
/**
|
|
155
|
+
* rounding helper
|
|
156
|
+
* allows for quantized rounding
|
|
157
|
+
* e.g 0.5 decimals s
|
|
158
|
+
*/
|
|
159
|
+
export function roundTo(num = 0, decimals = 3) {
|
|
160
|
+
if (decimals < 0) return num;
|
|
161
|
+
// Normal integer rounding
|
|
162
|
+
if (!decimals) return Math.round(num);
|
|
87
163
|
|
|
164
|
+
// stepped rounding
|
|
165
|
+
let intPart = Math.floor(decimals);
|
|
166
|
+
//let fracPart = decimals.toString().split('.');
|
|
167
|
+
//fracPart = fracPart[1] ? +fracPart[1] : 0
|
|
168
|
+
|
|
169
|
+
if (intPart !== decimals) {
|
|
170
|
+
let f = +(decimals - intPart).toFixed(2)
|
|
171
|
+
f = f > 0.5 ? (Math.floor((f) / 0.5) * 0.5) : f;
|
|
172
|
+
//console.log('fracPart', f);
|
|
173
|
+
let step = 10 ** -intPart * f;
|
|
174
|
+
return +(Math.round(num / step) * step).toFixed(8);
|
|
175
|
+
}
|
|
88
176
|
|
|
177
|
+
let factor = 10 ** decimals;
|
|
178
|
+
return Math.round(num * factor) / factor;
|
|
179
|
+
}
|
|
89
180
|
|
|
90
|
-
|
|
91
|
-
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
export function roundTo__(num = 0, decimals = 3) {
|
|
184
|
+
if (decimals <= -1) return num;
|
|
92
185
|
if (!decimals) return Math.round(num);
|
|
93
186
|
let factor = 10 ** decimals;
|
|
94
187
|
return Math.round(num * factor) / factor;
|
|
@@ -99,85 +192,24 @@ export function roundTo(num = 0, decimals = 3) {
|
|
|
99
192
|
* floating point accuracy
|
|
100
193
|
* based on numeric value
|
|
101
194
|
*/
|
|
102
|
-
export function autoRound(val, integerThresh = 50){
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if(val>integerThresh*2){
|
|
106
|
-
decimals=0
|
|
107
|
-
}
|
|
108
|
-
else if(val>integerThresh){
|
|
109
|
-
decimals=1
|
|
110
|
-
}else{
|
|
111
|
-
decimals=Math.ceil(500/val).toString().length
|
|
112
|
-
//console.log('decimals small', val, decimals);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
//console.log(val, decimals);
|
|
116
|
-
let factor = 10 ** decimals;
|
|
117
|
-
return Math.round(val * factor) / factor;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* round path data
|
|
125
|
-
* either by explicit decimal value or
|
|
126
|
-
* based on suggested accuracy in path data
|
|
127
|
-
*/
|
|
128
|
-
export function roundPathData(pathData, decimalsGlobal = -1) {
|
|
129
|
-
|
|
130
|
-
if (decimalsGlobal < 0) return pathData;
|
|
195
|
+
export function autoRound(val, integerThresh = 50) {
|
|
196
|
+
let decimals = 8;
|
|
131
197
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
//let values = pathData[c].values
|
|
142
|
-
let valLen = values.length;
|
|
143
|
-
if (!valLen) continue
|
|
144
|
-
|
|
145
|
-
for (let v = 0; v < valLen; v++) {
|
|
146
|
-
pathData[c].values[v] = roundTo(values[v], decimals);
|
|
147
|
-
}
|
|
148
|
-
};
|
|
198
|
+
if (val > integerThresh * 2) {
|
|
199
|
+
decimals = 0
|
|
200
|
+
}
|
|
201
|
+
else if (val > integerThresh) {
|
|
202
|
+
decimals = 1
|
|
203
|
+
} else {
|
|
204
|
+
decimals = Math.ceil(500 / val).toString().length
|
|
205
|
+
//console.log('decimals small', val, decimals);
|
|
206
|
+
}
|
|
149
207
|
|
|
150
|
-
//console.log(
|
|
151
|
-
|
|
208
|
+
//console.log(val, decimals);
|
|
209
|
+
let factor = 10 ** decimals;
|
|
210
|
+
return Math.round(val * factor) / factor;
|
|
152
211
|
}
|
|
153
212
|
|
|
154
213
|
|
|
155
|
-
export function roundPathData_(pathData, decimals = -1) {
|
|
156
|
-
|
|
157
|
-
if (decimals < 0) return pathData;
|
|
158
214
|
|
|
159
|
-
let len = pathData.length;
|
|
160
|
-
let c = 0;
|
|
161
|
-
while (c < len) {
|
|
162
215
|
|
|
163
|
-
//let com = pathData[c];
|
|
164
|
-
let values = pathData[c].values
|
|
165
|
-
let valLen = values.length;
|
|
166
|
-
|
|
167
|
-
// Z commands have no values
|
|
168
|
-
if (!valLen) {
|
|
169
|
-
c++; continue
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
let v = 0;
|
|
173
|
-
while (v < valLen) {
|
|
174
|
-
pathData[c].values[v] = roundTo(values[v], decimals);
|
|
175
|
-
v++
|
|
176
|
-
}
|
|
177
|
-
c++
|
|
178
|
-
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
//console.log(pathData);
|
|
182
|
-
return pathData;
|
|
183
|
-
}
|
package/src/svgii/svg_cleanup.js
CHANGED
|
@@ -17,7 +17,7 @@ import { qrDecomposeMatrix } from "./transform_qr_decompose";
|
|
|
17
17
|
import { svgNs } from "../constants";
|
|
18
18
|
import { toCamelCase, toShortStr } from "../string_helpers";
|
|
19
19
|
import { getElementLength } from "./svg_getElementLength";
|
|
20
|
-
import { removeHiddenSvgEls, removeSvgAtts, removeSvgChildAtts, removeSvgEls } from "./svg_cleanup_remove_els_and_atts";
|
|
20
|
+
import { removeAtts, removeHiddenSvgEls, removeSvgAtts, removeSvgChildAtts, removeSvgEls } from "./svg_cleanup_remove_els_and_atts";
|
|
21
21
|
import { cleanupSVGAttributes, removeElAtts } from "./svg_cleanup_general_svg_atts";
|
|
22
22
|
import { convertPathLengthAtt } from "./svg_cleanup_convertPathLength";
|
|
23
23
|
import { removeGroupProps, ungroupElements } from "./svg_cleanup_ungroup";
|
|
@@ -54,7 +54,10 @@ export function cleanUpSVG(svgMarkup, {
|
|
|
54
54
|
cleanupSVGAtts = true,
|
|
55
55
|
removeNameSpaced = true,
|
|
56
56
|
removeNameSpacedAtts = true,
|
|
57
|
+
|
|
58
|
+
// unit conversions
|
|
57
59
|
convertPathLength = false,
|
|
60
|
+
toAbsoluteUnits = false,
|
|
58
61
|
|
|
59
62
|
// meta
|
|
60
63
|
allowMeta = false,
|
|
@@ -82,10 +85,10 @@ export function cleanUpSVG(svgMarkup, {
|
|
|
82
85
|
|
|
83
86
|
|
|
84
87
|
// resolve dependencies
|
|
85
|
-
if (unGroup || convertTransforms || minifyRgbColors || attributesToGroup)
|
|
86
|
-
|
|
88
|
+
if (unGroup || convertTransforms || minifyRgbColors || attributesToGroup)
|
|
89
|
+
stylesToAttributes = true;
|
|
87
90
|
|
|
88
|
-
if(stylesToAttributes) cleanUpStrokes = true;
|
|
91
|
+
if (stylesToAttributes) cleanUpStrokes = true;
|
|
89
92
|
|
|
90
93
|
// replace namespaced refs
|
|
91
94
|
if (fixHref) svgMarkup = svgMarkup.replaceAll("xlink:href=", "href=");
|
|
@@ -136,7 +139,7 @@ export function cleanUpSVG(svgMarkup, {
|
|
|
136
139
|
removeClassNames,
|
|
137
140
|
minifyRgbColors,
|
|
138
141
|
stylesheetProps: {},
|
|
139
|
-
exclude:[]
|
|
142
|
+
exclude: []
|
|
140
143
|
}
|
|
141
144
|
|
|
142
145
|
// root svg inline style properties
|
|
@@ -235,11 +238,16 @@ export function cleanUpSVG(svgMarkup, {
|
|
|
235
238
|
|
|
236
239
|
|
|
237
240
|
// convert pathLength before transforming
|
|
238
|
-
if
|
|
241
|
+
if(convertTransforms || attributesToGroup) convertPathLength=true;
|
|
242
|
+
|
|
243
|
+
if (convertPathLength ) {
|
|
244
|
+
//console.log('convertPathLength', convertPathLength, name);
|
|
239
245
|
styleProps = convertPathLengthAtt(el, { styleProps });
|
|
240
246
|
remove = [...new Set([...remove, ...styleProps.remove])];
|
|
247
|
+
|
|
241
248
|
}
|
|
242
249
|
|
|
250
|
+
//console.log(styleProps);
|
|
243
251
|
|
|
244
252
|
// get parent styles
|
|
245
253
|
let { parentStyleProps = [] } = el;
|
|
@@ -275,9 +283,16 @@ export function cleanUpSVG(svgMarkup, {
|
|
|
275
283
|
if (stylePropsSVG['class']) delete stylePropsSVG['class']
|
|
276
284
|
if (stylePropsSVG['id']) delete stylePropsSVG['id']
|
|
277
285
|
|
|
286
|
+
// add svg props
|
|
287
|
+
inheritedProps = {
|
|
288
|
+
...stylePropsSVG,
|
|
289
|
+
...inheritedProps,
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
//console.log('inheritedProps', inheritedProps);
|
|
293
|
+
|
|
278
294
|
// merge with svg props
|
|
279
295
|
styleProps = {
|
|
280
|
-
...stylePropsSVG,
|
|
281
296
|
...inheritedProps,
|
|
282
297
|
...styleProps
|
|
283
298
|
}
|
|
@@ -287,7 +302,6 @@ export function cleanUpSVG(svgMarkup, {
|
|
|
287
302
|
addTransFormProps(styleProps, transFormInherited);
|
|
288
303
|
//console.log('transFormInherited', transFormInherited);
|
|
289
304
|
//console.log('styleProps', styleProps);
|
|
290
|
-
|
|
291
305
|
remove = [...new Set([...remove, ...styleProps.remove])];
|
|
292
306
|
|
|
293
307
|
|
|
@@ -325,6 +339,46 @@ export function cleanUpSVG(svgMarkup, {
|
|
|
325
339
|
// general cleanup
|
|
326
340
|
if (cleanupSVGAtts) cleanupSVGAttributes(svg, { removeIds, removeClassNames, removeDimensions, stylesToAttributes, allowMeta, allowAriaAtts, allowDataAtts });
|
|
327
341
|
|
|
342
|
+
// all relative units to absolute
|
|
343
|
+
if (toAbsoluteUnits) {
|
|
344
|
+
normalizeTransforms = true;
|
|
345
|
+
//stylesToAttributes = true
|
|
346
|
+
//console.log(name, styleProps);
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* apply consolidated
|
|
350
|
+
* element attributes
|
|
351
|
+
* remove non-supported element props
|
|
352
|
+
*/
|
|
353
|
+
stylePropsFiltered = filterSvgElProps(name, styleProps,
|
|
354
|
+
{ removeDefaults: true, cleanUpStrokes, allowMeta, allowAriaAtts, allowDataAtts, removeIds, inheritedProps });
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
for (let prop in stylePropsFiltered.propsFiltered) {
|
|
358
|
+
let values = styleProps[prop]
|
|
359
|
+
let val = values.length ? values.join(' ') : values[0]
|
|
360
|
+
el.setAttribute(prop, val)
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
//console.log('inheritedProps', inheritedProps);
|
|
364
|
+
//console.log('current props', stylePropsFiltered.propsFiltered);
|
|
365
|
+
|
|
366
|
+
let removeAttsEl = [...new Set([...remove, ...stylePropsFiltered.remove])];
|
|
367
|
+
|
|
368
|
+
// check if same value is in inherited
|
|
369
|
+
for (let prop in stylePropsFiltered.propsFiltered) {
|
|
370
|
+
let valInh = inheritedProps[prop] || [];
|
|
371
|
+
let val = stylePropsFiltered.propsFiltered[prop] || [];
|
|
372
|
+
if (valInh.join() === val.join()) {
|
|
373
|
+
removeAttsEl.push(prop)
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// remove obsolete/inherited
|
|
378
|
+
removeAtts(el, removeAttsEl)
|
|
379
|
+
|
|
380
|
+
}
|
|
381
|
+
|
|
328
382
|
|
|
329
383
|
|
|
330
384
|
if (stylesToAttributes) {
|
|
@@ -345,12 +399,9 @@ export function cleanUpSVG(svgMarkup, {
|
|
|
345
399
|
* remove non-supported element props
|
|
346
400
|
*/
|
|
347
401
|
stylePropsFiltered = filterSvgElProps(name, styleProps,
|
|
348
|
-
{ removeDefaults: true, cleanUpStrokes, allowMeta, allowAriaAtts, allowDataAtts, removeIds });
|
|
402
|
+
{ removeDefaults: true, cleanUpStrokes, allowMeta, allowAriaAtts, allowDataAtts, removeIds, inheritedProps });
|
|
349
403
|
|
|
350
|
-
//remove = [...remove, ...stylePropsFiltered.remove];
|
|
351
404
|
remove = [...new Set([...remove, ...stylePropsFiltered.remove])];
|
|
352
|
-
//console.log('el remove', name, remove);
|
|
353
|
-
//console.log('!!stylePropsFiltered', name, stylePropsFiltered);
|
|
354
405
|
|
|
355
406
|
for (let prop in stylePropsFiltered.propsFiltered) {
|
|
356
407
|
let values = styleProps[prop]
|
|
@@ -363,14 +414,14 @@ export function cleanUpSVG(svgMarkup, {
|
|
|
363
414
|
* remove obsolete
|
|
364
415
|
* attributes
|
|
365
416
|
*/
|
|
366
|
-
|
|
417
|
+
removeAtts(el, remove)
|
|
367
418
|
|
|
419
|
+
/*
|
|
368
420
|
for (let i = 0; i < remove.length; i++) {
|
|
369
421
|
let att = remove[i];
|
|
370
|
-
//if (att === 'style') continue
|
|
371
|
-
//console.log('--remove att', remove, att, name);
|
|
372
422
|
el.removeAttribute(att)
|
|
373
423
|
}
|
|
424
|
+
*/
|
|
374
425
|
|
|
375
426
|
|
|
376
427
|
} // endof style processing
|
|
@@ -396,7 +447,7 @@ export function cleanUpSVG(svgMarkup, {
|
|
|
396
447
|
|
|
397
448
|
// scale props like stroke width or dash-array before conversion
|
|
398
449
|
if (matrix && transComponents) {
|
|
399
|
-
['stroke-width', 'stroke-dasharray'].forEach(att => {
|
|
450
|
+
['stroke-width', 'stroke-dasharray', 'stroke-dashoffset'].forEach(att => {
|
|
400
451
|
let attVal = el.getAttribute(att)
|
|
401
452
|
let vals = attVal ? attVal.split(' ').filter(Boolean).map(Number).map(val => val * transComponents.scaleX) : []
|
|
402
453
|
if (vals.length) el.setAttribute(att, vals.join(' '))
|
|
@@ -460,15 +511,15 @@ export function cleanUpSVG(svgMarkup, {
|
|
|
460
511
|
let values = stylePropsFiltered[prop]
|
|
461
512
|
let val = values.length ? values.join(' ') : values[0]
|
|
462
513
|
|
|
463
|
-
if(prop!=='class' && prop!=='id'){
|
|
514
|
+
if (prop !== 'class' && prop !== 'id') {
|
|
464
515
|
|
|
465
516
|
let propShort = toShortStr(prop)
|
|
466
517
|
let valShort = toShortStr(val)
|
|
467
518
|
let propStr = `${propShort}-${valShort}`;
|
|
468
|
-
|
|
519
|
+
|
|
469
520
|
// store in node property
|
|
470
521
|
if (!el.styleSet) el.styleSet = new Set()
|
|
471
|
-
if(propStr) el.styleSet.add(propStr)
|
|
522
|
+
if (propStr) el.styleSet.add(propStr)
|
|
472
523
|
}
|
|
473
524
|
}
|
|
474
525
|
|
|
@@ -524,7 +575,7 @@ export function cleanUpSVG(svgMarkup, {
|
|
|
524
575
|
|
|
525
576
|
|
|
526
577
|
function removeEmptyClassAtts(svg) {
|
|
527
|
-
let emptyClassEls = svg.querySelectorAll('[class=""');
|
|
578
|
+
let emptyClassEls = svg.querySelectorAll('[class=""]');
|
|
528
579
|
emptyClassEls.forEach(el => {
|
|
529
580
|
el.removeAttribute('class')
|
|
530
581
|
})
|
|
@@ -538,7 +589,7 @@ function sharedAttributesToGroup(svg) {
|
|
|
538
589
|
|
|
539
590
|
let els = svg.querySelectorAll(renderedEls.join(', '))
|
|
540
591
|
let len = els.length;
|
|
541
|
-
if(len===1) return;
|
|
592
|
+
if (len === 1) return;
|
|
542
593
|
|
|
543
594
|
let el0 = els[0] || null
|
|
544
595
|
let stylePrev = el0.styleSet !== undefined ? [...el0.styleSet].join('_') : ''
|
|
@@ -623,7 +674,7 @@ function sharedAttributesToGroup(svg) {
|
|
|
623
674
|
|
|
624
675
|
|
|
625
676
|
// create new group
|
|
626
|
-
if (!groupEl || groups.length>1) {
|
|
677
|
+
if (!groupEl || groups.length > 1) {
|
|
627
678
|
//console.log('new group');
|
|
628
679
|
groupEl = document.createElementNS(svgNs, 'g')
|
|
629
680
|
child0.parentNode.insertBefore(groupEl, child0)
|
|
@@ -719,7 +770,9 @@ function removeOffCanvasEls(svg, { x = 0, y = 0, width = 0, height = 0 } = {}) {
|
|
|
719
770
|
bb0.bottom = y + height
|
|
720
771
|
|
|
721
772
|
els.forEach(el => {
|
|
773
|
+
//console.log(el);
|
|
722
774
|
let bb = getElBBox(el)
|
|
775
|
+
//console.log('!!bb', bb, el);
|
|
723
776
|
let outside = bb.right < bb0.x || bb.bottom < bb0.y || bb.x > bb0.right || bb.y > bb.bottom
|
|
724
777
|
if (outside) el.remove();
|
|
725
778
|
})
|
|
@@ -1,31 +1,43 @@
|
|
|
1
|
+
import { scaleProps } from "./svg_cleanup_normalize_transforms";
|
|
2
|
+
import { getElementLength } from "./svg_getElementLength";
|
|
3
|
+
|
|
1
4
|
export function convertPathLengthAtt(el, {
|
|
2
5
|
styleProps = {}
|
|
3
|
-
}={}) {
|
|
6
|
+
} = {}) {
|
|
7
|
+
|
|
8
|
+
let pathLength = styleProps['pathLength'];
|
|
9
|
+
|
|
10
|
+
if (pathLength) {
|
|
11
|
+
|
|
12
|
+
//let strokeDasharray
|
|
13
|
+
if ((styleProps['stroke-dasharray'] || styleProps['stroke-dashoffset'])) {
|
|
14
|
+
let elLength = getElementLength(el, {
|
|
15
|
+
pathLength,
|
|
16
|
+
props: styleProps
|
|
17
|
+
})
|
|
4
18
|
|
|
5
|
-
let pathLength = el.getAttribute('pathLength') ? +el.getAttribute('pathLength') : 0;
|
|
6
|
-
//let strokeDasharray
|
|
7
|
-
if (pathLength && (styleProps['stroke-dasharray'] || styleProps['stroke-dashoffset'])) {
|
|
8
|
-
let elLength = getElementLength(el, {
|
|
9
|
-
pathLength,
|
|
10
|
-
props: styleProps
|
|
11
|
-
})
|
|
12
19
|
|
|
13
|
-
|
|
14
|
-
|
|
20
|
+
let scale = elLength / pathLength
|
|
21
|
+
//console.log('elLength', elLength, scale);
|
|
15
22
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
23
|
+
styleProps = scaleProps(styleProps, { props: ['stroke-dasharray', 'stroke-dashoffset'], scale })
|
|
24
|
+
|
|
25
|
+
// set absolute
|
|
26
|
+
if (styleProps['stroke-dasharray']) el.setAttribute('stroke-dasharray', styleProps['stroke-dasharray'].join(' '))
|
|
27
|
+
if (styleProps['stroke-dashoffset']) el.setAttribute('stroke-dashoffset', styleProps['stroke-dashoffset'][0])
|
|
28
|
+
|
|
29
|
+
}
|
|
20
30
|
|
|
21
31
|
// tag for removal
|
|
22
32
|
delete styleProps['pathLength'];
|
|
23
33
|
styleProps.remove.push('pathLength')
|
|
24
34
|
el.removeAttribute('pathLength')
|
|
25
35
|
|
|
26
|
-
|
|
36
|
+
|
|
27
37
|
}
|
|
28
38
|
|
|
39
|
+
//console.log('pathLength', pathLength);
|
|
40
|
+
//console.log('styleProps', styleProps );
|
|
29
41
|
return styleProps;
|
|
30
42
|
|
|
31
43
|
|
|
@@ -76,7 +76,7 @@ export function scaleProps(styleProps = {}, { props = [], scale = 1 } = {}, roun
|
|
|
76
76
|
let prop = props[i];
|
|
77
77
|
|
|
78
78
|
if (styleProps[prop] !== undefined) {
|
|
79
|
-
styleProps[prop] = styleProps[prop].map(val => round ? roundTo(val * scale,
|
|
79
|
+
styleProps[prop] = styleProps[prop].map(val => round ? roundTo(val * scale, 3) : val * scale)
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
return styleProps
|
|
@@ -51,11 +51,16 @@ export function removeSvgEls(svg, {
|
|
|
51
51
|
*/
|
|
52
52
|
|
|
53
53
|
export function removeSvgAtts(svg, remove = []) {
|
|
54
|
+
removeAtts(svg, remove)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function removeAtts(el, remove = []) {
|
|
54
58
|
remove.forEach(att => {
|
|
55
|
-
|
|
59
|
+
el.removeAttribute(att);
|
|
56
60
|
})
|
|
57
61
|
}
|
|
58
62
|
|
|
63
|
+
|
|
59
64
|
export function removeSvgChildAtts(svg, remove = []) {
|
|
60
65
|
if (remove.length) {
|
|
61
66
|
let selector = remove.map(att => { return `[${att}]` }).join(', ')
|