svg-path-simplify 0.3.6 → 0.4.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svg-path-simplify",
3
- "version": "0.3.6",
3
+ "version": "0.4.1",
4
4
 
5
5
  "type": "module",
6
6
 
package/src/constants.js CHANGED
@@ -6,4 +6,11 @@ export const {
6
6
  export const rad2Deg = 180/Math.PI
7
7
  export const deg2rad = Math.PI/180
8
8
  export const root2 = 1.4142135623730951
9
- export const svgNs = 'http://www.w3.org/2000/svg'
9
+ export const svgNs = 'http://www.w3.org/2000/svg'
10
+
11
+ // 1/2.54
12
+ export const inch2cm = 0.39370078;
13
+
14
+ // 1/72
15
+ export const inch2pt = 0.01388889;
16
+
@@ -305,11 +305,3 @@ export function findSplitT(com1, com2) {
305
305
 
306
306
  return l1 / l3
307
307
  }
308
-
309
-
310
-
311
-
312
-
313
-
314
-
315
-
@@ -12,7 +12,7 @@ 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 } from './svgii/rounding';
16
16
  import { refineAdjacentExtremes } from './svgii/pathData_simplify_refineExtremes';
17
17
  import { cleanUpSVG, removeEmptySVGEls, stringifySVG } from './svgii/svg_cleanup';
18
18
  import { refineRoundedCorners } from './svgii/pathData_simplify_refineCorners';
