svg-path-simplify 0.3.0 → 0.3.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/.github/ISSUE_TEMPLATE/bug_report.yml +28 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +35 -0
- package/README.md +3 -1
- package/dist/svg-path-simplify.esm.js +2804 -2761
- package/dist/svg-path-simplify.esm.min.js +5 -7
- package/dist/svg-path-simplify.js +2804 -2761
- package/dist/svg-path-simplify.min.js +5 -7
- package/dist/svg-path-simplify.pathdata.esm.js +31 -2
- package/dist/svg-path-simplify.pathdata.esm.min.js +5 -5
- package/index.html +546 -203
- package/package.json +1 -1
- package/site.webmanifest +21 -0
- package/src/detect_input.js +30 -3
- package/src/pathSimplify-main.js +134 -67
- package/src/poly-fit-curve-schneider.js +266 -175
- package/src/simplify_poly_RDP.js +101 -1
- package/src/simplify_poly_radial_distance.js +85 -2
- package/src/svg_flatten_transforms.js +43 -0
- package/src/svgii/geometry.js +1 -0
- package/src/svgii/pathData_fromPoly.js +22 -7
- package/src/svgii/pathData_toPolygon.js +122 -230
- package/src/svgii/poly_analyze.js +114 -435
- package/src/svgii/poly_analyze_get_chunks.js +67 -0
- package/src/svgii/poly_normalize.js +51 -0
- package/src/svgii/poly_to_pathdata.js +51 -24
- package/src/svgii/rounding.js +36 -0
- package/src/svgii/svg-styles-getTransforms.js +43 -5
- package/src/svgii/svg-styles-to-attributes.js +81 -3
- package/src/svgii/svg_cleanup.js +21 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
|
|
2
|
+
// split in chunks based on significant points
|
|
3
|
+
|
|
4
|
+
import { pathDataToD } from "./pathData_stringify";
|
|
5
|
+
import { renderPath } from "./visualize";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export function getPolyChunks(pts,
|
|
9
|
+
{ closed = true,
|
|
10
|
+
keepCorners = true,
|
|
11
|
+
keepExtremes = true,
|
|
12
|
+
keepInflections = false
|
|
13
|
+
} = {}
|
|
14
|
+
) {
|
|
15
|
+
let chunks = [[pts[0]]];
|
|
16
|
+
//let chunk = [pts[0]];
|
|
17
|
+
let idx = 0
|
|
18
|
+
let lastChunk = chunks[idx]
|
|
19
|
+
|
|
20
|
+
let l = pts.length
|
|
21
|
+
|
|
22
|
+
// render
|
|
23
|
+
for (let i = 1; i < l; i++) {
|
|
24
|
+
let p0 = i > 0 ? pts[i] : pts[l - 1];
|
|
25
|
+
let p1 = pts[i];
|
|
26
|
+
let p2 = i < l - 1 ? pts[i + 1] : pts[l - 1];
|
|
27
|
+
|
|
28
|
+
// start new chunk
|
|
29
|
+
// keepInflections && p1.isDirChange
|
|
30
|
+
if ((keepExtremes && p1.isExtreme || keepCorners && p1.isCorner )) {
|
|
31
|
+
idx++
|
|
32
|
+
chunks.push([])
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
lastChunk = chunks[idx]
|
|
37
|
+
lastChunk.push(p1)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// test render
|
|
41
|
+
//renderchunks(chunks)
|
|
42
|
+
|
|
43
|
+
return chunks;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
function renderchunks(chunks) {
|
|
49
|
+
|
|
50
|
+
chunks.forEach((chunk, i) => {
|
|
51
|
+
|
|
52
|
+
let stroke = i % 2 === 0 ? 'orange' : 'blue';
|
|
53
|
+
let pathData = [{ type: 'M', values: [chunk[0].x, chunk[0].y] }]
|
|
54
|
+
let d = `M`
|
|
55
|
+
|
|
56
|
+
chunk.forEach(pt => {
|
|
57
|
+
|
|
58
|
+
pathData.push({ type: 'L', values: [pt.x, pt.y] })
|
|
59
|
+
d += ` ${[pt.x, pt.y].join(' ')}`
|
|
60
|
+
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
d = pathDataToD(pathData)
|
|
64
|
+
renderPath(markers, d, stroke, '2%', '0.5')
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export function normalizePoly(pts, {
|
|
2
|
+
toObject = true,
|
|
3
|
+
toArray = false,
|
|
4
|
+
flatten = false
|
|
5
|
+
} = {}) {
|
|
6
|
+
|
|
7
|
+
if (flatten) pts = pts.flat(2);
|
|
8
|
+
let poly = toArray ? polyPtsToArray(pts) : polyArrayToObject(pts)
|
|
9
|
+
return poly
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
export function polyArrayToObject(pts) {
|
|
14
|
+
|
|
15
|
+
// is point object array
|
|
16
|
+
if (pts[0].x !== undefined && pts[0].y !== undefined) return pts
|
|
17
|
+
|
|
18
|
+
let poly = [];
|
|
19
|
+
|
|
20
|
+
// complex poly object array
|
|
21
|
+
if (Array.isArray(pts[0]) && pts[0][0].x !== undefined && pts[0][0].y !== undefined) {
|
|
22
|
+
return pts
|
|
23
|
+
}
|
|
24
|
+
// complex poly value array
|
|
25
|
+
else if (Array.isArray(pts[0][0]) && pts[0][0].length === 2) {
|
|
26
|
+
pts.forEach(sub => {
|
|
27
|
+
poly.push(sub.map(pt => { return { x: pt[0], y: pt[1] } }))
|
|
28
|
+
})
|
|
29
|
+
return poly
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return pts.map(pt => { return { x: pt[0], y: pt[1] } })
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
export function polyPtsToArray(pts) {
|
|
37
|
+
|
|
38
|
+
// is already coordinate array
|
|
39
|
+
if (!Array.isArray(pts[0][0]) && pts[0].length === 2) return pts
|
|
40
|
+
|
|
41
|
+
let poly = [];
|
|
42
|
+
if (Array.isArray(pts[0][0]) && pts[0][0].length === 2) {
|
|
43
|
+
pts.forEach(sub => {
|
|
44
|
+
poly.push(sub.map(pt => [pt.x, pt.y]))
|
|
45
|
+
})
|
|
46
|
+
return poly
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
poly = Array.from(pts).map(pt => [pt.x, pt.y])
|
|
50
|
+
return poly
|
|
51
|
+
}
|
|
@@ -7,61 +7,84 @@
|
|
|
7
7
|
|
|
8
8
|
import { checkLineIntersection, getDistManhattan, interpolate, mirrorCpts } from "./geometry";
|
|
9
9
|
import { getPolyBBox } from "./geometry_bbox";
|
|
10
|
-
import { analyzePoly, getPolyChunks, isClosedPolygon } from "./poly_analyze";
|
|
11
|
-
import { fitCurveN } from "../poly-fit-curve-schneider";
|
|
12
10
|
import { renderPath, renderPoint, renderPoly } from "./visualize";
|
|
13
|
-
import {
|
|
11
|
+
import { simplifyPolyRDP } from "../simplify_poly_RDP";
|
|
14
12
|
import { pathDataFromPoly } from "./pathData_fromPoly";
|
|
13
|
+
import { getPolyChunks } from "./poly_analyze_get_chunks";
|
|
14
|
+
import { analyzePoly, isClosedPolygon } from "./poly_analyze";
|
|
15
|
+
import { fitCurveSchneider } from "../poly-fit-curve-schneider";
|
|
16
|
+
import { simplifyPolyRD } from "../simplify_poly_radial_distance";
|
|
17
|
+
|
|
18
|
+
|
|
15
19
|
|
|
16
20
|
export function simplifyPolygonToPathData(pts, {
|
|
17
21
|
debug = false,
|
|
18
22
|
width = 0,
|
|
19
23
|
height = 0,
|
|
20
24
|
denoise = 0.9,
|
|
21
|
-
keepCorners=true,
|
|
22
|
-
keepExtremes=true,
|
|
23
|
-
keepInflections=false,
|
|
25
|
+
keepCorners = true,
|
|
26
|
+
keepExtremes = true,
|
|
27
|
+
keepInflections = false,
|
|
24
28
|
manhattan = false,
|
|
25
29
|
absolute = false,
|
|
26
30
|
closed = true,
|
|
27
|
-
tolerance = 1
|
|
31
|
+
tolerance = 1,
|
|
32
|
+
simplifyRD = 1,
|
|
33
|
+
simplifyRDP = 1,
|
|
28
34
|
} = {}) {
|
|
29
35
|
|
|
30
36
|
|
|
31
|
-
denoise = 0
|
|
32
37
|
|
|
38
|
+
/*
|
|
33
39
|
// denoise via RDP
|
|
34
40
|
if (denoise && denoise !== 1) {
|
|
35
|
-
pts =
|
|
41
|
+
pts = simplifyPolyRDP(pts, {
|
|
36
42
|
width,
|
|
37
43
|
height,
|
|
38
44
|
quality: denoise,
|
|
39
45
|
manhattan,
|
|
40
46
|
absolute
|
|
41
47
|
})
|
|
48
|
+
}
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
/*
|
|
53
|
+
// simplify polygon
|
|
54
|
+
if (simplifyRD != 1) {
|
|
55
|
+
pts = simplifyPolyRD(pts, { quality: simplifyRD+'px' })
|
|
56
|
+
}
|
|
57
|
+
|
|
42
58
|
|
|
59
|
+
if (simplifyRDP != 1) {
|
|
60
|
+
pts = simplifyPolyRDP(pts, { quality: simplifyRDP+'px' })
|
|
43
61
|
}
|
|
62
|
+
*/
|
|
63
|
+
|
|
44
64
|
|
|
45
65
|
// get topology of poly
|
|
46
|
-
let polyAnalyzed = !keepExtremes
|
|
66
|
+
let polyAnalyzed = !keepExtremes && !keepCorners ? pts : analyzePoly(pts, {
|
|
47
67
|
debug: false
|
|
48
68
|
//width,
|
|
49
69
|
//height
|
|
50
70
|
})
|
|
51
71
|
|
|
72
|
+
//console.log(polyAnalyzed, polyAnalyzed2);
|
|
73
|
+
//return
|
|
52
74
|
|
|
53
75
|
// split into segment chunks
|
|
54
|
-
let chunks = !keepExtremes
|
|
76
|
+
let chunks = !keepExtremes && !keepCorners ? [polyAnalyzed] : getPolyChunks(polyAnalyzed, { keepCorners, keepExtremes, keepInflections });
|
|
55
77
|
|
|
56
78
|
|
|
57
79
|
// Schneider curve fit
|
|
58
80
|
let threshold = width && height ? (width + height) / 2 * 0.004 * tolerance : 2.5
|
|
59
81
|
|
|
60
|
-
threshold=2
|
|
82
|
+
//threshold = 2
|
|
61
83
|
|
|
62
84
|
let polyPath = simplifyPolyChunks(chunks, {
|
|
63
85
|
closed,
|
|
64
|
-
tolerance: threshold
|
|
86
|
+
tolerance: threshold,
|
|
87
|
+
keepCorners
|
|
65
88
|
});
|
|
66
89
|
|
|
67
90
|
return polyPath;
|
|
@@ -75,6 +98,7 @@ export function simplifyPolygonToPathData(pts, {
|
|
|
75
98
|
|
|
76
99
|
export function simplifyPolyChunks(chunks = [], {
|
|
77
100
|
closed = true,
|
|
101
|
+
keepCorners = true,
|
|
78
102
|
tolerance = 1,
|
|
79
103
|
} = {}) {
|
|
80
104
|
|
|
@@ -100,12 +124,14 @@ export function simplifyPolyChunks(chunks = [], {
|
|
|
100
124
|
}
|
|
101
125
|
|
|
102
126
|
// nothing to simplify
|
|
103
|
-
if (chunklen < 2 || (chunklen === 2 && chunk[1].isExtreme)
|
|
127
|
+
if (chunklen < 2 || (chunklen === 2 && chunk[1].isExtreme)) {
|
|
104
128
|
pLast = chunk[chunk.length - 1]
|
|
105
129
|
segments = chunk.map(com => { return { type: 'L', values: [com.x, com.y] } })
|
|
106
130
|
|
|
107
131
|
} else {
|
|
108
|
-
segments =
|
|
132
|
+
segments = fitCurveSchneider(chunk, {
|
|
133
|
+
maxError: tolerance, keepCorners
|
|
134
|
+
})
|
|
109
135
|
}
|
|
110
136
|
|
|
111
137
|
// remove first segment to connect to last segment
|
|
@@ -115,11 +141,12 @@ export function simplifyPolyChunks(chunks = [], {
|
|
|
115
141
|
|
|
116
142
|
|
|
117
143
|
if (closed) pathData.push({ type: 'Z', values: [] })
|
|
118
|
-
|
|
119
|
-
//console.log('!!!pathData', pathData);
|
|
144
|
+
//console.log('!!!pathData from poly', pathData);
|
|
120
145
|
|
|
121
146
|
// refine extremes
|
|
122
|
-
|
|
147
|
+
let refineExtremes = false;
|
|
148
|
+
//refineExtremes=true;
|
|
149
|
+
if (refineExtremes) refineAdjacentExtremes(pathData)
|
|
123
150
|
return pathData
|
|
124
151
|
|
|
125
152
|
}
|
|
@@ -160,13 +187,13 @@ export function refineAdjacentExtremes(pathData) {
|
|
|
160
187
|
let vertical2 = dx2 < dist1 && dy2 > dist1
|
|
161
188
|
|
|
162
189
|
|
|
163
|
-
let distCpO=0, distCpN=0, t=1;
|
|
190
|
+
let distCpO = 0, distCpN = 0, t = 1;
|
|
164
191
|
let cp2N, cp1N;
|
|
165
192
|
|
|
166
193
|
if (horizontal1 || vertical1) {
|
|
167
194
|
|
|
168
195
|
// adjust cp2 to horizontal
|
|
169
|
-
cp2N = horizontal1 ? {x:com.values[2], y: p.y} : (vertical1 ? {x:p.x, y:com.values[3]} : {x:com.values[2], y:com.values[3]})
|
|
196
|
+
cp2N = horizontal1 ? { x: com.values[2], y: p.y } : (vertical1 ? { x: p.x, y: com.values[3] } : { x: com.values[2], y: com.values[3] })
|
|
170
197
|
|
|
171
198
|
/*
|
|
172
199
|
// adjust length
|
|
@@ -182,14 +209,14 @@ export function refineAdjacentExtremes(pathData) {
|
|
|
182
209
|
com.values[3] = cp2N.y
|
|
183
210
|
|
|
184
211
|
}
|
|
185
|
-
|
|
212
|
+
|
|
186
213
|
|
|
187
214
|
if (horizontal2 || vertical2) {
|
|
188
215
|
// adjust cp1 to horizontal
|
|
189
216
|
|
|
190
|
-
cp1N = horizontal2 ?
|
|
191
|
-
|
|
192
|
-
|
|
217
|
+
cp1N = horizontal2 ?
|
|
218
|
+
{ x: comN.values[0], y: p.y } :
|
|
219
|
+
(vertical2 ? { x: p.x, y: comN.values[1] } : { x: comN.values[0], y: comN.values[1] })
|
|
193
220
|
|
|
194
221
|
/*
|
|
195
222
|
// adjust length
|
package/src/svgii/rounding.js
CHANGED
|
@@ -7,6 +7,42 @@
|
|
|
7
7
|
import { getDistAv, getDistManhattan } from "./geometry";
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
|
|
11
|
+
export function detectAccuracyPoly(pts) {
|
|
12
|
+
|
|
13
|
+
let minDim = Infinity
|
|
14
|
+
let dims = [];
|
|
15
|
+
//console.log(pathData);
|
|
16
|
+
|
|
17
|
+
// add average distances
|
|
18
|
+
for (let i = 1, len = pts.length; i < len; i++) {
|
|
19
|
+
let pt = pts[i];
|
|
20
|
+
let { p0 = null, p = null, dimA = 0 } = pt;
|
|
21
|
+
|
|
22
|
+
// use existing averave dimension value or calculate
|
|
23
|
+
if ( p && p0) {
|
|
24
|
+
dimA = dimA ? dimA : getDistManhattan(p0, p);
|
|
25
|
+
|
|
26
|
+
if (dimA) dims.push(dimA);
|
|
27
|
+
if (dimA && dimA < minDim) minDim = dimA;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
let dim_min = dims.sort()
|
|
32
|
+
let sliceIdx = Math.ceil(dim_min.length / 8);
|
|
33
|
+
dim_min = dim_min.slice(0, sliceIdx);
|
|
34
|
+
let minVal = dim_min.reduce((a, b) => a + b, 0) / sliceIdx;
|
|
35
|
+
|
|
36
|
+
let threshold = 75
|
|
37
|
+
let decimalsAuto = minVal > threshold * 1.5 ? 0 : Math.floor(threshold / minVal).toString().length
|
|
38
|
+
// clamp
|
|
39
|
+
return Math.min(Math.max(0, decimalsAuto), 8)
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
10
46
|
export function detectAccuracy(pathData) {
|
|
11
47
|
|
|
12
48
|
let minDim = Infinity
|
|
@@ -3,7 +3,41 @@
|
|
|
3
3
|
* transform property object
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
export function
|
|
6
|
+
export function parseTransform(transformString, transformOrigin = { x: 0, y: 0 }) {
|
|
7
|
+
|
|
8
|
+
//let regex = /(\w+)\(([^)]+)\)/g;
|
|
9
|
+
let transArr = transformString.match(/[a-z]+\([^)]*\)/gi);
|
|
10
|
+
|
|
11
|
+
//console.log('transArr', transArr);
|
|
12
|
+
|
|
13
|
+
let transforms = [];
|
|
14
|
+
transArr.forEach(trans => {
|
|
15
|
+
let [prop, vals] = trans.split(/\(|\)/).filter(Boolean)
|
|
16
|
+
//let prop = vals[0];
|
|
17
|
+
vals = vals.split(/,| /).filter(Boolean).map(Number)
|
|
18
|
+
console.log('trans', prop, vals);
|
|
19
|
+
|
|
20
|
+
// rotate has origin
|
|
21
|
+
if(prop==='rotate' && vals.length===3){
|
|
22
|
+
transforms.push({prop:'translate', values:[vals[1], vals[2]]})
|
|
23
|
+
transforms.push({prop:'rotate', values:[vals[0]]})
|
|
24
|
+
transforms.push({prop:'translate', values:[-vals[1], -vals[2]]})
|
|
25
|
+
}else{
|
|
26
|
+
transforms.push({prop, values:[vals[0]]})
|
|
27
|
+
}
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
console.log('transforms', transforms);
|
|
31
|
+
|
|
32
|
+
//let values =
|
|
33
|
+
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
export function parseCSSTransform(transformString, transformOrigin = { x: 0, y: 0 }) {
|
|
38
|
+
|
|
39
|
+
if (!transformString) return false;
|
|
40
|
+
|
|
7
41
|
let transformOptions = {
|
|
8
42
|
transforms: [],
|
|
9
43
|
transformOrigin,
|
|
@@ -53,7 +87,11 @@ export function parseCSSTransform(transformString, transformOrigin={x:0, y:0}) {
|
|
|
53
87
|
case 'skewY':
|
|
54
88
|
transformOptions.transforms.push({ skew: [0, values[0] || 0] });
|
|
55
89
|
break;
|
|
90
|
+
|
|
56
91
|
case 'rotate':
|
|
92
|
+
|
|
93
|
+
console.log('rotate', values);
|
|
94
|
+
|
|
57
95
|
transformOptions.transforms.push({ rotate: [0, 0, values[0] || 0] });
|
|
58
96
|
break;
|
|
59
97
|
case 'matrix':
|
|
@@ -165,9 +203,9 @@ export function getMatrix2D(transformations = [], origin = { x: 0, y: 0 }) {
|
|
|
165
203
|
|
|
166
204
|
|
|
167
205
|
// Process transformations in the provided order (right-to-left)
|
|
168
|
-
for (
|
|
169
|
-
|
|
170
|
-
|
|
206
|
+
for (let transform of transformations) {
|
|
207
|
+
let type = Object.keys(transform)[0]; // Get the transformation type (e.g., "translate")
|
|
208
|
+
let values = transform[type] || defaults[type]; // Use default values if none provided
|
|
171
209
|
|
|
172
210
|
// Destructure values with fallbacks
|
|
173
211
|
let [x, y = defaults[type][1]] = values
|
|
@@ -268,6 +306,6 @@ export function getCSSTransform({
|
|
|
268
306
|
let cssParent = `perspective-origin:${perspectiveOrigin.x}px ${perspectiveOrigin.y}px; perspective:${perspective}px;`;
|
|
269
307
|
|
|
270
308
|
css = `transform:${css.join(' ')};transform-origin:${transFormOrigin.x}px ${transFormOrigin.y}px;`;
|
|
271
|
-
return {el:css, parent:cssParent}
|
|
309
|
+
return { el: css, parent: cssParent }
|
|
272
310
|
|
|
273
311
|
}
|
|
@@ -1,6 +1,79 @@
|
|
|
1
1
|
import { getMatrix, parseCSSTransform } from './svg-styles-getTransforms';
|
|
2
2
|
import { attLookup } from './svg-styles-to-attributes-const';
|
|
3
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
|
+
|
|
4
77
|
export function svgStylesToAttributes(el, {
|
|
5
78
|
removeNameSpaced = true,
|
|
6
79
|
decimals = -1
|
|
@@ -10,6 +83,11 @@ export function svgStylesToAttributes(el, {
|
|
|
10
83
|
let attProps = getElAttributes(el)
|
|
11
84
|
let cssProps = getElStyleProps(el)
|
|
12
85
|
|
|
86
|
+
// normalize transform attributes
|
|
87
|
+
if (attProps['transform']) {
|
|
88
|
+
console.log(`attProps['transform']`, attProps['transform']);
|
|
89
|
+
}
|
|
90
|
+
|
|
13
91
|
// merge properties
|
|
14
92
|
let props = {
|
|
15
93
|
...attProps,
|
|
@@ -21,7 +99,7 @@ export function svgStylesToAttributes(el, {
|
|
|
21
99
|
|
|
22
100
|
// parse CSS transforms
|
|
23
101
|
let cssTrans = cssProps['transform']
|
|
24
|
-
|
|
102
|
+
|
|
25
103
|
if (cssTrans) {
|
|
26
104
|
let transStr = `${cssTrans}`
|
|
27
105
|
let transformObj = parseCSSTransform(transStr)
|
|
@@ -98,13 +176,13 @@ function parseInlineStyle(styleAtt = '') {
|
|
|
98
176
|
return props
|
|
99
177
|
}
|
|
100
178
|
|
|
101
|
-
function getElStyleProps(el) {
|
|
179
|
+
export function getElStyleProps(el) {
|
|
102
180
|
let styleAtt = el.getAttribute('style')
|
|
103
181
|
let props = styleAtt ? parseInlineStyle(styleAtt) : {}
|
|
104
182
|
return props
|
|
105
183
|
}
|
|
106
184
|
|
|
107
|
-
function getElAttributes(el) {
|
|
185
|
+
export function getElAttributes(el) {
|
|
108
186
|
let props = {}
|
|
109
187
|
let atts = [...el.attributes].map((att) => att.name);
|
|
110
188
|
let l = atts.length;
|
package/src/svgii/svg_cleanup.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { flattenTransforms } from "../svg_flatten_transforms";
|
|
1
2
|
import { parsePathDataString } from "./pathData_parse";
|
|
2
3
|
import { shapeElToPath } from "./pathData_parse_els";
|
|
3
4
|
import { svgStylesToAttributes } from "./svg-styles-to-attributes";
|
|
@@ -27,6 +28,8 @@ export function cleanUpSVG(svgMarkup, {
|
|
|
27
28
|
removeNameSpaced = true,
|
|
28
29
|
attributesToGroup = true,
|
|
29
30
|
shapesToPaths = false,
|
|
31
|
+
convertTransforms = false,
|
|
32
|
+
cleanUpStrokes=true,
|
|
30
33
|
decimals = -1,
|
|
31
34
|
excludedEls = [],
|
|
32
35
|
} = {}) {
|
|
@@ -113,6 +116,24 @@ export function cleanUpSVG(svgMarkup, {
|
|
|
113
116
|
//console.log('!!!svgMarkup', svgMarkup);
|
|
114
117
|
|
|
115
118
|
|
|
119
|
+
// remove empty defs
|
|
120
|
+
let defs = svg.querySelectorAll('defs')
|
|
121
|
+
defs.forEach(def=>{
|
|
122
|
+
let children=[...def.children]
|
|
123
|
+
let attributes = [...def.attributes]
|
|
124
|
+
if(!children.length){
|
|
125
|
+
def.remove()
|
|
126
|
+
}
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
/*
|
|
131
|
+
if(convertTransforms){
|
|
132
|
+
flattenTransforms(svg)
|
|
133
|
+
}
|
|
134
|
+
*/
|
|
135
|
+
|
|
136
|
+
|
|
116
137
|
if (returnDom) return svg
|
|
117
138
|
let markup = stringifySVG(svg)
|
|
118
139
|
|