svg-path-simplify 0.3.5 → 0.4.0
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 +19 -0
- package/README.md +3 -76
- package/dist/svg-path-simplify.esm.js +5505 -4030
- package/dist/svg-path-simplify.esm.min.js +2 -8
- package/dist/svg-path-simplify.js +5506 -4029
- package/dist/svg-path-simplify.min.js +2 -8
- package/dist/svg-path-simplify.pathdata.esm.js +1154 -1042
- package/dist/svg-path-simplify.pathdata.esm.min.js +2 -8
- package/docs/api.md +127 -0
- package/index.html +279 -257
- package/package.json +1 -1
- package/src/constants.js +10 -1
- package/src/index.js +7 -1
- package/src/pathData_simplify_cubic.js +1 -18
- package/src/pathSimplify-main.js +87 -30
- package/src/pathSimplify-only-pathdata.js +2 -2
- package/src/svg-getAttributes.js +13 -0
- package/src/svg_flatten_transforms.js +1 -1
- package/src/svg_getViewbox.js +23 -11
- package/src/svg_rootSVG.js +9 -0
- package/src/svgii/convert_colors.js +145 -0
- package/src/svgii/convert_units.js +159 -0
- package/src/svgii/geometry.js +24 -4
- package/src/svgii/geometry_bbox.js +2 -1
- package/src/svgii/geometry_bbox_element.js +46 -0
- package/src/svgii/pathData_analyze.js +34 -14
- package/src/svgii/pathData_convert.js +204 -34
- package/src/svgii/pathData_parse.js +2 -99
- package/src/svgii/pathData_parse_els.js +217 -128
- package/src/svgii/pathData_simplify_refineCorners.js +72 -43
- package/src/svgii/pathData_stringify.js +6 -5
- package/src/svgii/pathData_toPolygon.js +3 -1
- package/src/svgii/pathData_transform.js +307 -0
- package/src/svgii/poly_normalize.js +21 -1
- package/src/svgii/rounding.js +36 -5
- package/src/svgii/svg-styles-getTransforms.js +119 -8
- package/src/svgii/svg-styles-to-attributes-const.js +26 -6
- package/src/svgii/svg_cleanup.js +540 -74
- package/src/svgii/svg_el_parse_style_props.js +561 -0
- package/src/svgii/transform_qr_decompose.js +74 -0
- package/src/svgii/pathData_scale.js +0 -42
- package/src/svgii/stringify.js +0 -103
- package/src/svgii/svg-styles-to-attributes.js +0 -217
package/src/svgii/stringify.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Serialize pathData array to a minified "d" attribute string.
|
|
3
|
-
*/
|
|
4
|
-
export function pathDataToD(pathData, optimize = 1) {
|
|
5
|
-
|
|
6
|
-
let beautify = optimize>1;
|
|
7
|
-
let minify = beautify ? false : true;
|
|
8
|
-
|
|
9
|
-
// Convert first "M" to "m" if followed by "l" (when minified)
|
|
10
|
-
if (pathData[1].type === "l" && minify) {
|
|
11
|
-
pathData[0].type = "m";
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
let d = '';
|
|
15
|
-
if(beautify) {
|
|
16
|
-
d = `${pathData[0].type} ${pathData[0].values.join(" ")}\n`;
|
|
17
|
-
}else{
|
|
18
|
-
d = `${pathData[0].type}${pathData[0].values.join(" ")}`;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
for (let i = 1, len = pathData.length; i < len; i++) {
|
|
23
|
-
let com0 = pathData[i - 1];
|
|
24
|
-
let com = pathData[i];
|
|
25
|
-
let { type, values } = com;
|
|
26
|
-
|
|
27
|
-
// Minify Arc commands (A/a) – actually sucks!
|
|
28
|
-
if (minify && (type === 'A' || type === 'a')) {
|
|
29
|
-
values = [
|
|
30
|
-
values[0], values[1], values[2],
|
|
31
|
-
`${values[3]}${values[4]}${values[5]}`,
|
|
32
|
-
values[6]
|
|
33
|
-
];
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Omit type for repeated commands
|
|
37
|
-
type = (com0.type === com.type && com.type.toLowerCase() !== 'm' && minify)
|
|
38
|
-
? " "
|
|
39
|
-
: (
|
|
40
|
-
(com0.type === "m" && com.type === "l") ||
|
|
41
|
-
(com0.type === "M" && com.type === "l") ||
|
|
42
|
-
(com0.type === "M" && com.type === "L")
|
|
43
|
-
) && minify
|
|
44
|
-
? " "
|
|
45
|
-
: com.type;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
// concatenate subsequent floating point values
|
|
49
|
-
if (minify) {
|
|
50
|
-
|
|
51
|
-
//console.log(optimize, beautify, minify);
|
|
52
|
-
|
|
53
|
-
let valsString = '';
|
|
54
|
-
let prevWasFloat = false;
|
|
55
|
-
|
|
56
|
-
for (let v = 0, l = values.length; v < l; v++) {
|
|
57
|
-
let val = values[v];
|
|
58
|
-
let valStr = val.toString();
|
|
59
|
-
let isFloat = valStr.includes('.');
|
|
60
|
-
let isSmallFloat = isFloat && Math.abs(val) < 1;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
// Remove leading zero from small floats *only* if the previous was also a float
|
|
64
|
-
if (isSmallFloat && prevWasFloat) {
|
|
65
|
-
valStr = valStr.replace(/^0\./, '.');
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Add space unless this is the first value OR previous was a small float
|
|
69
|
-
if (v > 0 && !(prevWasFloat && isSmallFloat)) {
|
|
70
|
-
valsString += ' ';
|
|
71
|
-
}
|
|
72
|
-
//console.log(isSmallFloat, prevWasFloat, valStr);
|
|
73
|
-
|
|
74
|
-
valsString += valStr
|
|
75
|
-
//.replace(/-0./g, '-.').replace(/ -./g, '-.')
|
|
76
|
-
prevWasFloat = isSmallFloat;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
//console.log('minify', valsString);
|
|
80
|
-
d += `${type}${valsString}`;
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
// regular non-minified output
|
|
84
|
-
else{
|
|
85
|
-
if(beautify) {
|
|
86
|
-
d += `${type} ${values.join(' ')}\n`;
|
|
87
|
-
}else{
|
|
88
|
-
d += `${type}${values.join(' ')}`;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (minify) {
|
|
94
|
-
d = d
|
|
95
|
-
.replace(/ 0\./g, " .") // Space before small decimals
|
|
96
|
-
.replace(/ -/g, "-") // Remove space before negatives
|
|
97
|
-
.replace(/-0\./g, "-.") // Remove leading zero from negative decimals
|
|
98
|
-
.replace(/Z/g, "z"); // Convert uppercase 'Z' to lowercase
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
return d;
|
|
103
|
-
}
|
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
import { getMatrix, parseCSSTransform } from './svg-styles-getTransforms';
|
|
2
|
-
import { attLookup } from './svg-styles-to-attributes-const';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export function getElementProps(el, {
|
|
7
|
-
removeNameSpaced = true,
|
|
8
|
-
decimals = -1
|
|
9
|
-
} = {}) {
|
|
10
|
-
|
|
11
|
-
let nodeName = el.nodeName.toLowerCase();
|
|
12
|
-
let attProps = getElAttributes(el)
|
|
13
|
-
let cssProps = getElStyleProps(el)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
// normalize transform attributes
|
|
17
|
-
if (attProps['transform']) {
|
|
18
|
-
|
|
19
|
-
let transAtt = attProps['transform']
|
|
20
|
-
let transArr = transAtt.match(/[a-z]+\([^)]*\)/gi);
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
//console.log(`attProps['transform']`, transAtt);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
let transforms = [];
|
|
27
|
-
transArr.forEach(trans => {
|
|
28
|
-
let [prop, vals] = trans.split(/\(|\)/).filter(Boolean)
|
|
29
|
-
//let prop = vals[0];
|
|
30
|
-
vals = vals.split(/,| /).filter(Boolean).map(Number)
|
|
31
|
-
console.log('trans', prop, vals);
|
|
32
|
-
|
|
33
|
-
let cssTrans = '';
|
|
34
|
-
|
|
35
|
-
// rotate has origin
|
|
36
|
-
if (prop === 'rotate' && vals.length === 3) {
|
|
37
|
-
|
|
38
|
-
cssTrans = `
|
|
39
|
-
translate(${vals[1]}px, ${vals[2]}px)
|
|
40
|
-
rotate(${vals[0]}deg)
|
|
41
|
-
translate(${-vals[1]}px, ${-vals[2]}px)
|
|
42
|
-
`
|
|
43
|
-
/*
|
|
44
|
-
transforms.push({ prop: 'translate', values: [vals[1], vals[2]] })
|
|
45
|
-
transforms.push({ prop: 'rotate', values: [vals[0]] })
|
|
46
|
-
transforms.push({ prop: 'translate', values: [-vals[1], -vals[2]] })
|
|
47
|
-
*/
|
|
48
|
-
} else {
|
|
49
|
-
cssTrans = `
|
|
50
|
-
${prop}(${vals[1]}px, ${vals[2]}px)
|
|
51
|
-
rotate(${vals[0]}deg)
|
|
52
|
-
translate(${-vals[1]}px, ${-vals[2]}px)
|
|
53
|
-
`
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
//transforms.push({ prop, values: [vals[0]] })
|
|
57
|
-
}
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
console.log('transforms', transforms);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// merge properties
|
|
68
|
-
let props = {
|
|
69
|
-
...attProps,
|
|
70
|
-
...cssProps
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
export function svgStylesToAttributes(el, {
|
|
78
|
-
removeNameSpaced = true,
|
|
79
|
-
decimals = -1
|
|
80
|
-
} = {}) {
|
|
81
|
-
|
|
82
|
-
let nodeName = el.nodeName.toLowerCase();
|
|
83
|
-
let attProps = getElAttributes(el)
|
|
84
|
-
let cssProps = getElStyleProps(el)
|
|
85
|
-
|
|
86
|
-
// normalize transform attributes
|
|
87
|
-
if (attProps['transform']) {
|
|
88
|
-
console.log(`attProps['transform']`, attProps['transform']);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// merge properties
|
|
92
|
-
let props = {
|
|
93
|
-
...attProps,
|
|
94
|
-
...cssProps
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// filter out obsolete properties
|
|
98
|
-
let propsFiltered = {}
|
|
99
|
-
|
|
100
|
-
// parse CSS transforms
|
|
101
|
-
let cssTrans = cssProps['transform']
|
|
102
|
-
|
|
103
|
-
if (cssTrans) {
|
|
104
|
-
let transStr = `${cssTrans}`
|
|
105
|
-
let transformObj = parseCSSTransform(transStr)
|
|
106
|
-
let matrix = getMatrix(transformObj)
|
|
107
|
-
|
|
108
|
-
// apply as SVG matrix transform
|
|
109
|
-
props['transform'] = `matrix(${Object.values(matrix).join(',')})`
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
// can't be replaced with attributes
|
|
114
|
-
let cssOnlyProps = ['inline-size']
|
|
115
|
-
let styleProps = [];
|
|
116
|
-
|
|
117
|
-
for (let prop in props) {
|
|
118
|
-
|
|
119
|
-
let value = props[prop];
|
|
120
|
-
|
|
121
|
-
// CSS variable
|
|
122
|
-
if (value && prop.startsWith('--') || cssOnlyProps.includes(prop) ||
|
|
123
|
-
(!removeNameSpaced && prop.startsWith('-'))) {
|
|
124
|
-
styleProps.push(`${prop}:${value}`)
|
|
125
|
-
continue
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// check if property is valid
|
|
129
|
-
if (value && attLookup.atts[prop] &&
|
|
130
|
-
(attLookup.atts[prop] === '*' ||
|
|
131
|
-
attLookup.atts[prop].includes(nodeName) ||
|
|
132
|
-
!removeNameSpaced && (prop.includes(':'))
|
|
133
|
-
)
|
|
134
|
-
) {
|
|
135
|
-
propsFiltered[prop] = value
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// remove property
|
|
139
|
-
el.removeAttribute(prop)
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// apply filtered attributes
|
|
144
|
-
for (let prop in propsFiltered) {
|
|
145
|
-
let value = propsFiltered[prop]
|
|
146
|
-
el.setAttribute(prop, value)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
if (styleProps.length) {
|
|
150
|
-
el.setAttribute('style', styleProps.join(';'));
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
//console.log('propsFiltered', propsFiltered);
|
|
154
|
-
|
|
155
|
-
return propsFiltered;
|
|
156
|
-
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
function parseInlineStyle(styleAtt = '') {
|
|
161
|
-
|
|
162
|
-
let props = {}
|
|
163
|
-
if (!styleAtt) return props;
|
|
164
|
-
|
|
165
|
-
let styleArr = styleAtt.split(';').filter(Boolean).map(prop => prop.trim());
|
|
166
|
-
let l = styleArr.length
|
|
167
|
-
if (!l) return props;
|
|
168
|
-
|
|
169
|
-
for (let i = 0; l && i < l; i++) {
|
|
170
|
-
let style = styleArr[i]
|
|
171
|
-
let [prop, value] = style.split(':').filter(Boolean)
|
|
172
|
-
props[prop] = value;
|
|
173
|
-
//props.push(`${prop}:${value}`)
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return props
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
export function getElStyleProps(el) {
|
|
180
|
-
let styleAtt = el.getAttribute('style')
|
|
181
|
-
let props = styleAtt ? parseInlineStyle(styleAtt) : {}
|
|
182
|
-
return props
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
export function getElAttributes(el) {
|
|
186
|
-
let props = {}
|
|
187
|
-
let atts = [...el.attributes].map((att) => att.name);
|
|
188
|
-
let l = atts.length;
|
|
189
|
-
if (!l) return props;
|
|
190
|
-
|
|
191
|
-
for (let i = 0; i < l; i++) {
|
|
192
|
-
let att = atts[i];
|
|
193
|
-
let value = el.getAttribute(att);
|
|
194
|
-
props[att] = value
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
return props;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
function getUnit(val) {
|
|
202
|
-
return val && isNaN(val) ? val.match(/[^\d|.]+/g)[0] : '';
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
function roundValue(value = '', decimals = -1) {
|
|
207
|
-
if (decimals < 0) return value;
|
|
208
|
-
value = value.replace(/["]/g, '').trim()
|
|
209
|
-
let valueNum = parseFloat(value);
|
|
210
|
-
let valueHasNumber = !isNaN(valueNum);
|
|
211
|
-
if (!valueHasNumber) return value;
|
|
212
|
-
|
|
213
|
-
let unit = valueHasNumber ? getUnit(value) : '';
|
|
214
|
-
if (valueHasNumber) value = `${valueNum.toFixed(decimals)}${unit}`;
|
|
215
|
-
//console.log('rounded', value)
|
|
216
|
-
return value;
|
|
217
|
-
}
|