@@ -99,9 +99,12 @@ export function svgPathSimplify(input = '', {
99
99
  scaleTo = 0,
100
100
  crop = false,
101
101
  alignToOrigin = false,
102
+
103
+ // flatten transforms
102
104
  convertTransforms = false,
103
105
 
104
106
 
107
+
105
108
  //svg path optimizations
106
109
  decimals = 3,
107
110
  autoAccuracy = true,
@@ -114,24 +117,28 @@ export function svgPathSimplify(input = '', {
114
117
  reversePath = false,
115
118
 
116
119
  //svg cleanup options
120
+ minifyRgbColors = false,
117
121
  removePrologue = true,
118
122
  removeHidden = true,
119
123
  removeUnused = true,
120
124
  cleanupDefs = true,
121
125
  cleanupClip = true,
122
126
  cleanupSVGAtts = true,
123
-
127
+
124
128
  stylesToAttributes = false,
125
129
  fixHref = false,
126
130
  legacyHref = false,
127
131
  removeNameSpaced = true,
128
- attributesToGroup = false,
129
- removeOffCanvas = false,
130
132
 
133
+ //attributesToGroup = false,
134
+ removeOffCanvas = false,
135
+ unGroup = false,
131
136
  mergePaths = false,
132
137
 
133
138
  // shape conversions
134
139
  shapesToPaths = false,
140
+
141
+
135
142
  //toPaths || toShapes
136
143
  shapeConvert = 0,
137
144
  convert_rects = false,
@@ -146,6 +153,8 @@ export function svgPathSimplify(input = '', {
146
153
  addViewBox = false,
147
154
  addDimensions = false,
148
155
 
156
+ removeComments = true,
157
+
149
158
  } = {}) {
150
159
 
151
160
 
@@ -230,12 +239,19 @@ export function svgPathSimplify(input = '', {
230
239
  // mode:1 – process complete svg DOM
231
240
  else {
232
241
 
242
+ // convert all shapes to paths
243
+ if (shapesToPaths) {
244
+ shapeConvert = true
245
+ convert_rects = true
246
+ convert_ellipses = true
247
+ convert_poly = true
248
+ convert_lines = true
249
+ }
233
250
 
234
251
  //sanitize
235
252
  let svgPropObject = cleanUpSVG(input, {
236
253
  removeIds, removeClassNames, removeDimensions, cleanupSVGAtts, cleanUpStrokes, removeHidden, removeUnused, removeNameSpaced, stylesToAttributes, removePrologue, fixHref, mergePaths, convertTransforms, legacyHref, cleanupDefs, cleanupClip, addViewBox, removeOffCanvas, addDimensions,
237
- shapeConvert, convert_rects, convert_ellipses, convert_poly, convert_lines
238
-
254
+ shapeConvert, convert_rects, convert_ellipses, convert_poly, convert_lines, minifyRgbColors, unGroup, convertTransforms
239
255
  }
240
256
  );
241
257
 
@@ -580,8 +596,8 @@ export function svgPathSimplify(input = '', {
580
596
 
581
597
  if (autoAccuracy) {
582
598
  accuracyArr = accuracyArr.sort().reverse();
583
- let decimalsMid = accuracyArr[Math.floor(accuracyArr.length*0.5)]
584
- decimals = Math.floor( (accuracyArr[0] + decimalsMid) * 0.5 )
599
+ let decimalsMid = accuracyArr[Math.floor(accuracyArr.length * 0.5)]
600
+ decimals = Math.floor((accuracyArr[0] + decimalsMid) * 0.5)
585
601
  //decimals = detectAccuracy(pathData)
586
602
  //console.log('decimals', decimals, 'decimalsMid', decimalsMid, accuracyArr);
587
603
  pathOptions.decimals = decimals
@@ -711,7 +727,7 @@ export function svgPathSimplify(input = '', {
711
727
  }
712
728
 
713
729
 
714
- svg = stringifySVG(svg, omitNamespace);
730
+ svg = stringifySVG(svg, { omitNamespace, removeComments });
715
731
 
716
732
 
717
733
  //svgSizeOpt = new Blob([svg]).size
@@ -1,5 +1,5 @@
1
1
  import { parseCSSTransform, parseTransform } from "./svgii/svg-styles-getTransforms";
2
- import { getElAttributes, getElementProps, getElStyleProps } from "./svgii/svg-styles-to-attributes";
2
+ import { getElAttributes, getElementProps, getElStyleProps } from "../__back/svg-styles-to-attributes";
3
3
 
4
4
  export function flattenTransforms(svg) {
5
5
 
@@ -1,3 +1,45 @@
1
+
2
+ export function parseColor(str) {
3
+ let type = str.startsWith('#') ? 'rgbHex' : (str.includes('(') ? 'fn' : typeof str);
4
+ let col = {}
5
+ let mode = null;
6
+ let colObj = { mode: null, values: [] }
7
+ if (type === 'rgbHex') {
8
+ col = hex2Rgb(str)
9
+ mode = 'rgba';
10
+ }
11
+ else if (type === 'fn') {
12
+ let colVals = str.split(/\(|\)/).filter(Boolean)
13
+ if (colVals.length < 2) return str;
14
+
15
+ mode = colVals[0];
16
+ let colorComponents = colVals[1].split(/,| /).filter(Boolean).map(Number)
17
+
18
+ let keys = mode.split('');
19
+ keys.forEach((k, i) => {
20
+ let val = colorComponents[i]
21
+ if (mode === 'rgba' && k === 'a') {
22
+ val = Math.floor(val * 255)
23
+ }
24
+ col[k] = val;
25
+ })
26
+ }
27
+ else if (type === 'string') {
28
+ colObj.mode = 'keyword'
29
+ colObj.values = [str]
30
+ return colObj
31
+ }
32
+
33
+ if (mode === 'rgba' || mode === 'rgb') {
34
+ col.a = !col.a ? 255 : col.a;
35
+ }
36
+
37
+ colObj.mode = mode
38
+ colObj.values = Object.values(col)
39
+
40
+ return colObj;
41
+ }
42
+
1
43
  export function hex2Rgb(hex = '') {
2
44
  // Remove # if present
3
45
  if (hex.startsWith('#')) hex = hex.substring(1);
@@ -30,13 +72,18 @@ export function hex2Rgb(hex = '') {
30
72
 
31
73
  }
32
74
 
33
- export function rgba2Hex({ r, g, b, a = 255 }) {
75
+ export function rgba2Hex({ r = 0, g = 0, b = 0, a = 255, values = [] }) {
34
76
  // Helper function to convert number to 2-digit hex
35
77
  const toHex = (num) => {
36
78
  const hex = Math.min(255, Math.max(0, Math.round(num))).toString(16);
37
79
  return hex.length === 1 ? '0' + hex : hex;
38
80
  };
39
81
 
82
+ // convert from number array input
83
+ if (!r && !g && !b && values.length) {
84
+ [r, g, b, a = 255] = values;
85
+ }
86
+
40
87
  // Get hex values
41
88
  let rHex = toHex(r);
42
89
  let gHex = toHex(g);
@@ -51,7 +98,7 @@ export function rgba2Hex({ r, g, b, a = 255 }) {
51
98
  }
52
99
 
53
100
  // Check for 4-character RGBA short notation (e.g., #ffff)
54
- if (aHex && allowsShort ) {
101
+ if (aHex && allowsShort) {
55
102
  return `#${rHex[0]}${gHex[0]}${bHex[0]}${aHex[0]}`;
56
103
  }
57
104
 
@@ -67,7 +114,7 @@ export function rgba2Hex({ r, g, b, a = 255 }) {
67
114
 
68
115
 
69
116
  export function hsl2Rgb(hsla = {}) {
70
- let {h, s, l, a = 1} = hsla;
117
+ let { h, s, l, a = 1 } = hsla;
71
118
 
72
119
  // Normalize
73
120
  h = ((h % 360) + 360) % 360; // wrap hue
@@ -90,9 +137,9 @@ export function hsl2Rgb(hsla = {}) {
90
137
  let r = (r1 + m) * 255;
91
138
  let g = (g1 + m) * 255;
92
139
  let b = (b1 + m) * 255;
93
- a = Math.floor(a*255);
140
+ a = Math.floor(a * 255);
94
141
 
95
142
  [r, g, b] = [r, g, b].map((val) => +val.toFixed(0));
96
143
 
97
- return {r,g,b,a}
144
+ return { r, g, b, a }
98
145
  }
@@ -1,4 +1,4 @@
1
- import { deg2rad, rad2Deg, root2 } from "../constants";
1
+ import { deg2rad, inch2cm, inch2pt, rad2Deg, root2 } from "../constants";
2
2
  import { hex2Rgb, hsl2Rgb, rgba2Hex } from "./convert_colors";
3
3
  import { autoRound } from "./rounding";
4
4
  import { horizontalProps, verticalProps } from "./svg-styles-to-attributes-const";
@@ -56,21 +56,21 @@ export function normalizeUnits(value = null, {
56
56
  // only required for circle r normalization when height!=width
57
57
  normalizedDiagonal = width === height ? false : normalizedDiagonal;
58
58
 
59
- //console.log('???value',value );
59
+ let type = typeof value;
60
60
  if (!value) return value;
61
61
 
62
62
  // check if value is string
63
- let isArray = value.split(/,| /).length>1
64
- let isFunction = value.includes('(')
63
+ let isNum = type === 'number' ? true : isNumericValue(value)
64
+ let isArray = type === 'string' ? value.split(/,| /).length > 1 : false;
65
+ let isFunction = type === 'string' ? value.includes('(') : false;
65
66
  //console.log(isArray);
66
- let isNum = isNumericValue(value)
67
67
  if (!isNum || isArray || isFunction) return value
68
68
 
69
69
  // check unit if not specified
70
70
  unit = !unit ? getUnit(value) : unit;
71
71
 
72
72
  let val = parseFloat(value);
73
- let scale=1;
73
+ let scale = 1;
74
74
  let scaleRoot = Math.sqrt(width * width + height * height) / root2
75
75
 
76
76
 
@@ -92,7 +92,6 @@ export function normalizeUnits(value = null, {
92
92
  }
93
93
  break;
94
94
 
95
-
96
95
  case "rad":
97
96
  scale = rad2Deg;
98
97
  break;
@@ -103,15 +102,31 @@ export function normalizeUnits(value = null, {
103
102
  case "in":
104
103
  scale = dpi;
105
104
  break;
105
+
106
106
  case "pt":
107
- scale = (1 / 72) * dpi;
107
+ // 1/72
108
+ scale = dpi * inch2pt;
109
+ break;
110
+
111
+ case "pc":
112
+ // 1/6
113
+ scale = dpi * 0.16666667;
108
114
  break;
115
+
109
116
  case "cm":
110
- scale = (1 / 2.54) * dpi;
117
+ // 1/2.54
118
+ scale = inch2cm * dpi;
111
119
  break;
112
120
  case "mm":
113
- scale = ((1 / 2.54) * dpi) / 10;
121
+ //scale = ((1 / 2.54) * dpi) * 0.1;
122
+ scale = inch2cm * dpi * 0.1
123
+ break;
124
+
125
+ // has anyone ever used it?
126
+ case "Q":
127
+ scale = inch2cm * dpi * 0.025;
114
128
  break;
129
+
115
130
  // just a default approximation
116
131
  case "em":
117
132
  case "rem":
@@ -55,10 +55,10 @@ export function analyzePathData(pathData = [], {
55
55
  let len = pathData.length;
56
56
 
57
57
  // threshold for corner angles: 10 deg
58
- let thresholdCorner = Math.PI * 2 / 360 * 10
58
+ //let thresholdCorner = Math.PI * 2 / 360 * 10
59
59
 
60
60
  // define angle threshold for semi extremes
61
- let thresholdAngle = detectSemiExtremes ? 0.01 : 0.05
61
+ //let thresholdAngle = detectSemiExtremes ? 0.01 : 0.05
62
62
 
63
63
 
64
64
  for (let c = 2; len && c <= len; c++) {
@@ -86,7 +86,7 @@ export function analyzePathData(pathData = [], {
86
86
  // check flatness of command
87
87
  let toleranceFlat = 0.01;
88
88
  let thresholdLength = dimA * 0.1
89
- let threshold = thresholdLength*0.01
89
+ let threshold = thresholdLength * 0.01
90
90
  let areaThresh = squareDist * toleranceFlat;
91
91
  let isFlat = Math.abs(cptArea) < areaThresh;
92
92
 
@@ -109,14 +109,29 @@ export function analyzePathData(pathData = [], {
109
109
  let dx = type === 'C' ? Math.abs(com.cp2.x - com.p.x) : Math.abs(com.cp1.x - com.p.x)
110
110
  let dy = type === 'C' ? Math.abs(com.cp2.y - com.p.y) : Math.abs(com.cp1.y - com.p.y)
111
111
 
112
- let horizontal = (dy === 0 || dy<threshold ) && dx > 0
113
- let vertical = (dx === 0 || dx<threshold ) && dy > 0
112
+ //let horizontal = (dy === 0 || dy<=threshold ) && dx > 0
113
+ //let vertical = (dx === 0 || dx<=threshold ) && dy > 0
114
+ let horizontal = (dy === 0 || dy <= threshold) && dx > 0
115
+ let vertical = (dx === 0 || dx <= threshold) && dy > 0
116
+
114
117
 
115
118
  if (horizontal || vertical) {
116
119
  hasExtremes = true;
117
120
  }
118
121
 
119
122
  // is extreme relative to bounding box
123
+
124
+ // (cp1.x===p0.x && cp1.y!==p0.y ) ||
125
+ if ((cp1.x === p0.x && cp1.y !== p0.y) || (cp1.y === p0.y && cp1.x !== p0.x)) {
126
+ //hasExtremes = true;
127
+ //renderPoint(markers, p0 )
128
+ //p0.extreme = true
129
+ //let comP = pathDataProps[pathDataProps.length-1]
130
+ pathDataProps[pathDataProps.length - 1].extreme = true
131
+ //console.log(comP);
132
+ }
133
+
134
+
120
135
  if ((p.x === left || p.y === top || p.x === right || p.y === bottom)) {
121
136
  hasExtremes = true;
122
137
  }
@@ -126,6 +141,7 @@ export function analyzePathData(pathData = [], {
126
141
  let couldHaveExtremes = bezierhasExtreme(null, commandPts)
127
142
  if (couldHaveExtremes) {
128
143
  let tArr = getTatAngles(commandPts)
144
+
129
145
  if (tArr.length && (tArr[0] > 0.2)) {
130
146
  hasExtremes = true;
131
147
  }
@@ -181,24 +197,28 @@ export function analyzePathData(pathData = [], {
181
197
 
182
198
  let signChange2 = (areaCpt < 0 && com.cptArea > 0) || (areaCpt > 0 && com.cptArea < 0) ? true : false;
183
199
 
184
- let isCorner=!isFlat && signChange2;
200
+ let isCorner = !isFlat && signChange2;
185
201
  if (isCorner) com.corner = true;
186
202
  }
187
203
  }
188
204
 
189
- //debug = true;
190
- if (debug) {
205
+ pathDataProps.push(com)
206
+
207
+ }
208
+
209
+
210
+ //debug = true;
211
+
212
+ if (debug) {
213
+ pathDataProps.forEach(com=>{
191
214
  //if (com.semiExtreme) renderPoint(markers, com.p, 'blue', '2%', '0.5')
192
215
  if (com.directionChange) renderPoint(markers, com.p, 'orange', '1.5%', '0.5')
193
216
  if (com.corner) renderPoint(markers, com.p, 'magenta', '1.5%', '0.5')
194
217
  if (com.extreme) renderPoint(markers, com.p, 'cyan', '1%', '0.5')
195
-
196
- }
197
-
198
- pathDataProps.push(com)
199
-
218
+ })
200
219
  }
201
220
 
221
+
202
222
  //pathDataProps.push(comLast)
203
223
 
204
224
 
@@ -51,6 +51,8 @@ export function parsePathDataNormalized(d,
51
51
  let { hasRelatives = true, hasShorthands = true, hasQuadratics = true, hasArcs = true } = pathDataObj;
52
52
  let pathData = hasConstructor ? pathDataObj : pathDataObj.pathData;
53
53
 
54
+ //console.log('???quadraticToCubic', quadraticToCubic);
55
+
54
56
  // normalize
55
57
  pathData = normalizePathData(pathData,
56
58
  {
@@ -77,11 +79,14 @@ export function convertPathData(pathData, {
77
79
  hasShorthands = true,
78
80
  hasQuadratics = true,
79
81
  hasArcs = true,
82
+ optimizeArcs = true,
80
83
  testTypes = false
81
84
 
82
85
 
83
86
  } = {}) {
84
87
 
88
+
89
+
85
90
  // pathdata properties - test= true adds a manual test
86
91
  if (testTypes) {
87
92
  //console.log('test for conversions');
@@ -99,26 +104,76 @@ export function convertPathData(pathData, {
99
104
  toShorthands = toLonghands ? false : toShorthands
100
105
 
101
106
 
102
- //console.log(toShorthands, toRelative, decimals);
103
- if (hasQuadratics && quadraticToCubic) pathData = pathDataQuadraticToCubic(pathData);
107
+ if (toAbsolute) pathData = pathDataToAbsolute(pathData);
108
+ if (hasShorthands && toLonghands) pathData = pathDataToLonghands(pathData);
109
+
110
+
111
+ // minify semicircle radii
112
+ if (optimizeArcs) pathData = optimizeArcPathData(pathData);
104
113
 
105
114
 
106
115
  //if(decimals>-1 && decimals<2) pathData = roundPathData(pathData, decimals);
107
116
  if (toShorthands) pathData = pathDataToShorthands(pathData);
108
- if (hasShorthands && toLonghands) pathData = pathDataToLonghands(pathData);
109
-
110
- if (toAbsolute) pathData = pathDataToAbsolute(pathData);
111
117
 
112
118
  if (hasArcs && arcToCubic) pathData = pathDataArcsToCubics(pathData)
113
119
 
120
+ //console.log(toShorthands, toRelative, decimals);
121
+ if (hasQuadratics && quadraticToCubic) pathData = pathDataQuadraticToCubic(pathData);
122
+
123
+
114
124
  // pre round - before relative conversion to minimize distortions
115
125
  if (decimals > -1 && toRelative) pathData = roundPathData(pathData, decimals);
126
+
127
+
116
128
  if (toRelative) pathData = pathDataToRelative(pathData);
117
129
  if (decimals > -1) pathData = roundPathData(pathData, decimals);
118
130
 
119
131
  return pathData
120
132
  }
121
133
 
134
+ /**
135
+ *
136
+ * @param {*} pathData
137
+ * @returns
138
+ */
139
+
140
+ export function optimizeArcPathData(pathData = []) {
141
+ pathData.forEach((com, i) => {
142
+ let { type, values } = com;
143
+ if (type === 'A') {
144
+ let [rx, ry, largeArc, x, y] = [values[0], values[1], values[3], values[5], values[6]];
145
+ let comPrev = pathData[i - 1]
146
+ let [x0, y0] = [comPrev.values[comPrev.values.length - 2], comPrev.values[comPrev.values.length - 1]];
147
+ let M = { x: x0, y: y0 };
148
+ let p = { x, y };
149
+ //largeArc=true
150
+ //let pMid = {x: Math.abs(x-x0), y:Math.abs(y-y0)}
151
+
152
+ // rx and ry are large enough
153
+ if (rx >= 1 && (x === x0 || y === y0)) {
154
+ let diff = Math.abs(rx - ry) / rx;
155
+
156
+ // rx~==ry
157
+ if (diff < 0.01) {
158
+
159
+ // test radius against mid point
160
+ let pMid = interpolate(M, p, 0.5)
161
+ let distM = getDistance(pMid, M)
162
+ let rDiff = Math.abs(distM - rx) / rx
163
+
164
+ // half distance between mid and start point should be ~ equal
165
+ if(rDiff<0.01){
166
+ pathData[i].values[0] = 1;
167
+ pathData[i].values[1] = 1;
168
+ pathData[i].values[2] = 0;
169
+ }
170
+ }
171
+ }
172
+ }
173
+ })
174
+ return pathData;
175
+ }
176
+
122
177
 
123
178
 
124
179
  /**
@@ -139,6 +194,7 @@ export function normalizePathData(pathData = [],
139
194
  } = {}
140
195
  ) {
141
196
 
197
+
142
198
  return convertPathData(pathData, { toAbsolute, toLonghands, quadraticToCubic, arcToCubic, arcAccuracy, hasRelatives, hasShorthands, hasQuadratics, hasArcs, testTypes, decimals: -1 })
143
199
  }
144
200
 
@@ -577,7 +633,7 @@ export function pathDataToShorthands(pathData, decimals = -1, test = false) {
577
633
  let dy1 = (p0.y - cpPrev.y)
578
634
 
579
635
  //adjust maxDist
580
- maxDist = getDistManhattan(cpPrev, cpFirst) * 0.025
636
+ maxDist = getDistManhattan(cpPrev, cpFirst) * 0.01
581
637
 
582
638
  // reflected cp
583
639
  let cpR = { x: cpPrev.x + dx1 * 2, y: cpPrev.y + dy1 * 2 }
@@ -11,8 +11,10 @@ import { getPolyBBox } from './geometry_bbox.js';
11
11
  import { getPathDataVerbose } from './pathData_analyze.js';
12
12
  import { parsePathDataNormalized } from './pathData_convert.js';
13
13
  import { parsePathDataString, stringifyPathData } from './pathData_parse.js';
14
+ import { transformPathData } from './pathData_transform.js';
14
15
  import { autoRound, roundTo } from './rounding.js';
15
16
  import { attLookup } from './svg-styles-to-attributes-const.js';
17
+ import { qrDecomposeMatrix } from './transform_qr_decompose.js';
16
18
 
17
19
 
18
20
  export function pathElToShape(el, {
@@ -151,39 +153,53 @@ export function shapeElToPath(el, { width = 0,
151
153
  convert_rects = false,
152
154
  convert_ellipses = false,
153
155
  convert_poly = false,
154
- convert_lines = false
156
+ convert_lines = false,
157
+ //matrix={a:1, b:0, c:0, d:1, e:0, f:0},
158
+ matrix=null
155
159
 
156
160
  } = {}) {
157
161
 
158
162
  let nodeName = el.nodeName.toLowerCase();
163
+ //console.log('shapeElToPath', nodeName);
164
+
159
165
 
160
166
  if (
161
- nodeName === 'path' ||
167
+ nodeName === 'path' && !matrix ||
162
168
  nodeName === 'rect' && !convert_rects ||
163
169
  (nodeName === 'circle' || nodeName === 'ellipse') && !convert_ellipses ||
164
170
  (nodeName === 'polygon' || nodeName === 'polyline') && !convert_poly ||
165
171
  (nodeName === 'line') && !convert_lines
166
172
  ) return el;
167
173
 
174
+
168
175
  let pathData = getPathDataFromEl(el, { width, height });
176
+
177
+ // shape attributes – obsolete for path els
178
+ let exclude = ['d', 'x', 'y', 'x1', 'y1', 'x2', 'y2', 'cx', 'cy', 'dx', 'dy', 'r', 'rx', 'ry', 'width', 'height', 'points'];
179
+
180
+ // transform pathData
181
+ if(matrix && Object.values(matrix).join('')!=='100100'){
182
+ pathData = transformPathData(pathData, matrix)
183
+ exclude.push('transform', 'transform-origin')
184
+ }
185
+
169
186
  let d = pathData.map(com => { return `${com.type} ${com.values} ` }).join(' ')
170
187
  let attributes = [...el.attributes].map(att => att.name);
171
188
 
172
-
173
189
  let pathN = document.createElementNS(svgNs, 'path');
174
190
  pathN.setAttribute('d', d);
175
191
 
176
- let exclude = ['x', 'y', 'x1', 'y1', 'x2', 'y2', 'cx', 'cy', 'dx', 'dy', 'r', 'rx', 'ry', 'width', 'height', 'points'];
177
192
 
193
+ // copy attributes
178
194
  attributes.forEach(att => {
179
195
  if (!exclude.includes(att)) {
180
- //console.log(att, attributes, exclude);
181
196
  let val = el.getAttribute(att);
182
197
  pathN.setAttribute(att, val)
183
198
  }
184
199
  })
185
200
 
186
201
  //el.replaceWith(pathN)
202
+ //console.log(pathN.outerHTML, d);
187
203
  return pathN
188
204
 
189
205
  }
@@ -129,9 +129,11 @@ simplifyRDP=1,
129
129
  poly = poly.map(pt => { return [pt.x, pt.y] })
130
130
  }
131
131
  else if(polyFormat==='string'){
132
- poly = poly.map(pt => { return [pt.x, pt.y].join(',') }).join(' ')
132
+ poly = poly.map(pt => { return [pt.x, pt.y].join(',') }).flat().join(' ')
133
133
  }
134
134
 
135
+ //console.log(pathData);
136
+
135
137
  return { pathData, poly }
136
138
 
137
139
  }