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.
Files changed (61) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +7 -4
  3. package/dist/svg-path-simplify.esm.js +3593 -1279
  4. package/dist/svg-path-simplify.esm.min.js +2 -2
  5. package/dist/svg-path-simplify.js +3594 -1278
  6. package/dist/svg-path-simplify.min.js +2 -2
  7. package/dist/svg-path-simplify.pathdata.esm.js +1017 -538
  8. package/dist/svg-path-simplify.pathdata.esm.min.js +2 -2
  9. package/dist/svg-path-simplify.poly.cjs +9 -8
  10. package/docs/privacy-webapp.md +24 -0
  11. package/index.html +331 -152
  12. package/package.json +1 -1
  13. package/src/constants.js +4 -0
  14. package/src/css_parse.js +317 -0
  15. package/src/detect_input.js +76 -28
  16. package/src/index.js +8 -0
  17. package/src/pathData_simplify_cubic.js +26 -16
  18. package/src/pathData_simplify_harmonize_cpts.js +77 -1
  19. package/src/pathData_simplify_revertToquadratics.js +0 -1
  20. package/src/pathSimplify-main.js +304 -276
  21. package/src/pathSimplify-only-pathdata.js +7 -2
  22. package/src/pathSimplify-presets.js +254 -0
  23. package/src/poly-fit-curve-schneider.js +14 -7
  24. package/src/simplify_poly_RC.js +102 -0
  25. package/src/simplify_poly_RDP.js +109 -1
  26. package/src/simplify_poly_radial_distance.js +3 -3
  27. package/src/string_helpers.js +130 -4
  28. package/src/svg-getAttributes.js +4 -2
  29. package/src/svgii/convert_units.js +1 -1
  30. package/src/svgii/geometry.js +322 -5
  31. package/src/svgii/geometry_bbox_element.js +1 -1
  32. package/src/svgii/geometry_deduceRadius.js +116 -27
  33. package/src/svgii/geometry_length.js +253 -0
  34. package/src/svgii/pathData_analyze.js +18 -0
  35. package/src/svgii/pathData_convert.js +193 -89
  36. package/src/svgii/pathData_fix_directions.js +12 -14
  37. package/src/svgii/pathData_fromPoly.js +3 -3
  38. package/src/svgii/pathData_getLength.js +86 -0
  39. package/src/svgii/pathData_parse.js +2 -0
  40. package/src/svgii/pathData_parse_els.js +66 -68
  41. package/src/svgii/pathData_reorder.js +122 -16
  42. package/src/svgii/pathData_simplify_refineCorners.js +130 -35
  43. package/src/svgii/pathData_simplify_refine_round.js +420 -0
  44. package/src/svgii/pathData_split_to_groups.js +168 -0
  45. package/src/svgii/pathData_stringify.js +26 -64
  46. package/src/svgii/pathData_toPolygon.js +3 -4
  47. package/src/svgii/poly_analyze.js +61 -0
  48. package/src/svgii/poly_normalize.js +11 -2
  49. package/src/svgii/poly_to_pathdata.js +85 -24
  50. package/src/svgii/rounding.js +80 -78
  51. package/src/svgii/svg_cleanup.js +421 -619
  52. package/src/svgii/svg_cleanup_convertPathLength.js +39 -0
  53. package/src/svgii/svg_cleanup_general_svg_atts.js +97 -0
  54. package/src/svgii/svg_cleanup_normalize_transforms.js +83 -0
  55. package/src/svgii/svg_cleanup_remove_els_and_atts.js +77 -0
  56. package/src/svgii/svg_cleanup_ungroup.js +36 -0
  57. package/src/svgii/svg_el_parse_style_props.js +72 -47
  58. package/src/svgii/svg_getElementLength.js +67 -0
  59. package/src/svgii/svg_validate.js +220 -0
  60. package/tests/testSVG.js +14 -1
  61. package/src/svgii/pathData_refine_round.js +0 -222
