svg-path-commander 0.1.10-alpha2 → 0.1.10-alpha3
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/dist/svg-path-commander.esm.js +172 -146
- package/dist/svg-path-commander.esm.min.js +2 -2
- package/dist/svg-path-commander.js +174 -149
- package/dist/svg-path-commander.min.js +2 -2
- package/package.json +1 -1
- package/src/math/rotateVector.js +3 -2
- package/src/parser/finalizeSegment.js +2 -0
- package/src/parser/isArcCommand.js +1 -1
- package/src/parser/isDigit.js +1 -1
- package/src/parser/isDigitStart.js +1 -1
- package/src/parser/isSpace.js +5 -6
- package/src/parser/parsePathString.js +2 -1
- package/src/process/arcToCubic.js +59 -71
- package/src/process/fixArc.js +2 -0
- package/src/process/getSVGMatrix.js +5 -0
- package/src/process/lineToCubic.js +7 -5
- package/src/process/normalizeSegment.js +3 -3
- package/src/process/reverseCurve.js +3 -2
- package/src/process/shorthandToCubic.js +6 -6
- package/src/process/shorthandToQuad.js +6 -6
- package/src/process/splitCubic.js +2 -2
- package/src/util/getCubicSize.js +4 -2
- package/src/util/getPathArea.js +3 -1
- package/src/util/getPathBBox.js +14 -10
- package/src/util/getPathLength.js +2 -1
- package/src/util/getPointAtLength.js +5 -3
- package/src/util/getPointAtSegLength.js +9 -9
- package/src/util/getSegArcLength.js +2 -2
- package/src/util/getSegCubicLength.js +19 -11
- package/src/util/getSegLineLength.js +5 -5
- package/src/util/getSegQuadLength.js +8 -8
- package/src/util/shapeToPath.js +7 -1
- package/types/index.d.ts +73 -66
- package/types/types.d.ts +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* SVGPathCommander v0.1.
|
|
2
|
+
* SVGPathCommander v0.1.10alpha3 (http://thednp.github.io/svg-path-commander)
|
|
3
3
|
* Copyright 2021 © thednp
|
|
4
4
|
* Licensed under MIT (https://github.com/thednp/svg-path-commander/blob/master/LICENSE)
|
|
5
5
|
*/
|
|
@@ -39,9 +39,11 @@ function finalizeSegment(path) {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
if (pathComLK === 'r') {
|
|
42
|
+
// @ts-ignore
|
|
42
43
|
path.segments.push([pathCommand].concat(params));
|
|
43
44
|
} else {
|
|
44
45
|
while (params.length >= paramsCount[pathComLK]) {
|
|
46
|
+
// @ts-ignore
|
|
45
47
|
path.segments.push([pathCommand].concat(params.splice(0, paramsCount[pathComLK])));
|
|
46
48
|
if (!paramsCount[pathComLK]) {
|
|
47
49
|
break;
|
|
@@ -80,7 +82,7 @@ function scanFlag(path) {
|
|
|
80
82
|
/**
|
|
81
83
|
* Checks if a character is a digit.
|
|
82
84
|
*
|
|
83
|
-
* @param {
|
|
85
|
+
* @param {number} code the character to check
|
|
84
86
|
* @returns {boolean} check result
|
|
85
87
|
*/
|
|
86
88
|
function isDigit(code) {
|
|
@@ -185,18 +187,17 @@ function scanParam(path) {
|
|
|
185
187
|
/**
|
|
186
188
|
* Checks if the character is a space.
|
|
187
189
|
*
|
|
188
|
-
* @param {
|
|
190
|
+
* @param {number} ch the character to check
|
|
189
191
|
* @returns {boolean} check result
|
|
190
192
|
*/
|
|
191
|
-
function isSpace(
|
|
193
|
+
function isSpace(ch) {
|
|
192
194
|
const specialSpaces = [
|
|
193
195
|
0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006,
|
|
194
196
|
0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF];
|
|
195
|
-
// Line terminators
|
|
196
|
-
return (code === 0x0A) || (code === 0x0D) || (code === 0x2028) || (code === 0x2029)
|
|
197
|
+
return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029) // Line terminators
|
|
197
198
|
// White spaces
|
|
198
|
-
|| (
|
|
199
|
-
|| (
|
|
199
|
+
|| (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0)
|
|
200
|
+
|| (ch >= 0x1680 && specialSpaces.indexOf(ch) >= 0);
|
|
200
201
|
}
|
|
201
202
|
|
|
202
203
|
/**
|
|
@@ -243,7 +244,7 @@ function isPathCommand(code) {
|
|
|
243
244
|
* Checks if the character is or belongs to a number.
|
|
244
245
|
* [0-9]|+|-|.
|
|
245
246
|
*
|
|
246
|
-
* @param {
|
|
247
|
+
* @param {number} code the character to check
|
|
247
248
|
* @returns {boolean} check result
|
|
248
249
|
*/
|
|
249
250
|
function isDigitStart(code) {
|
|
@@ -256,7 +257,7 @@ function isDigitStart(code) {
|
|
|
256
257
|
/**
|
|
257
258
|
* Checks if the character is an A (arc-to) path command.
|
|
258
259
|
*
|
|
259
|
-
* @param {
|
|
260
|
+
* @param {number} code the character to check
|
|
260
261
|
* @returns {boolean} check result
|
|
261
262
|
*/
|
|
262
263
|
function isArcCommand(code) {
|
|
@@ -387,9 +388,10 @@ function isPathArray(path) {
|
|
|
387
388
|
*/
|
|
388
389
|
function parsePathString(pathInput) {
|
|
389
390
|
if (isPathArray(pathInput)) {
|
|
391
|
+
// @ts-ignore
|
|
390
392
|
return clonePath(pathInput);
|
|
391
393
|
}
|
|
392
|
-
|
|
394
|
+
// @ts-ignore
|
|
393
395
|
const path = new SVGPathArray(pathInput);
|
|
394
396
|
|
|
395
397
|
skipSpaces(path);
|
|
@@ -672,12 +674,12 @@ function pathToString(path, round) {
|
|
|
672
674
|
* Returns the missing control point from an
|
|
673
675
|
* T (shorthand quadratic bezier) segment.
|
|
674
676
|
*
|
|
675
|
-
* @param {
|
|
676
|
-
* @param {
|
|
677
|
-
* @param {
|
|
678
|
-
* @param {
|
|
679
|
-
* @param {
|
|
680
|
-
* @returns {
|
|
677
|
+
* @param {number} x1 curve start x
|
|
678
|
+
* @param {number} y1 curve start y
|
|
679
|
+
* @param {number} qx control point x
|
|
680
|
+
* @param {number} qy control point y
|
|
681
|
+
* @param {string} prevCommand the previous path command
|
|
682
|
+
* @returns {{qx: number, qy: number}}} the missing control point
|
|
681
683
|
*/
|
|
682
684
|
function shorthandToQuad(x1, y1, qx, qy, prevCommand) {
|
|
683
685
|
return 'QT'.indexOf(prevCommand) > -1
|
|
@@ -689,12 +691,12 @@ function shorthandToQuad(x1, y1, qx, qy, prevCommand) {
|
|
|
689
691
|
* Returns the missing control point from an
|
|
690
692
|
* S (shorthand cubic bezier) segment.
|
|
691
693
|
*
|
|
692
|
-
* @param {
|
|
693
|
-
* @param {
|
|
694
|
-
* @param {
|
|
695
|
-
* @param {
|
|
696
|
-
* @param {
|
|
697
|
-
* @returns {
|
|
694
|
+
* @param {number} x1 curve start x
|
|
695
|
+
* @param {number} y1 curve start y
|
|
696
|
+
* @param {number} x2 curve end x
|
|
697
|
+
* @param {number} y2 curve end y
|
|
698
|
+
* @param {string} prevCommand the previous path command
|
|
699
|
+
* @returns {{x1: number, y1: number}}} the missing control point
|
|
698
700
|
*/
|
|
699
701
|
function shorthandToCubic(x1, y1, x2, y2, prevCommand) {
|
|
700
702
|
return 'CS'.indexOf(prevCommand) > -1
|
|
@@ -706,14 +708,14 @@ function shorthandToCubic(x1, y1, x2, y2, prevCommand) {
|
|
|
706
708
|
* Normalizes a single segment of a `pathArray` object.
|
|
707
709
|
*
|
|
708
710
|
* @param {SVGPC.pathSegment} segment the segment object
|
|
709
|
-
* @param {
|
|
711
|
+
* @param {any} params the coordinates of the previous segment
|
|
710
712
|
* @param {String} prevCommand the path command of the previous segment
|
|
711
|
-
* @returns {
|
|
713
|
+
* @returns {any} the normalized segment
|
|
712
714
|
*/
|
|
713
715
|
function normalizeSegment(segment, params, prevCommand) {
|
|
714
716
|
const [pathCommand] = segment;
|
|
715
717
|
const xy = segment.slice(1);
|
|
716
|
-
let result = segment;
|
|
718
|
+
let result = segment.slice();
|
|
717
719
|
|
|
718
720
|
if ('TQ'.indexOf(segment[0]) < 0) {
|
|
719
721
|
// optional but good to be cautious
|
|
@@ -940,8 +942,9 @@ const epsilon = 1e-9;
|
|
|
940
942
|
* Returns an {x,y} vector rotated by a given
|
|
941
943
|
* angle in radian.
|
|
942
944
|
*
|
|
943
|
-
* @param {
|
|
944
|
-
* @param {
|
|
945
|
+
* @param {number} x the initial vector x
|
|
946
|
+
* @param {number} y the initial vector y
|
|
947
|
+
* @param {number} rad the radian vector angle
|
|
945
948
|
* @returns {{x: number, y: number}} the rotated vector
|
|
946
949
|
*/
|
|
947
950
|
function rotateVector(x, y, rad) {
|
|
@@ -956,29 +959,27 @@ function rotateVector(x, y, rad) {
|
|
|
956
959
|
* For more information of where this math came from visit:
|
|
957
960
|
* http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
|
|
958
961
|
*
|
|
959
|
-
* @param {number}
|
|
960
|
-
* @param {number}
|
|
961
|
-
* @param {number}
|
|
962
|
-
* @param {number}
|
|
962
|
+
* @param {number} X1 the starting x position
|
|
963
|
+
* @param {number} Y1 the starting y position
|
|
964
|
+
* @param {number} RX x-radius of the arc
|
|
965
|
+
* @param {number} RY y-radius of the arc
|
|
963
966
|
* @param {number} angle x-axis-rotation of the arc
|
|
964
967
|
* @param {number} LAF large-arc-flag of the arc
|
|
965
968
|
* @param {number} SF sweep-flag of the arc
|
|
966
|
-
* @param {number}
|
|
967
|
-
* @param {number}
|
|
969
|
+
* @param {number} X2 the ending x position
|
|
970
|
+
* @param {number} Y2 the ending y position
|
|
968
971
|
* @param {number[] | null} recursive the parameters needed to split arc into 2 segments
|
|
969
|
-
* @return {
|
|
972
|
+
* @return {any} the resulting cubic-bezier segment(s)
|
|
970
973
|
*/
|
|
971
|
-
function arcToCubic(x1, y1, rx, ry, angle, LAF, SF, x2, y2, recursive) {
|
|
974
|
+
// export default function arcToCubic(x1, y1, rx, ry, angle, LAF, SF, x2, y2, recursive) {
|
|
975
|
+
function arcToCubic(X1, Y1, RX, RY, angle, LAF, SF, X2, Y2, recursive) {
|
|
976
|
+
let x1 = X1; let y1 = Y1; let rx = RX; let ry = RY; let x2 = X2; let y2 = Y2;
|
|
977
|
+
// for more information of where this Math came from visit:
|
|
978
|
+
// http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
|
|
972
979
|
const d120 = (Math.PI * 120) / 180;
|
|
973
|
-
|
|
974
|
-
|
|
980
|
+
|
|
981
|
+
const rad = (Math.PI / 180) * (+angle || 0);
|
|
975
982
|
let res = [];
|
|
976
|
-
let X1 = x1;
|
|
977
|
-
let X2 = x2;
|
|
978
|
-
let Y1 = y1;
|
|
979
|
-
let Y2 = y2;
|
|
980
|
-
let RX = rx;
|
|
981
|
-
let RY = ry;
|
|
982
983
|
let xy;
|
|
983
984
|
let f1;
|
|
984
985
|
let f2;
|
|
@@ -986,41 +987,39 @@ function arcToCubic(x1, y1, rx, ry, angle, LAF, SF, x2, y2, recursive) {
|
|
|
986
987
|
let cy;
|
|
987
988
|
|
|
988
989
|
if (!recursive) {
|
|
989
|
-
xy = rotateVector(
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
xy = rotateVector(
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
const x = (
|
|
997
|
-
const y = (
|
|
998
|
-
let h = (x
|
|
990
|
+
xy = rotateVector(x1, y1, -rad);
|
|
991
|
+
x1 = xy.x;
|
|
992
|
+
y1 = xy.y;
|
|
993
|
+
xy = rotateVector(x2, y2, -rad);
|
|
994
|
+
x2 = xy.x;
|
|
995
|
+
y2 = xy.y;
|
|
996
|
+
|
|
997
|
+
const x = (x1 - x2) / 2;
|
|
998
|
+
const y = (y1 - y2) / 2;
|
|
999
|
+
let h = (x * x) / (rx * rx) + (y * y) / (ry * ry);
|
|
999
1000
|
if (h > 1) {
|
|
1000
1001
|
h = Math.sqrt(h);
|
|
1001
|
-
|
|
1002
|
-
|
|
1002
|
+
rx *= h;
|
|
1003
|
+
ry *= h;
|
|
1003
1004
|
}
|
|
1004
|
-
const rx2 =
|
|
1005
|
-
const ry2 =
|
|
1006
|
-
const k = (LAF === SF ? -1 : 1)
|
|
1007
|
-
* Math.sqrt(Math.abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x)
|
|
1008
|
-
/ (rx2 * y * y + ry2 * x * x)));
|
|
1005
|
+
const rx2 = rx * rx;
|
|
1006
|
+
const ry2 = ry * ry;
|
|
1009
1007
|
|
|
1010
|
-
|
|
1011
|
-
|
|
1008
|
+
const k = (LAF === SF ? -1 : 1)
|
|
1009
|
+
* Math.sqrt(Math.abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x)
|
|
1010
|
+
/ (rx2 * y * y + ry2 * x * x)));
|
|
1012
1011
|
|
|
1012
|
+
cx = ((k * rx * y) / ry) + ((x1 + x2) / 2);
|
|
1013
|
+
cy = ((k * -ry * x) / rx) + ((y1 + y2) / 2);
|
|
1013
1014
|
// eslint-disable-next-line no-bitwise -- Impossible to satisfy no-bitwise
|
|
1014
|
-
f1 = Math.asin((((
|
|
1015
|
+
f1 = (Math.asin((((y1 - cy) / ry))) * (10 ** 9) >> 0) / (10 ** 9);
|
|
1015
1016
|
// eslint-disable-next-line no-bitwise -- Impossible to satisfy no-bitwise
|
|
1016
|
-
f2 = Math.asin((((
|
|
1017
|
-
|
|
1018
|
-
f1 = X1 < cx ? Math.PI - f1 : f1;
|
|
1019
|
-
f2 = X2 < cx ? Math.PI - f2 : f2;
|
|
1020
|
-
|
|
1021
|
-
if (f1 < 0) { f1 = Math.PI * 2 + f1; }
|
|
1022
|
-
if (f2 < 0) { f2 = Math.PI * 2 + f2; }
|
|
1017
|
+
f2 = (Math.asin((((y2 - cy) / ry))) * (10 ** 9) >> 0) / (10 ** 9);
|
|
1023
1018
|
|
|
1019
|
+
f1 = x1 < cx ? Math.PI - f1 : f1;
|
|
1020
|
+
f2 = x2 < cx ? Math.PI - f2 : f2;
|
|
1021
|
+
if (f1 < 0) (f1 = Math.PI * 2 + f1);
|
|
1022
|
+
if (f2 < 0) (f2 = Math.PI * 2 + f2);
|
|
1024
1023
|
if (SF && f1 > f2) {
|
|
1025
1024
|
f1 -= Math.PI * 2;
|
|
1026
1025
|
}
|
|
@@ -1028,51 +1027,43 @@ function arcToCubic(x1, y1, rx, ry, angle, LAF, SF, x2, y2, recursive) {
|
|
|
1028
1027
|
f2 -= Math.PI * 2;
|
|
1029
1028
|
}
|
|
1030
1029
|
} else {
|
|
1031
|
-
|
|
1032
|
-
f1 = r1;
|
|
1033
|
-
f2 = r2;
|
|
1034
|
-
cx = r3;
|
|
1035
|
-
cy = r4;
|
|
1030
|
+
[f1, f2, cx, cy] = recursive;
|
|
1036
1031
|
}
|
|
1037
|
-
|
|
1038
1032
|
let df = f2 - f1;
|
|
1039
|
-
|
|
1040
1033
|
if (Math.abs(df) > d120) {
|
|
1041
1034
|
const f2old = f2;
|
|
1042
|
-
const x2old =
|
|
1043
|
-
const y2old =
|
|
1044
|
-
|
|
1035
|
+
const x2old = x2;
|
|
1036
|
+
const y2old = y2;
|
|
1045
1037
|
f2 = f1 + d120 * (SF && f2 > f1 ? 1 : -1);
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
res = arcToCubic(
|
|
1038
|
+
x2 = cx + rx * Math.cos(f2);
|
|
1039
|
+
y2 = cy + ry * Math.sin(f2);
|
|
1040
|
+
res = arcToCubic(x2, y2, rx, ry, angle, 0, SF, x2old, y2old, [f2, f2old, cx, cy]);
|
|
1049
1041
|
}
|
|
1050
|
-
|
|
1051
1042
|
df = f2 - f1;
|
|
1052
1043
|
const c1 = Math.cos(f1);
|
|
1053
1044
|
const s1 = Math.sin(f1);
|
|
1054
1045
|
const c2 = Math.cos(f2);
|
|
1055
1046
|
const s2 = Math.sin(f2);
|
|
1056
1047
|
const t = Math.tan(df / 4);
|
|
1057
|
-
const hx = (4 / 3) *
|
|
1058
|
-
const hy = (4 / 3) *
|
|
1059
|
-
const m1 = [
|
|
1060
|
-
const m2 = [
|
|
1061
|
-
const m3 = [
|
|
1062
|
-
const m4 = [
|
|
1048
|
+
const hx = (4 / 3) * rx * t;
|
|
1049
|
+
const hy = (4 / 3) * ry * t;
|
|
1050
|
+
const m1 = [x1, y1];
|
|
1051
|
+
const m2 = [x1 + hx * s1, y1 - hy * c1];
|
|
1052
|
+
const m3 = [x2 + hx * s2, y2 - hy * c2];
|
|
1053
|
+
const m4 = [x2, y2];
|
|
1063
1054
|
m2[0] = 2 * m1[0] - m2[0];
|
|
1064
1055
|
m2[1] = 2 * m1[1] - m2[1];
|
|
1065
|
-
|
|
1066
1056
|
if (recursive) {
|
|
1067
|
-
return [m2, m3, m4].concat(res)
|
|
1057
|
+
return [m2, m3, m4].concat(res);
|
|
1068
1058
|
}
|
|
1069
|
-
res = [m2, m3, m4].concat(res).join().split(',')
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
}
|
|
1059
|
+
res = [m2, m3, m4].concat(res).join().split(',');
|
|
1060
|
+
const newres = [];
|
|
1061
|
+
for (let i = 0, ii = res.length; i < ii; i += 1) {
|
|
1062
|
+
newres[i] = i % 2
|
|
1063
|
+
// @ts-ignore
|
|
1064
|
+
? rotateVector(res[i - 1], res[i], rad).y : rotateVector(res[i], res[i + 1], rad).x;
|
|
1065
|
+
}
|
|
1066
|
+
return newres;
|
|
1076
1067
|
}
|
|
1077
1068
|
|
|
1078
1069
|
/**
|
|
@@ -1102,15 +1093,15 @@ function quadToCubic(x1, y1, qx, qy, x2, y2) {
|
|
|
1102
1093
|
* Returns the {x,y} coordinates of a point at a
|
|
1103
1094
|
* given length of a cubic-bezier segment.
|
|
1104
1095
|
*
|
|
1105
|
-
* @param {
|
|
1106
|
-
* @param {
|
|
1107
|
-
* @param {
|
|
1108
|
-
* @param {
|
|
1109
|
-
* @param {
|
|
1110
|
-
* @param {
|
|
1111
|
-
* @param {
|
|
1112
|
-
* @param {
|
|
1113
|
-
* @param {
|
|
1096
|
+
* @param {number} p1x the starting point X
|
|
1097
|
+
* @param {number} p1y the starting point Y
|
|
1098
|
+
* @param {number} c1x the first control point X
|
|
1099
|
+
* @param {number} c1y the first control point Y
|
|
1100
|
+
* @param {number} c2x the second control point X
|
|
1101
|
+
* @param {number} c2y the second control point Y
|
|
1102
|
+
* @param {number} p2x the ending point X
|
|
1103
|
+
* @param {number} p2y the ending point Y
|
|
1104
|
+
* @param {number} t a [0-1] ratio
|
|
1114
1105
|
* @returns {{x: number, y: number}} the requested {x,y} coordinates
|
|
1115
1106
|
*/
|
|
1116
1107
|
function getPointAtSegLength(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {
|
|
@@ -1144,11 +1135,11 @@ function midPoint(a, b, t) {
|
|
|
1144
1135
|
/**
|
|
1145
1136
|
* Converts an L (line-to) segment to C (cubic-bezier).
|
|
1146
1137
|
*
|
|
1147
|
-
* @param {
|
|
1148
|
-
* @param {
|
|
1149
|
-
* @param {
|
|
1150
|
-
* @param {
|
|
1151
|
-
* @returns {
|
|
1138
|
+
* @param {number} x1 line start x
|
|
1139
|
+
* @param {number} y1 line start y
|
|
1140
|
+
* @param {number} x2 line end x
|
|
1141
|
+
* @param {number} y2 line end y
|
|
1142
|
+
* @returns {number[]} the cubic-bezier segment
|
|
1152
1143
|
*/
|
|
1153
1144
|
function lineToCubic(x1, y1, x2, y2) {
|
|
1154
1145
|
const t = 0.5;
|
|
@@ -1159,7 +1150,9 @@ function lineToCubic(x1, y1, x2, y2) {
|
|
|
1159
1150
|
const p4 = midPoint(p2, p3, t);
|
|
1160
1151
|
const p5 = midPoint(p3, p4, t);
|
|
1161
1152
|
const p6 = midPoint(p4, p5, t);
|
|
1153
|
+
// @ts-ignore
|
|
1162
1154
|
const cp1 = getPointAtSegLength.apply(0, p0.concat(p2, p4, p6, t));
|
|
1155
|
+
// @ts-ignore
|
|
1163
1156
|
const cp2 = getPointAtSegLength.apply(0, p6.concat(p5, p3, p1, 0));
|
|
1164
1157
|
|
|
1165
1158
|
return [cp1.x, cp1.y, cp2.x, cp2.y, x2, y2];
|
|
@@ -1219,6 +1212,8 @@ function fixArc(path, allPathCommands, i) {
|
|
|
1219
1212
|
while (segment.length) {
|
|
1220
1213
|
// if created multiple C:s, their original seg is saved
|
|
1221
1214
|
allPathCommands[i] = 'A';
|
|
1215
|
+
// path.splice(i++, 0, ['C'].concat(segment.splice(0, 6)));
|
|
1216
|
+
// @ts-ignore
|
|
1222
1217
|
path.splice(ni += 1, 0, ['C'].concat(segment.splice(0, 6)));
|
|
1223
1218
|
}
|
|
1224
1219
|
path.splice(i, 1);
|
|
@@ -2045,18 +2040,21 @@ function getSVGMatrix(transform) {
|
|
|
2045
2040
|
if ((Array.isArray(translate) && translate.some((x) => +x !== 0)) || !Number.isNaN(translate)) {
|
|
2046
2041
|
matrix = Array.isArray(translate)
|
|
2047
2042
|
? matrix.translate(+translate[0] || 0, +translate[1] || 0, +translate[2] || 0)
|
|
2043
|
+
// @ts-ignore
|
|
2048
2044
|
: matrix.translate(+translate || 0);
|
|
2049
2045
|
}
|
|
2050
2046
|
|
|
2051
2047
|
if (rotate || skew || scale) {
|
|
2052
2048
|
// set SVG transform-origin, always defined
|
|
2053
2049
|
// matrix = matrix.translate(+originX,+originY,+originZ)
|
|
2050
|
+
// @ts-ignore
|
|
2054
2051
|
matrix = matrix.translate(+originX, +originY);
|
|
2055
2052
|
|
|
2056
2053
|
// set rotation
|
|
2057
2054
|
if (rotate) {
|
|
2058
2055
|
matrix = Array.isArray(rotate) && rotate.some((x) => +x !== 0)
|
|
2059
2056
|
? matrix.rotate(+rotate[0] || 0, +rotate[1] || 0, +rotate[2] || 0)
|
|
2057
|
+
// @ts-ignore
|
|
2060
2058
|
: matrix.rotate(+rotate || 0);
|
|
2061
2059
|
}
|
|
2062
2060
|
// set skew(s)
|
|
@@ -2072,10 +2070,12 @@ function getSVGMatrix(transform) {
|
|
|
2072
2070
|
if (!Number.isNaN(scale) || (Array.isArray(scale) && scale.some((x) => +x !== 1))) {
|
|
2073
2071
|
matrix = Array.isArray(scale)
|
|
2074
2072
|
? (matrix.scale(+scale[0] || 1, +scale[1] || 1, +scale[2] || 1))
|
|
2073
|
+
// @ts-ignore
|
|
2075
2074
|
: matrix.scale(+scale || 1);
|
|
2076
2075
|
}
|
|
2077
2076
|
// set SVG transform-origin
|
|
2078
2077
|
// matrix = matrix.translate(-originX,-originY,-originZ)
|
|
2078
|
+
// @ts-ignore
|
|
2079
2079
|
matrix = matrix.translate(-originX, -originY);
|
|
2080
2080
|
}
|
|
2081
2081
|
return matrix;
|
|
@@ -2335,8 +2335,9 @@ function getCubicSize(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {
|
|
|
2335
2335
|
const y = [p1y, p2y];
|
|
2336
2336
|
const x = [p1x, p2x];
|
|
2337
2337
|
let dot;
|
|
2338
|
-
|
|
2338
|
+
// @ts-ignore
|
|
2339
2339
|
if (Math.abs(t1) > '1e12') t1 = 0.5;
|
|
2340
|
+
// @ts-ignore
|
|
2340
2341
|
if (Math.abs(t2) > '1e12') t2 = 0.5;
|
|
2341
2342
|
|
|
2342
2343
|
if (t1 > 0 && t1 < 1) {
|
|
@@ -2354,8 +2355,9 @@ function getCubicSize(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {
|
|
|
2354
2355
|
c = p1y - c1y;
|
|
2355
2356
|
t1 = (-b + Math.sqrt(b * b - 4 * a * c)) / 2 / a;
|
|
2356
2357
|
t2 = (-b - Math.sqrt(b * b - 4 * a * c)) / 2 / a;
|
|
2357
|
-
|
|
2358
|
+
// @ts-ignore
|
|
2358
2359
|
if (Math.abs(t1) > '1e12') t1 = 0.5;
|
|
2360
|
+
// @ts-ignore
|
|
2359
2361
|
if (Math.abs(t2) > '1e12') t2 = 0.5;
|
|
2360
2362
|
|
|
2361
2363
|
if (t1 > 0 && t1 < 1) {
|
|
@@ -2435,35 +2437,39 @@ function pathToCurve(pathInput) {
|
|
|
2435
2437
|
function getPathBBox(path) {
|
|
2436
2438
|
if (!path) {
|
|
2437
2439
|
return {
|
|
2438
|
-
x: 0, y: 0, width: 0, height: 0, x2: 0, y2: 0,
|
|
2440
|
+
x: 0, y: 0, width: 0, height: 0, x2: 0, y2: 0, cx: 0, cy: 0,
|
|
2439
2441
|
};
|
|
2440
2442
|
}
|
|
2441
2443
|
const pathCurve = pathToCurve(path);
|
|
2442
|
-
|
|
2443
|
-
let x = 0;
|
|
2444
|
-
let y = 0;
|
|
2445
|
-
let X = [];
|
|
2446
|
-
let Y = [];
|
|
2444
|
+
// @ts-ignore
|
|
2445
|
+
let x = 0; let y = 0; let X = []; let Y = [];
|
|
2447
2446
|
|
|
2448
2447
|
pathCurve.forEach((segment) => {
|
|
2449
2448
|
const [s1, s2] = segment.slice(-2);
|
|
2450
2449
|
if (segment[0] === 'M') {
|
|
2451
|
-
x = s1;
|
|
2452
|
-
y = s2;
|
|
2450
|
+
x = +s1;
|
|
2451
|
+
y = +s2;
|
|
2453
2452
|
X.push(s1);
|
|
2454
2453
|
Y.push(s2);
|
|
2455
2454
|
} else {
|
|
2455
|
+
// @ts-ignore
|
|
2456
2456
|
const dim = getCubicSize.apply(0, [x, y].concat(segment.slice(1)));
|
|
2457
|
+
// @ts-ignore
|
|
2457
2458
|
X = X.concat(dim.min.x, dim.max.x);
|
|
2459
|
+
// @ts-ignore
|
|
2458
2460
|
Y = Y.concat(dim.min.y, dim.max.y);
|
|
2459
|
-
x = s1;
|
|
2460
|
-
y = s2;
|
|
2461
|
+
x = +s1;
|
|
2462
|
+
y = +s2;
|
|
2461
2463
|
}
|
|
2462
2464
|
});
|
|
2463
2465
|
|
|
2466
|
+
// @ts-ignore
|
|
2464
2467
|
const xTop = Math.min.apply(0, X);
|
|
2468
|
+
// @ts-ignore
|
|
2465
2469
|
const yTop = Math.min.apply(0, Y);
|
|
2470
|
+
// @ts-ignore
|
|
2466
2471
|
const xBot = Math.max.apply(0, X);
|
|
2472
|
+
// @ts-ignore
|
|
2467
2473
|
const yBot = Math.max.apply(0, Y);
|
|
2468
2474
|
const width = xBot - xTop;
|
|
2469
2475
|
const height = yBot - yTop;
|
|
@@ -2508,7 +2514,7 @@ function getCubicSegArea(x0, y0, x1, y1, x2, y2, x3, y3) {
|
|
|
2508
2514
|
* => https://github.com/paperjs/paper.js/blob/develop/src/path/Path.js
|
|
2509
2515
|
*
|
|
2510
2516
|
* @param {SVGPC.pathArray} path the shape `pathArray`
|
|
2511
|
-
* @returns {
|
|
2517
|
+
* @returns {number} the length of the cubic-bezier segment
|
|
2512
2518
|
*/
|
|
2513
2519
|
function getPathArea(path) {
|
|
2514
2520
|
let x = 0; let y = 0;
|
|
@@ -2524,13 +2530,23 @@ function getPathArea(path) {
|
|
|
2524
2530
|
y = my;
|
|
2525
2531
|
return 0;
|
|
2526
2532
|
default:
|
|
2533
|
+
// @ts-ignore
|
|
2527
2534
|
len = getCubicSegArea.apply(0, [x, y].concat(seg.slice(1)));
|
|
2535
|
+
// @ts-ignore
|
|
2528
2536
|
[x, y] = seg.slice(-2);
|
|
2529
2537
|
return len;
|
|
2530
2538
|
}
|
|
2531
2539
|
}).reduce((a, b) => a + b, 0);
|
|
2532
2540
|
}
|
|
2533
2541
|
|
|
2542
|
+
/**
|
|
2543
|
+
* @param {number} p1
|
|
2544
|
+
* @param {number} p2
|
|
2545
|
+
* @param {number} p3
|
|
2546
|
+
* @param {number} p4
|
|
2547
|
+
* @param {number} t a [0-1] ratio
|
|
2548
|
+
* @returns {number}
|
|
2549
|
+
*/
|
|
2534
2550
|
function base3(p1, p2, p3, p4, t) {
|
|
2535
2551
|
const t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4;
|
|
2536
2552
|
const t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3;
|
|
@@ -2540,19 +2556,19 @@ function base3(p1, p2, p3, p4, t) {
|
|
|
2540
2556
|
/**
|
|
2541
2557
|
* Returns the C (cubic-bezier) segment length.
|
|
2542
2558
|
*
|
|
2543
|
-
* @param {
|
|
2544
|
-
* @param {
|
|
2545
|
-
* @param {
|
|
2546
|
-
* @param {
|
|
2547
|
-
* @param {
|
|
2548
|
-
* @param {
|
|
2549
|
-
* @param {
|
|
2550
|
-
* @param {
|
|
2551
|
-
* @param {
|
|
2552
|
-
* @returns {
|
|
2559
|
+
* @param {number} x1 the starting point X
|
|
2560
|
+
* @param {number} y1 the starting point Y
|
|
2561
|
+
* @param {number} x2 the first control point X
|
|
2562
|
+
* @param {number} y2 the first control point Y
|
|
2563
|
+
* @param {number} x3 the second control point X
|
|
2564
|
+
* @param {number} y3 the second control point Y
|
|
2565
|
+
* @param {number} x4 the ending point X
|
|
2566
|
+
* @param {number} y4 the ending point Y
|
|
2567
|
+
* @param {number} z a [0-1] ratio
|
|
2568
|
+
* @returns {number} the cubic-bezier segment length
|
|
2553
2569
|
*/
|
|
2554
2570
|
function getSegCubicLength(x1, y1, x2, y2, x3, y3, x4, y4, z) {
|
|
2555
|
-
let Z;
|
|
2571
|
+
let Z = z;
|
|
2556
2572
|
if (z === null || Number.isNaN(+z)) Z = 1;
|
|
2557
2573
|
|
|
2558
2574
|
// Z = Z > 1 ? 1 : Z < 0 ? 0 : Z;
|
|
@@ -2582,12 +2598,13 @@ function getSegCubicLength(x1, y1, x2, y2, x3, y3, x4, y4, z) {
|
|
|
2582
2598
|
* pathToCurve version
|
|
2583
2599
|
*
|
|
2584
2600
|
* @param {SVGPC.pathArray} path the ending point Y
|
|
2585
|
-
* @returns {
|
|
2601
|
+
* @returns {number} the shape total length
|
|
2586
2602
|
*/
|
|
2587
2603
|
function getPathLength(path) {
|
|
2588
2604
|
let totalLength = 0;
|
|
2589
2605
|
pathToCurve(path).forEach((s, i, curveArray) => {
|
|
2590
2606
|
totalLength += s[0] === 'M' ? 0
|
|
2607
|
+
// @ts-ignore
|
|
2591
2608
|
: getSegCubicLength.apply(0, curveArray[i - 1].slice(-2).concat(s.slice(1)));
|
|
2592
2609
|
});
|
|
2593
2610
|
return totalLength;
|
|
@@ -2608,23 +2625,25 @@ function getDrawDirection(path) {
|
|
|
2608
2625
|
* Returns [x,y] coordinates of a point at a given length of a shape.
|
|
2609
2626
|
*
|
|
2610
2627
|
* @param {string | SVGPC.pathArray} path the `pathArray` to look into
|
|
2611
|
-
* @param {
|
|
2612
|
-
* @returns {
|
|
2628
|
+
* @param {number} length the length of the shape to look at
|
|
2629
|
+
* @returns {number[]} the requested [x,y] coordinates
|
|
2613
2630
|
*/
|
|
2614
2631
|
function getPointAtLength(path, length) {
|
|
2615
2632
|
let totalLength = 0;
|
|
2616
2633
|
let segLen;
|
|
2617
2634
|
let data;
|
|
2618
2635
|
let result;
|
|
2619
|
-
|
|
2636
|
+
// @ts-ignore
|
|
2620
2637
|
return pathToCurve(path).map((seg, i, curveArray) => {
|
|
2621
2638
|
data = i ? curveArray[i - 1].slice(-2).concat(seg.slice(1)) : seg.slice(1);
|
|
2639
|
+
// @ts-ignore
|
|
2622
2640
|
segLen = i ? getSegCubicLength.apply(0, data) : 0;
|
|
2623
2641
|
totalLength += segLen;
|
|
2624
2642
|
|
|
2625
2643
|
if (i === 0) {
|
|
2626
2644
|
result = { x: data[0], y: data[1] };
|
|
2627
2645
|
} else if (totalLength > length && length > totalLength - segLen) {
|
|
2646
|
+
// @ts-ignore
|
|
2628
2647
|
result = getPointAtSegLength.apply(0, data.concat(1 - (totalLength - length) / segLen));
|
|
2629
2648
|
} else {
|
|
2630
2649
|
result = null;
|
|
@@ -2803,12 +2822,13 @@ function shapeToPath(element, replace) {
|
|
|
2803
2822
|
|
|
2804
2823
|
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
2805
2824
|
const type = element.tagName;
|
|
2806
|
-
/** @
|
|
2825
|
+
/** @ts-ignore */
|
|
2807
2826
|
const shapeAttrs = shapeParams[type];
|
|
2808
2827
|
|
|
2809
2828
|
// set config
|
|
2810
2829
|
const config = {};
|
|
2811
2830
|
config.type = type;
|
|
2831
|
+
/** @ts-ignore */
|
|
2812
2832
|
shapeAttrs.forEach((p) => { config[p] = element.getAttribute(p); });
|
|
2813
2833
|
|
|
2814
2834
|
// set no-specific shape attributes: fill, stroke, etc
|
|
@@ -2818,10 +2838,15 @@ function shapeToPath(element, replace) {
|
|
|
2818
2838
|
|
|
2819
2839
|
// set d
|
|
2820
2840
|
let description;
|
|
2841
|
+
/** @ts-ignore */
|
|
2821
2842
|
if (type === 'circle') description = pathToString(getCirclePath(config));
|
|
2843
|
+
/** @ts-ignore */
|
|
2822
2844
|
else if (type === 'ellipse') description = pathToString(getEllipsePath(config));
|
|
2845
|
+
/** @ts-ignore */
|
|
2823
2846
|
else if (['polyline', 'polygon'].includes(type)) description = pathToString(getPolyPath(config));
|
|
2847
|
+
/** @ts-ignore */
|
|
2824
2848
|
else if (type === 'rect') description = pathToString(getRectanglePath(config));
|
|
2849
|
+
/** @ts-ignore */
|
|
2825
2850
|
else if (type === 'line') description = pathToString(getLinePath(config));
|
|
2826
2851
|
else if (type === 'glyph') description = element.getAttribute('d');
|
|
2827
2852
|
|
|
@@ -2852,12 +2877,13 @@ function reverseCurve(path) {
|
|
|
2852
2877
|
.map((x) => x.map((_, i) => x[x.length - i - 2 * (1 - (i % 2))]))
|
|
2853
2878
|
.reverse();
|
|
2854
2879
|
|
|
2855
|
-
|
|
2856
|
-
|
|
2880
|
+
// @ts-ignore
|
|
2881
|
+
return [['M'].concat(rotatedCurve[0].slice(0, 2))]
|
|
2882
|
+
// @ts-ignore
|
|
2857
2883
|
.concat(rotatedCurve.map((x) => ['C'].concat(x.slice(2))));
|
|
2858
2884
|
}
|
|
2859
2885
|
|
|
2860
|
-
var version = "0.1.
|
|
2886
|
+
var version = "0.1.10alpha3";
|
|
2861
2887
|
|
|
2862
2888
|
// @ts-ignore
|
|
2863
2889
|
|