@@ -3,16 +3,142 @@ import { isNumericValue } from "./svgii/convert_units"
3
3
  export function toCamelCase(str) {
4
4
  return str
5
5
  .split(/[-| ]/)
6
- .map((e,i) => i
6
+ .map((e, i) => i
7
7
  ? e.charAt(0).toUpperCase() + e.slice(1).toLowerCase()
8
8
  : e.toLowerCase()
9
9
  )
10
10
  .join('')
11
11
  }
12
12
 
13
- export function toShortStr(str){
14
- if(isNumericValue(str)) return str
15
- let strShort = str.split('-').map(str=>{return str.replace(/a|e|i|o|u/g,'') }).join('-')
13
+ export function toShortStr(str) {
14
+ if (isNumericValue(str)) return str
15
+ let strShort = str.split('-').map(str => { return str.replace(/a|e|i|o|u/g, '') }).join('-')
16
16
  strShort = toCamelCase(strShort)
17
17
  return strShort
18
18
  }
19
+
20
+
21
+ export function stringifySVG(svg, {
22
+ omitNamespace = false,
23
+ removeComments = true,
24
+ format = 0,
25
+ } = {}) {
26
+
27
+
28
+ let markup = '';
29
+
30
+ if (format < 2) {
31
+ markup = new XMLSerializer().serializeToString(svg);
32
+ //if (format === 0) markup = minifySVGMarkup(markup, { removeComments })
33
+ markup = minifySVGMarkup(markup, { removeComments })
34
+
35
+ } else {
36
+ markup = serializeSVGPretty(svg)
37
+ }
38
+
39
+
40
+ if (omitNamespace) {
41
+ markup = markup.replaceAll('xmlns="http://www.w3.org/2000/svg"', '')
42
+ }
43
+
44
+ if (removeComments) {
45
+ markup = markup
46
+ .replace(/(<!--.*?-->)|(<!--[\S\s]+?-->)|(<!--[\S\s]*?$)/g, '')
47
+ }
48
+
49
+ /*
50
+ markup = markup
51
+ .replace(/\t/g, "")
52
+ .replace(/[\n\r|]/g, "\n")
53
+ .replace(/\n\s*\n/g, '\n')
54
+ .replace(/ +/g, ' ')
55
+ //.replace(/ +/g, ' ')
56
+ .replace(/> </g, '><')
57
+ .trim()
58
+ // sanitize linebreaks within pathdata
59
+ .replaceAll('&#10;', '\n');
60
+ */
61
+
62
+ //console.log(markup);
63
+
64
+ return markup
65
+ }
66
+
67
+
68
+
69
+ export function minifySVGMarkup(svg, {
70
+ removeComments = true,
71
+ } = {}) {
72
+
73
+ if (removeComments) {
74
+ svg = svg.replace(/<!--[\s\S]*?-->/g, '')
75
+ }
76
+
77
+ // Remove whitespace between tags
78
+ svg = svg.replace(/>\s+</g, '><')
79
+ // Trim leading/trailing whitespace
80
+ .trim()
81
+ // Remove extra whitespace within tags (attributes)
82
+ .replace(/\s+([=])\s+/g, '$1')
83
+ .replace(/\s+(?=[^<]*>)/g, ' ')
84
+ // Collapse multiple spaces to single space
85
+ .replace(/\s{2,}/g, ' ')
86
+ // Remove spaces around = signs in attributes
87
+ .replace(/\s*=\s*/g, '=');
88
+
89
+ return svg
90
+ }
91
+
92
+ export function serializeSVGPretty(xmlDoc, {
93
+ indentSize = 2 } = {}) {
94
+ if (typeof xmlDoc === 'string') {
95
+ xmlDoc = new DOMParser().parseFromString(xmlDoc, 'image/svg+xml').querySelector('svg')
96
+ }
97
+ return formatXMLNode(xmlDoc, 0, indentSize);
98
+ }
99
+
100
+
101
+ function formatXMLNode(node, level, indentSize) {
102
+ let indent = " ".repeat(level * indentSize);
103
+
104
+ if (node.nodeType === Node.TEXT_NODE) {
105
+ let text = node.textContent.trim();
106
+ return text ? text : "";
107
+ }
108
+
109
+ if (node.nodeType === Node.ELEMENT_NODE) {
110
+ let hasChildren = node.children.length > 0;
111
+ let hasTextContent = node.textContent.trim().length > 0 && node.children.length === 0;
112
+
113
+ let result = `${indent}<${node.nodeName}`;
114
+
115
+ // Add attributes
116
+ for (let i = 0; i < node.attributes.length; i++) {
117
+ let att = node.attributes[i];
118
+ result += ` ${att.name}="${att.value}"`;
119
+ }
120
+
121
+ if (!hasChildren && !hasTextContent) {
122
+ return result + " />\n";
123
+ }
124
+
125
+ result += ">";
126
+
127
+ if (hasChildren) {
128
+ result += "\n";
129
+ for (let child of node.children) {
130
+ result += formatXMLNode(child, level + 1, indentSize);
131
+ }
132
+ result += `${indent}</${node.nodeName}>\n`;
133
+ } else if (hasTextContent) {
134
+ result += node.textContent.trim();
135
+ result += `</${node.nodeName}>\n`;
136
+ } else {
137
+ result += `</${node.nodeName}>\n`;
138
+ }
139
+
140
+ return result;
141
+ }
142
+
143
+ return "";
144
+ }
@@ -1,11 +1,13 @@
1
1
  import { normalizeUnits } from "./svgii/convert_units";
2
2
 
3
3
  export function getElementAtts(el, {x=0, y=0, width=0, height=0}={}){
4
- let attributes = [...el.attributes];
4
+ //let attributes = [...el.attributes];
5
+ let attributes = [...el.attributes].map(att=>att.name);
5
6
 
6
7
  let atts={};
7
8
  attributes.forEach(att=>{
8
- let value = normalizeUnits(att.nodeValue, {x, y, width, height});
9
+ //let value = normalizeUnits(att.nodeValue, {x, y, width, height});
10
+ let value = normalizeUnits(el.getAttribute(att), {x, y, width, height});
9
11
  atts[att.name] = value
10
12
  })
11
13
 
@@ -94,7 +94,7 @@ export function normalizeUnits(value = null, {
94
94
  scale = height / 100;
95
95
  }
96
96
  else {
97
- scale = normalizedDiagonal ? scaleRoot / 100 : 1;
97
+ scale = normalizedDiagonal ? scaleRoot / 100 : width / 100;
98
98
  }
99
99
  break;
100
100
 
@@ -3,7 +3,8 @@ import {abs, acos, asin, atan, atan2, ceil, cos, exp, floor,
3
3
  log, max, min, pow, random, round, sin, sqrt, tan, PI} from '/.constants.js';
4
4
  */
5
5
 
6
- import { rad2Deg, root2 } from "../constants";
6
+ import { deg2rad, rad2Deg, root2 } from "../constants";
7
+ //import { roundTo } from "./rounding";
7
8
  //import { getPolyBBox } from "./geometry_bbox";
8
9
  import { renderPoint } from "./visualize";
9
10
 
@@ -23,6 +24,11 @@ export function getAngle(p1, p2, normalize = false) {
23
24
  }
24
25
 
25
26
 
27
+
28
+
29
+
30
+
31
+
26
32
  export function getDeltaAngle2(centerPoint, startPoint, endPoint, largeArc = false) {
27
33
 
28
34
  const normalizeAngle = (angle) => {
@@ -315,6 +321,7 @@ export function pointAtT(pts, t = 0.5, getTangent = false, getCpts = false, retu
315
321
  let t1 = 1 - t;
316
322
 
317
323
  // cubic beziers
324
+ /*
318
325
  if (isCubic) {
319
326
  pt = {
320
327
  x:
@@ -330,11 +337,30 @@ export function pointAtT(pts, t = 0.5, getTangent = false, getCpts = false, retu
330
337
  };
331
338
 
332
339
  }
340
+ */
341
+
342
+ if (isCubic) {
343
+ pt = {
344
+ x:
345
+ t1 * t1 * t1 * p0.x +
346
+ 3 * t1 * t1 * t * cp1.x +
347
+ 3 * t1 * t * t * cp2.x +
348
+ t * t * t * p.x,
349
+ y:
350
+ t1 * t1 * t1 * p0.y +
351
+ 3 * t1 * t1 * t * cp1.y +
352
+ 3 * t1 * t * t * cp2.y +
353
+ t * t * t * p.y,
354
+ };
355
+
356
+ }
357
+
358
+
333
359
  // quadratic beziers
334
360
  else {
335
361
  pt = {
336
- x: t1 * t1 * p0.x + 2 * t1 * t * cp1.x + t ** 2 * p.x,
337
- y: t1 * t1 * p0.y + 2 * t1 * t * cp1.y + t ** 2 * p.y,
362
+ x: t1 * t1 * p0.x + 2 * t1 * t * cp1.x + t * t * p.x,
363
+ y: t1 * t1 * p0.y + 2 * t1 * t * cp1.y + t * t * p.y,
338
364
  };
339
365
  }
340
366
 
@@ -370,9 +396,40 @@ export function pointAtT(pts, t = 0.5, getTangent = false, getCpts = false, retu
370
396
 
371
397
 
372
398
 
399
+
373
400
  /**
374
401
  * get vertices from path command final on-path points
375
402
  */
403
+
404
+ export function getPathDataVertices(pathData=[], includeCpts = false, decimals = -1) {
405
+ let polyPoints = [];
406
+ //console.log(pathData);
407
+
408
+ pathData.forEach((com) => {
409
+ let { type, values } = com;
410
+
411
+ // get final on path point from last 2 values
412
+ if (values.length) {
413
+
414
+ // round
415
+ if (decimals > -1) values = values.map(val => +val.toFixed(decimals))
416
+
417
+ if (includeCpts) {
418
+
419
+ for (let i = 1; i < values.length; i += 2) {
420
+ polyPoints.push({ x: values[i - 1], y: values[i] });
421
+ }
422
+
423
+ } else {
424
+ polyPoints.push({ x: values[values.length - 2], y: values[values.length - 1] });
425
+ }
426
+
427
+ }
428
+ });
429
+ return polyPoints;
430
+ }
431
+
432
+ /*
376
433
  export function getPathDataVertices(pathData) {
377
434
  let polyPoints = [];
378
435
  let p0 = { x: pathData[0].values[0], y: pathData[0].values[1] };
@@ -389,6 +446,7 @@ export function getPathDataVertices(pathData) {
389
446
  });
390
447
  return polyPoints;
391
448
  };
449
+ */
392
450
 
393
451
 
394
452
 
@@ -396,7 +454,148 @@ export function getPathDataVertices(pathData) {
396
454
  * based on @cuixiping;
397
455
  * https://stackoverflow.com/questions/9017100/calculate-center-of-svg-arc/12329083#12329083
398
456
  */
399
- export function svgArcToCenterParam(x1, y1, rx, ry, xAxisRotation, largeArc, sweep, x2, y2) {
457
+
458
+
459
+ export function svgArcToCenterParam(x1, y1, rx, ry, xAxisRotation, largeArc, sweep, x2, y2, normalize = true
460
+ ) {
461
+
462
+ // helper for angle calculation
463
+ const getAngle = (cx, cy, x, y, normalize = true) => {
464
+ let angle = Math.atan2(y - cy, x - cx);
465
+ if (normalize && angle < 0) angle += Math.PI * 2
466
+ return angle
467
+ };
468
+
469
+ // make sure rx, ry are positive
470
+ rx = Math.abs(rx);
471
+ ry = Math.abs(ry);
472
+
473
+ // normalize xAxis rotation
474
+ xAxisRotation = rx === ry ? 0 : (xAxisRotation < 0 && normalize ? xAxisRotation + 360 : xAxisRotation);
475
+
476
+
477
+ // create data object
478
+ let arcData = {
479
+ cx: 0,
480
+ cy: 0,
481
+ // rx/ry values may be deceptive in arc commands
482
+ rx: rx,
483
+ ry: ry,
484
+ startAngle: 0,
485
+ endAngle: 0,
486
+ deltaAngle: 0,
487
+ clockwise: sweep,
488
+ // copy explicit arc properties
489
+ xAxisRotation,
490
+ largeArc,
491
+ sweep
492
+ };
493
+
494
+
495
+ if (rx == 0 || ry == 0) {
496
+ // invalid arguments
497
+ throw Error("rx and ry can not be 0");
498
+ }
499
+
500
+
501
+ /**
502
+ * if rx===ry x-axis rotation is ignored
503
+ * otherwise convert degrees to radians
504
+ */
505
+ let phi = rx === ry ? 0 : xAxisRotation * deg2rad;
506
+ let cx, cy
507
+
508
+ let s_phi = !phi ? 0 : Math.sin(phi);
509
+ let c_phi = !phi ? 1 : Math.cos(phi);
510
+
511
+ let hd_x = (x1 - x2) / 2;
512
+ let hd_y = (y1 - y2) / 2;
513
+ let hs_x = (x1 + x2) / 2;
514
+ let hs_y = (y1 + y2) / 2;
515
+
516
+ // F6.5.1
517
+ let x1_ = !phi ? hd_x : c_phi * hd_x + s_phi * hd_y;
518
+ let y1_ = !phi ? hd_y : c_phi * hd_y - s_phi * hd_x;
519
+
520
+ // F.6.6 Correction of out-of-range radii
521
+ // Step 3: Ensure radii are large enough
522
+ let lambda = (x1_ * x1_) / (rx * rx) + (y1_ * y1_) / (ry * ry);
523
+ if (lambda > 1) {
524
+ let lambdaRoot = Math.sqrt(lambda);
525
+ rx = rx * lambdaRoot;
526
+ ry = ry * lambdaRoot;
527
+
528
+ // save real rx/ry
529
+ arcData.rx = rx;
530
+ arcData.ry = ry;
531
+ }
532
+
533
+ let rxry = rx * ry;
534
+ let rxy1_ = rx * y1_;
535
+ let ryx1_ = ry * x1_;
536
+ let sum_of_sq = rxy1_ ** 2 + ryx1_ ** 2; // sum of square
537
+ if (!sum_of_sq) {
538
+ //console.log('error:', rx, ry, rxy1_, ryx1_);
539
+ throw Error("start point can not be same as end point");
540
+ }
541
+ let coe = Math.sqrt(Math.abs((rxry * rxry - sum_of_sq) / sum_of_sq));
542
+ if (largeArc === sweep) {
543
+ coe = -coe;
544
+ }
545
+
546
+ // F6.5.2
547
+ let cx_ = (coe * rxy1_) / ry;
548
+ let cy_ = (-coe * ryx1_) / rx;
549
+
550
+ /** F6.5.3
551
+ * center point of ellipse
552
+ */
553
+ cx = !phi ? hs_x + cx_ : c_phi * cx_ - s_phi * cy_ + hs_x;
554
+ cy = !phi ? hs_y + cy_ : s_phi * cx_ + c_phi * cy_ + hs_y;
555
+ arcData.cy = cy;
556
+ arcData.cx = cx;
557
+
558
+ /** F6.5.5
559
+ * calculate angles between center point and
560
+ * commands starting and final on path point
561
+ */
562
+ let startAngle = getAngle(cx, cy, x1, y1, normalize);
563
+ let endAngle = getAngle(cx, cy, x2, y2, normalize);
564
+
565
+ // adjust end angle
566
+
567
+ // Adjust angles based on sweep direction
568
+ if (sweep) {
569
+ // Clockwise
570
+ if (endAngle < startAngle) {
571
+ endAngle += Math.PI * 2;
572
+ }
573
+ } else {
574
+ // Counterclockwise
575
+ if (endAngle > startAngle) {
576
+ endAngle -= Math.PI * 2;
577
+ }
578
+ }
579
+
580
+ let deltaAngle = endAngle - startAngle;
581
+
582
+ // The rest of your code remains the same
583
+ arcData.startAngle = startAngle;
584
+ arcData.startAngle_deg = startAngle * rad2Deg;
585
+ arcData.endAngle = endAngle;
586
+ arcData.endAngle_deg = endAngle * rad2Deg;
587
+ arcData.deltaAngle = deltaAngle;
588
+ arcData.deltaAngle_deg = deltaAngle * rad2Deg;
589
+
590
+ //console.log('arc', arcData);
591
+ return arcData;
592
+ }
593
+
594
+
595
+
596
+
597
+
598
+ export function svgArcToCenterParam_back(x1, y1, rx, ry, xAxisRotation, largeArc, sweep, x2, y2) {
400
599
 
401
600
  // helper for angle calculation
402
601
  const getAngle = (cx, cy, x, y) => {
@@ -784,6 +983,124 @@ export function getBezierExtremeT(pts, { addExtremes = true, addSemiExtremes = f
784
983
  * https://stackoverflow.com/questions/87734/#75031511
785
984
  * See also: https://github.com/foo123/Geometrize
786
985
  */
986
+
987
+ export function getArcExtemesParam({
988
+ cx=0, cy=0, rx=0, ry=0,
989
+ p=null,
990
+ p0=null,
991
+ endAngle=0,
992
+ deltaAngle=0,
993
+
994
+
995
+ }={}) {
996
+ // compute point on ellipse from angle around ellipse (theta)
997
+ const arc = (theta, cx, cy, rx, ry, alpha) => {
998
+ // theta is angle in radians around arc
999
+ // alpha is angle of rotation of ellipse in radians
1000
+ var cos = Math.cos(alpha),
1001
+ sin = Math.sin(alpha),
1002
+ x = rx * Math.cos(theta),
1003
+ y = ry * Math.sin(theta);
1004
+
1005
+ return {
1006
+ x: cx + cos * x - sin * y,
1007
+ y: cy + sin * x + cos * y
1008
+ };
1009
+ }
1010
+
1011
+ //parametrize arcto data
1012
+ //let arcData = svgArcToCenterParam(p0.x, p0.y, values[0], values[1], values[2], values[3], values[4], values[5], values[6]);
1013
+ //let { rx, ry, cx, cy, endAngle, deltaAngle } = arcData;
1014
+
1015
+ // arc rotation
1016
+ let deg = values[2];
1017
+
1018
+ // final on path point
1019
+ //let p = { x: values[5], y: values[6] }
1020
+
1021
+ // collect extreme points – add end point
1022
+ let extremes = [p]
1023
+
1024
+ // rotation to radians
1025
+ let alpha = deg * Math.PI / 180;
1026
+ let tan = Math.tan(alpha),
1027
+ p1, p2, p3, p4, theta;
1028
+
1029
+ /**
1030
+ * find min/max from zeroes of directional derivative along x and y
1031
+ * along x axis
1032
+ */
1033
+ theta = Math.atan2(-ry * tan, rx);
1034
+
1035
+ let angle1 = theta;
1036
+ let angle2 = theta + Math.PI;
1037
+ let angle3 = Math.atan2(ry, rx * tan);
1038
+ let angle4 = angle3 + Math.PI;
1039
+
1040
+
1041
+ // inner bounding box
1042
+ let xArr = [p0.x, p.x]
1043
+ let yArr = [p0.y, p.y]
1044
+ let xMin = Math.min(...xArr)
1045
+ let xMax = Math.max(...xArr)
1046
+ let yMin = Math.min(...yArr)
1047
+ let yMax = Math.max(...yArr)
1048
+
1049
+
1050
+ // on path point close after start
1051
+ let angleAfterStart = endAngle - deltaAngle * 0.001
1052
+ let pP2 = arc(angleAfterStart, cx, cy, rx, ry, alpha);
1053
+
1054
+ // on path point close before end
1055
+ let angleBeforeEnd = endAngle - deltaAngle * 0.999
1056
+ let pP3 = arc(angleBeforeEnd, cx, cy, rx, ry, alpha);
1057
+
1058
+
1059
+ /**
1060
+ * expected extremes
1061
+ * if leaving inner bounding box
1062
+ * (between segment start and end point)
1063
+ * otherwise exclude elliptic extreme points
1064
+ */
1065
+
1066
+ // right
1067
+ if (pP2.x > xMax || pP3.x > xMax) {
1068
+ // get point for this theta
1069
+ p1 = arc(angle1, cx, cy, rx, ry, alpha);
1070
+ extremes.push(p1)
1071
+ }
1072
+
1073
+ // left
1074
+ if (pP2.x < xMin || pP3.x < xMin) {
1075
+ // get anti-symmetric point
1076
+ p2 = arc(angle2, cx, cy, rx, ry, alpha);
1077
+ extremes.push(p2)
1078
+ }
1079
+
1080
+ // top
1081
+ if (pP2.y < yMin || pP3.y < yMin) {
1082
+ // get anti-symmetric point
1083
+ p4 = arc(angle4, cx, cy, rx, ry, alpha);
1084
+ extremes.push(p4)
1085
+ }
1086
+
1087
+ // bottom
1088
+ if (pP2.y > yMax || pP3.y > yMax) {
1089
+ // get point for this theta
1090
+ p3 = arc(angle3, cx, cy, rx, ry, alpha);
1091
+ extremes.push(p3)
1092
+ }
1093
+
1094
+ return extremes;
1095
+ }
1096
+
1097
+
1098
+
1099
+
1100
+
1101
+
1102
+
1103
+
787
1104
  export function getArcExtemes(p0, values) {
788
1105
  // compute point on ellipse from angle around ellipse (theta)
789
1106
  const arc = (theta, cx, cy, rx, ry, alpha) => {
@@ -1292,7 +1609,7 @@ export function getDistance(p1, p2, isArray = false) {
1292
1609
  let dy = isArray ? p2[1] - p1[1] : (p2.y - p1.y);
1293
1610
 
1294
1611
  //console.log('dx', dx, dy, p1, p2);
1295
- return sqrt(dx * dx + dy * dy);
1612
+ return Math.sqrt(dx * dx + dy * dy);
1296
1613
  }
1297
1614
 
1298
1615
  // just an alias
@@ -12,7 +12,7 @@ export function getElBBox(el){
12
12
 
13
13
  switch(type){
14
14
  case 'path':
15
- let pathData = parsePathDataNormalized(atts.d)
15
+ let pathData = parsePathDataNormalized(el.getAttribute('d'))
16
16
  bb=getPolyBBox(getPathDataPoly(pathData))
17
17
 
18
18
  break;