svg-path-commander 1.0.5 → 2.0.0-alpha2

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 (131) hide show
  1. package/README.md +26 -4
  2. package/dist/svg-path-commander.cjs +2 -0
  3. package/dist/svg-path-commander.cjs.map +1 -0
  4. package/dist/svg-path-commander.d.ts +454 -0
  5. package/dist/svg-path-commander.js +2 -3762
  6. package/dist/svg-path-commander.js.map +1 -0
  7. package/dist/svg-path-commander.mjs +1194 -0
  8. package/dist/svg-path-commander.mjs.map +1 -0
  9. package/package.json +39 -42
  10. package/src/convert/pathToAbsolute.ts +101 -0
  11. package/src/convert/{pathToCurve.js → pathToCurve.ts} +12 -14
  12. package/src/convert/pathToRelative.ts +92 -0
  13. package/src/convert/pathToString.ts +17 -0
  14. package/src/{svg-path-commander.js → index.ts} +143 -66
  15. package/src/interface.ts +129 -0
  16. package/src/math/distanceSquareRoot.ts +13 -0
  17. package/src/math/midPoint.ts +16 -0
  18. package/src/math/{polygonArea.js → polygonArea.ts} +6 -4
  19. package/src/math/{polygonLength.js → polygonLength.ts} +5 -3
  20. package/src/math/rotateVector.ts +16 -0
  21. package/src/options/options.ts +9 -0
  22. package/src/parser/error.ts +2 -0
  23. package/src/parser/finalizeSegment.ts +31 -0
  24. package/src/parser/{invalidPathValue.js → invalidPathValue.ts} +0 -0
  25. package/src/parser/{isArcCommand.js → isArcCommand.ts} +5 -4
  26. package/src/parser/isDigit.ts +12 -0
  27. package/src/parser/isDigitStart.ts +14 -0
  28. package/src/parser/isPathCommand.ts +28 -0
  29. package/src/parser/isSpace.ts +23 -0
  30. package/src/parser/paramsCount.ts +16 -0
  31. package/src/parser/paramsParser.ts +14 -0
  32. package/src/parser/{parsePathString.js → parsePathString.ts} +13 -7
  33. package/src/parser/pathParser.ts +29 -0
  34. package/src/parser/{scanFlag.js → scanFlag.ts} +8 -5
  35. package/src/parser/{scanParam.js → scanParam.ts} +12 -11
  36. package/src/parser/{scanSegment.js → scanSegment.ts} +9 -5
  37. package/src/parser/{skipSpaces.js → skipSpaces.ts} +5 -3
  38. package/src/process/{arcToCubic.js → arcToCubic.ts} +42 -28
  39. package/src/process/fixArc.ts +23 -0
  40. package/src/process/getSVGMatrix.ts +70 -0
  41. package/src/process/lineToCubic.ts +17 -0
  42. package/src/process/{normalizePath.js → normalizePath.ts} +10 -10
  43. package/src/process/normalizeSegment.ts +47 -0
  44. package/src/process/{optimizePath.js → optimizePath.ts} +18 -21
  45. package/src/process/{projection2d.js → projection2d.ts} +16 -15
  46. package/src/process/quadToCubic.ts +31 -0
  47. package/src/process/reverseCurve.ts +21 -0
  48. package/src/process/reversePath.ts +101 -0
  49. package/src/process/roundPath.ts +29 -0
  50. package/src/process/segmentToCubic.ts +46 -0
  51. package/src/process/shortenSegment.ts +79 -0
  52. package/src/process/splitCubic.ts +28 -0
  53. package/src/process/{splitPath.js → splitPath.ts} +9 -8
  54. package/src/process/{transformPath.js → transformPath.ts} +55 -48
  55. package/src/types.ts +193 -0
  56. package/src/util/getClosestPoint.ts +15 -0
  57. package/src/util/{getDrawDirection.js → getDrawDirection.ts} +7 -4
  58. package/src/util/getPathArea.ts +70 -0
  59. package/src/util/{getPathBBox.js → getPathBBox.ts} +16 -5
  60. package/src/util/getPointAtLength.ts +14 -0
  61. package/src/util/{getPropertiesAtLength.js → getPropertiesAtLength.ts} +28 -19
  62. package/src/util/{getPropertiesAtPoint.js → getPropertiesAtPoint.ts} +16 -12
  63. package/src/util/getSegmentAtLength.ts +15 -0
  64. package/src/util/getSegmentOfPoint.ts +18 -0
  65. package/src/util/{getTotalLength.js → getTotalLength.ts} +6 -4
  66. package/src/util/isAbsoluteArray.ts +18 -0
  67. package/src/util/{isCurveArray.js → isCurveArray.ts} +6 -4
  68. package/src/util/{isNormalizedArray.js → isNormalizedArray.ts} +4 -2
  69. package/src/util/isPathArray.ts +19 -0
  70. package/src/util/isPointInStroke.ts +15 -0
  71. package/src/util/isRelativeArray.ts +18 -0
  72. package/src/util/{isValidPath.js → isValidPath.ts} +5 -4
  73. package/src/util/{pathLengthFactory.js → pathLengthFactory.ts} +38 -31
  74. package/src/util/{segmentArcFactory.js → segmentArcFactory.ts} +71 -55
  75. package/src/util/segmentCubicFactory.ts +114 -0
  76. package/src/util/{segmentLineFactory.js → segmentLineFactory.ts} +10 -8
  77. package/src/util/{segmentQuadFactory.js → segmentQuadFactory.ts} +47 -32
  78. package/src/util/shapeToPath.ts +214 -0
  79. package/dist/svg-path-commander.es5.js +0 -3875
  80. package/dist/svg-path-commander.es5.min.js +0 -2
  81. package/dist/svg-path-commander.esm.js +0 -3754
  82. package/dist/svg-path-commander.esm.min.js +0 -2
  83. package/dist/svg-path-commander.min.js +0 -2
  84. package/src/convert/pathToAbsolute.js +0 -86
  85. package/src/convert/pathToRelative.js +0 -84
  86. package/src/convert/pathToString.js +0 -14
  87. package/src/index.js +0 -10
  88. package/src/math/distanceSquareRoot.js +0 -14
  89. package/src/math/epsilon.js +0 -8
  90. package/src/math/midPoint.js +0 -13
  91. package/src/math/rotateVector.js +0 -14
  92. package/src/options/options.js +0 -10
  93. package/src/parser/error.js +0 -2
  94. package/src/parser/finalizeSegment.js +0 -28
  95. package/src/parser/isDigit.js +0 -9
  96. package/src/parser/isDigitStart.js +0 -13
  97. package/src/parser/isPathCommand.js +0 -25
  98. package/src/parser/isSpace.js +0 -16
  99. package/src/parser/paramsCount.js +0 -9
  100. package/src/parser/paramsParser.js +0 -8
  101. package/src/parser/pathParser.js +0 -24
  102. package/src/process/clonePath.js +0 -9
  103. package/src/process/fixArc.js +0 -21
  104. package/src/process/fixPath.js +0 -31
  105. package/src/process/getSVGMatrix.js +0 -61
  106. package/src/process/lineToCubic.js +0 -30
  107. package/src/process/normalizeSegment.js +0 -45
  108. package/src/process/quadToCubic.js +0 -22
  109. package/src/process/reverseCurve.js +0 -18
  110. package/src/process/reversePath.js +0 -89
  111. package/src/process/roundPath.js +0 -26
  112. package/src/process/segmentToCubic.js +0 -46
  113. package/src/process/shortenSegment.js +0 -58
  114. package/src/process/splitCubic.js +0 -26
  115. package/src/util/getClosestPoint.js +0 -12
  116. package/src/util/getPathArea.js +0 -47
  117. package/src/util/getPointAtLength.js +0 -12
  118. package/src/util/getSegmentAtLength.js +0 -11
  119. package/src/util/getSegmentOfPoint.js +0 -12
  120. package/src/util/isAbsoluteArray.js +0 -14
  121. package/src/util/isPathArray.js +0 -14
  122. package/src/util/isPointInStroke.js +0 -13
  123. package/src/util/isRelativeArray.js +0 -14
  124. package/src/util/segmentCubicFactory.js +0 -97
  125. package/src/util/shapeToPath.js +0 -204
  126. package/src/util/util.js +0 -82
  127. package/src/version.js +0 -8
  128. package/types/index.d.ts +0 -120
  129. package/types/more/modules.ts +0 -82
  130. package/types/more/svg.d.ts +0 -211
  131. package/types/svg-path-commander.d.ts +0 -1089
@@ -1,61 +0,0 @@
1
- import CSSMatrix from 'dommatrix';
2
-
3
- /**
4
- * Returns a transformation matrix to apply to `<path>` elements.
5
- *
6
- * @see SVGPath.transformObject
7
- *
8
- * @param {SVGPath.transformObject} transform the `transformObject`
9
- * @returns {CSSMatrix} a new transformation matrix
10
- */
11
- export default function getSVGMatrix(transform) {
12
- let matrix = new CSSMatrix();
13
- const { origin } = transform;
14
- const [originX, originY] = origin;
15
- const { translate } = transform;
16
- const { rotate } = transform;
17
- const { skew } = transform;
18
- const { scale } = transform;
19
-
20
- // set translate
21
- if (Array.isArray(translate) && translate.every((x) => !Number.isNaN(+x))
22
- && translate.some((x) => x !== 0)) {
23
- matrix = matrix.translate(...translate);
24
- } else if (typeof translate === 'number' && !Number.isNaN(translate)) {
25
- matrix = matrix.translate(translate);
26
- }
27
-
28
- if (rotate || skew || scale) {
29
- // set SVG transform-origin, always defined
30
- matrix = matrix.translate(originX, originY);
31
-
32
- // set rotation
33
- if (Array.isArray(rotate) && rotate.every((x) => !Number.isNaN(+x))
34
- && rotate.some((x) => x !== 0)) {
35
- matrix = matrix.rotate(...rotate);
36
- } else if (typeof rotate === 'number' && !Number.isNaN(rotate)) {
37
- matrix = matrix.rotate(rotate);
38
- }
39
-
40
- // set skew(s)
41
- if (Array.isArray(skew) && skew.every((x) => !Number.isNaN(+x))
42
- && skew.some((x) => x !== 0)) {
43
- matrix = skew[0] ? matrix.skewX(skew[0]) : matrix;
44
- matrix = skew[1] ? matrix.skewY(skew[1]) : matrix;
45
- } else if (typeof skew === 'number' && !Number.isNaN(skew)) {
46
- matrix = matrix.skewX(skew);
47
- }
48
-
49
- // set scale
50
- if (Array.isArray(scale) && scale.every((x) => !Number.isNaN(+x))
51
- && scale.some((x) => x !== 1)) {
52
- matrix = matrix.scale(...scale);
53
- } else if (typeof scale === 'number' && !Number.isNaN(scale)) {
54
- matrix = matrix.scale(scale);
55
- }
56
- // set SVG transform-origin
57
- matrix = matrix.translate(-originX, -originY);
58
- }
59
-
60
- return matrix;
61
- }
@@ -1,30 +0,0 @@
1
- import segmentLineFactory from '../util/segmentLineFactory';
2
- import midPoint from '../math/midPoint';
3
-
4
- /**
5
- * Converts an L (line-to) segment to C (cubic-bezier).
6
- *
7
- * @param {number} x1 line start x
8
- * @param {number} y1 line start y
9
- * @param {number} x2 line end x
10
- * @param {number} y2 line end y
11
- * @returns {number[]} the cubic-bezier segment
12
- */
13
- export default function lineToCubic(x1, y1, x2, y2) {
14
- const t = 0.5;
15
- /** @type {[number, number]} */
16
- const p0 = [x1, y1];
17
- /** @type {[number, number]} */
18
- const p1 = [x2, y2];
19
- const p2 = midPoint(p0, p1, t);
20
- const p3 = midPoint(p1, p2, t);
21
- const p4 = midPoint(p2, p3, t);
22
- const p5 = midPoint(p3, p4, t);
23
- const p6 = midPoint(p4, p5, t);
24
- const seg1 = [...p0, ...p2, ...p4, ...p6, t];
25
- const cp1 = segmentLineFactory(...seg1).point;
26
- const seg2 = [...p6, ...p5, ...p3, ...p1, 0];
27
- const cp2 = segmentLineFactory(...seg2).point;
28
-
29
- return [cp1.x, cp1.y, cp2.x, cp2.y, x2, y2];
30
- }
@@ -1,45 +0,0 @@
1
- /**
2
- * Normalizes a single segment of a `pathArray` object.
3
- *
4
- * @param {SVGPath.pathSegment} segment the segment object
5
- * @param {any} params the coordinates of the previous segment
6
- * @returns {SVGPath.normalSegment} the normalized segment
7
- */
8
- export default function normalizeSegment(segment, params) {
9
- const [pathCommand] = segment;
10
- const {
11
- x1: px1, y1: py1, x2: px2, y2: py2,
12
- } = params;
13
- const values = segment.slice(1).map(Number);
14
- let result = segment;
15
-
16
- if (!'TQ'.includes(pathCommand)) {
17
- // optional but good to be cautious
18
- params.qx = null;
19
- params.qy = null;
20
- }
21
-
22
- if (pathCommand === 'H') {
23
- result = ['L', segment[1], py1];
24
- } else if (pathCommand === 'V') {
25
- result = ['L', px1, segment[1]];
26
- } else if (pathCommand === 'S') {
27
- const x1 = px1 * 2 - px2;
28
- const y1 = py1 * 2 - py2;
29
- params.x1 = x1;
30
- params.y1 = y1;
31
- result = ['C', x1, y1, ...values];
32
- } else if (pathCommand === 'T') {
33
- const qx = px1 * 2 - params.qx;
34
- const qy = py1 * 2 - params.qy;
35
- params.qx = qx;
36
- params.qy = qy;
37
- result = ['Q', qx, qy, ...values];
38
- } else if (pathCommand === 'Q') {
39
- const [nqx, nqy] = values;
40
- params.qx = nqx;
41
- params.qy = nqy;
42
- }
43
-
44
- return result;
45
- }
@@ -1,22 +0,0 @@
1
- /**
2
- * Converts a Q (quadratic-bezier) segment to C (cubic-bezier).
3
- *
4
- * @param {number} x1 curve start x
5
- * @param {number} y1 curve start y
6
- * @param {number} qx control point x
7
- * @param {number} qy control point y
8
- * @param {number} x2 curve end x
9
- * @param {number} y2 curve end y
10
- * @returns {number[]} the cubic-bezier segment
11
- */
12
- export default function quadToCubic(x1, y1, qx, qy, x2, y2) {
13
- const r13 = 1 / 3;
14
- const r23 = 2 / 3;
15
- return [
16
- r13 * x1 + r23 * qx, // cpx1
17
- r13 * y1 + r23 * qy, // cpy1
18
- r13 * x2 + r23 * qx, // cpx2
19
- r13 * y2 + r23 * qy, // cpy2
20
- x2, y2, // x,y
21
- ];
22
- }
@@ -1,18 +0,0 @@
1
- /**
2
- * Reverses all segments of a `pathArray`
3
- * which consists of only C (cubic-bezier) path commands.
4
- *
5
- * @param {SVGPath.curveArray} path the source `pathArray`
6
- * @returns {SVGPath.curveArray} the reversed `pathArray`
7
- */
8
- export default function reverseCurve(path) {
9
- const rotatedCurve = path.slice(1)
10
- .map((x, i, curveOnly) => (!i
11
- ? [...path[0].slice(1), ...x.slice(1)]
12
- : [...curveOnly[i - 1].slice(-2), ...x.slice(1)]))
13
- .map((x) => x.map((_, i) => x[x.length - i - 2 * (1 - (i % 2))]))
14
- .reverse();
15
-
16
- return [['M', ...rotatedCurve[0].slice(0, 2)],
17
- ...rotatedCurve.map((x) => ['C', ...x.slice(2)])];
18
- }
@@ -1,89 +0,0 @@
1
- import pathToAbsolute from '../convert/pathToAbsolute';
2
- import normalizePath from './normalizePath';
3
-
4
- /**
5
- * Reverses all segments of a `pathArray` and returns a new `pathArray` instance.
6
- *
7
- * @param {SVGPath.pathArray} pathInput the source `pathArray`
8
- * @returns {SVGPath.pathArray} the reversed `pathArray`
9
- */
10
- export default function reversePath(pathInput) {
11
- const absolutePath = pathToAbsolute(pathInput);
12
- const isClosed = absolutePath.slice(-1)[0][0] === 'Z';
13
-
14
- const reversedPath = normalizePath(absolutePath).map((segment, i) => {
15
- const [x, y] = segment.slice(-2).map(Number);
16
- return {
17
- seg: absolutePath[i], // absolute
18
- n: segment, // normalized
19
- c: absolutePath[i][0], // pathCommand
20
- x, // x
21
- y, // y
22
- };
23
- }).map((seg, i, path) => {
24
- const segment = seg.seg;
25
- const data = seg.n;
26
- const prevSeg = i && path[i - 1];
27
- const nextSeg = path[i + 1];
28
- const pathCommand = seg.c;
29
- const pLen = path.length;
30
- /** @type {number} */
31
- const x = i ? path[i - 1].x : path[pLen - 1].x;
32
- const y = i ? path[i - 1].y : path[pLen - 1].y;
33
- /** @type {SVGPath.pathSegment} */
34
- let result = [];
35
-
36
- switch (pathCommand) {
37
- case 'M':
38
- result = isClosed ? ['Z'] : [pathCommand, x, y];
39
- break;
40
- case 'A':
41
- result = [pathCommand, ...segment.slice(1, -3), (segment[5] === 1 ? 0 : 1), x, y];
42
- break;
43
- case 'C':
44
- if (nextSeg && nextSeg.c === 'S') {
45
- result = ['S', segment[1], segment[2], x, y];
46
- } else {
47
- result = [pathCommand, segment[3], segment[4], segment[1], segment[2], x, y];
48
- }
49
- break;
50
- case 'S':
51
- if ((prevSeg && 'CS'.includes(prevSeg.c)) && (!nextSeg || nextSeg.c !== 'S')) {
52
- result = ['C', data[3], data[4], data[1], data[2], x, y];
53
- } else {
54
- result = [pathCommand, data[1], data[2], x, y];
55
- }
56
- break;
57
- case 'Q':
58
- if (nextSeg && nextSeg.c === 'T') {
59
- result = ['T', x, y];
60
- } else {
61
- result = [pathCommand, ...segment.slice(1, -2), x, y];
62
- }
63
- break;
64
- case 'T':
65
- if ((prevSeg && 'QT'.includes(prevSeg.c)) && (!nextSeg || nextSeg.c !== 'T')) {
66
- result = ['Q', data[1], data[2], x, y];
67
- } else {
68
- result = [pathCommand, x, y];
69
- }
70
- break;
71
- case 'Z':
72
- result = ['M', x, y];
73
- break;
74
- case 'H':
75
- result = [pathCommand, x];
76
- break;
77
- case 'V':
78
- result = [pathCommand, y];
79
- break;
80
- default:
81
- result = [pathCommand, ...segment.slice(1, -2), x, y];
82
- }
83
-
84
- return result;
85
- });
86
-
87
- return isClosed ? reversedPath.reverse()
88
- : [reversedPath[0], ...reversedPath.slice(1).reverse()];
89
- }
@@ -1,26 +0,0 @@
1
- import defaultOptions from '../options/options';
2
- import clonePath from './clonePath';
3
- /**
4
- * Rounds the values of a `pathArray` instance to
5
- * a specified amount of decimals and returns it.
6
- *
7
- * @param {SVGPath.pathArray} path the source `pathArray`
8
- * @param {number | 'off'} roundOption the amount of decimals to round numbers to
9
- * @returns {SVGPath.pathArray} the resulted `pathArray` with rounded values
10
- */
11
- export default function roundPath(path, roundOption) {
12
- let { round } = defaultOptions;
13
- if (roundOption === 'off' || round === 'off') return clonePath(path);
14
- // round = roundOption >= 1 ? roundOption : round;
15
- // allow for ZERO decimals
16
- round = roundOption >= 0 ? roundOption : round;
17
- // to round values to the power
18
- // the `round` value must be integer
19
- const pow = typeof round === 'number' && round >= 1 ? (10 ** round) : 1;
20
-
21
- return path.map((pi) => {
22
- const values = pi.slice(1).map(Number)
23
- .map((n) => (round ? (Math.round(n * pow) / pow) : Math.round(n)));
24
- return [pi[0], ...values];
25
- });
26
- }
@@ -1,46 +0,0 @@
1
- import arcToCubic from './arcToCubic';
2
- import quadToCubic from './quadToCubic';
3
- import lineToCubic from './lineToCubic';
4
-
5
- /**
6
- * Converts any segment to C (cubic-bezier).
7
- *
8
- * @param {SVGPath.pathSegment} segment the source segment
9
- * @param {SVGPath.parserParams} params the source segment parameters
10
- * @returns {SVGPath.cubicSegment | SVGPath.MSegment} the cubic-bezier segment
11
- */
12
- export default function segmentToCubic(segment, params) {
13
- const [pathCommand] = segment;
14
- const values = segment.slice(1).map(Number);
15
- const [x, y] = values;
16
- let args;
17
- const {
18
- x1: px1, y1: py1, x: px, y: py,
19
- } = params;
20
-
21
- if (!'TQ'.includes(pathCommand)) {
22
- params.qx = null;
23
- params.qy = null;
24
- }
25
-
26
- switch (pathCommand) {
27
- case 'M':
28
- params.x = x;
29
- params.y = y;
30
- return segment;
31
- case 'A':
32
- args = [px1, py1, ...values];
33
- return ['C', ...arcToCubic(...args)];
34
- case 'Q':
35
- params.qx = x;
36
- params.qy = y;
37
- args = [px1, py1, ...values];
38
- return ['C', ...quadToCubic(...args)];
39
- case 'L':
40
- return ['C', ...lineToCubic(px1, py1, x, y)];
41
- case 'Z':
42
- return ['C', ...lineToCubic(px1, py1, px, py)];
43
- default:
44
- }
45
- return segment;
46
- }
@@ -1,58 +0,0 @@
1
- /**
2
- * Shorten a single segment of a `pathArray` object.
3
- *
4
- * @param {SVGPath.absoluteSegment} segment the `absoluteSegment` object
5
- * @param {SVGPath.normalSegment} normalSegment the `normalSegment` object
6
- * @param {any} params the coordinates of the previous segment
7
- * @param {string} prevCommand the path command of the previous segment
8
- * @returns {SVGPath.shortSegment | SVGPath.pathSegment} the shortened segment
9
- */
10
- export default function shortenSegment(segment, normalSegment, params, prevCommand) {
11
- const [pathCommand] = segment;
12
- const round4 = (/** @type {number} */n) => Math.round(n * (10 ** 4)) / 10 ** 4;
13
- const segmentValues = segment.slice(1).map((n) => +n);
14
- const normalValues = normalSegment.slice(1).map((n) => +n);
15
- const {
16
- x1: px1, y1: py1, x2: px2, y2: py2, x: px, y: py,
17
- } = params;
18
- let result = segment;
19
- const [x, y] = normalValues.slice(-2);
20
-
21
- if (!'TQ'.includes(pathCommand)) {
22
- // optional but good to be cautious
23
- params.qx = null;
24
- params.qy = null;
25
- }
26
-
27
- if (['V', 'H', 'S', 'T', 'Z'].includes(pathCommand)) {
28
- result = [pathCommand, ...segmentValues];
29
- } else if (pathCommand === 'L') {
30
- if (round4(px) === round4(x)) {
31
- result = ['V', y];
32
- } else if (round4(py) === round4(y)) {
33
- result = ['H', x];
34
- }
35
- } else if (pathCommand === 'C') {
36
- const [x1, y1] = normalValues;
37
-
38
- if ('CS'.includes(prevCommand)
39
- && ((round4(x1) === round4(px1 * 2 - px2) && round4(y1) === round4(py1 * 2 - py2))
40
- || (round4(px1) === round4(px2 * 2 - px) && round4(py1) === round4(py2 * 2 - py)))) {
41
- result = ['S', ...normalValues.slice(-4)];
42
- }
43
- params.x1 = x1;
44
- params.y1 = y1;
45
- } else if (pathCommand === 'Q') {
46
- const [qx, qy] = normalValues;
47
- params.qx = qx;
48
- params.qy = qy;
49
-
50
- if ('QT'.includes(prevCommand)
51
- && ((round4(qx) === round4(px1 * 2 - px2) && round4(qy) === round4(py1 * 2 - py2))
52
- || (round4(px1) === round4(px2 * 2 - px) && round4(py1) === round4(py2 * 2 - py)))) {
53
- result = ['T', ...normalValues.slice(-2)];
54
- }
55
- }
56
-
57
- return result;
58
- }
@@ -1,26 +0,0 @@
1
- import midPoint from '../math/midPoint';
2
-
3
- /**
4
- * Split a cubic-bezier segment into two.
5
- *
6
- * @param {number[]} pts the cubic-bezier parameters
7
- * @return {SVGPath.cubicSegment[]} two new cubic-bezier segments
8
- */
9
- export default function splitCubic(pts/* , ratio */) {
10
- const t = /* ratio || */ 0.5;
11
- const p0 = pts.slice(0, 2);
12
- const p1 = pts.slice(2, 4);
13
- const p2 = pts.slice(4, 6);
14
- const p3 = pts.slice(6, 8);
15
- const p4 = midPoint(p0, p1, t);
16
- const p5 = midPoint(p1, p2, t);
17
- const p6 = midPoint(p2, p3, t);
18
- const p7 = midPoint(p4, p5, t);
19
- const p8 = midPoint(p5, p6, t);
20
- const p9 = midPoint(p7, p8, t);
21
-
22
- return [
23
- ['C', ...p4, ...p7, ...p9],
24
- ['C', ...p8, ...p6, ...p3],
25
- ];
26
- }
@@ -1,12 +0,0 @@
1
- import getPropertiesAtPoint from './getPropertiesAtPoint';
2
-
3
- /**
4
- * Returns the point in path closest to a given point.
5
- *
6
- * @param {string | SVGPath.pathArray} pathInput target `pathArray`
7
- * @param {{x: number, y: number}} point the given point
8
- * @returns {{x: number, y: number}} the best match
9
- */
10
- export default function getClosestPoint(pathInput, point) {
11
- return getPropertiesAtPoint(pathInput, point).closest;
12
- }
@@ -1,47 +0,0 @@
1
- import pathToCurve from '../convert/pathToCurve';
2
-
3
- /**
4
- * Returns the area of a single cubic-bezier segment.
5
- *
6
- * http://objectmix.com/graphics/133553-area-closed-bezier-curve.html
7
- *
8
- * @param {number} x1 the starting point X
9
- * @param {number} y1 the starting point Y
10
- * @param {number} c1x the first control point X
11
- * @param {number} c1y the first control point Y
12
- * @param {number} c2x the second control point X
13
- * @param {number} c2y the second control point Y
14
- * @param {number} x2 the ending point X
15
- * @param {number} y2 the ending point Y
16
- * @returns {number} the area of the cubic-bezier segment
17
- */
18
- function getCubicSegArea(x1, y1, c1x, c1y, c2x, c2y, x2, y2) {
19
- return (3 * ((y2 - y1) * (c1x + c2x) - (x2 - x1) * (c1y + c2y)
20
- + (c1y * (x1 - c2x)) - (c1x * (y1 - c2y))
21
- + (y2 * (c2x + x1 / 3)) - (x2 * (c2y + y1 / 3)))) / 20;
22
- }
23
-
24
- /**
25
- * Returns the area of a shape.
26
- * @author Jürg Lehni & Jonathan Puckey
27
- *
28
- * @see https://github.com/paperjs/paper.js/blob/develop/src/path/Path.js
29
- *
30
- * @param {SVGPath.pathArray} path the shape `pathArray`
31
- * @returns {number} the length of the cubic-bezier segment
32
- */
33
- export default function getPathArea(path) {
34
- let x = 0; let y = 0; let len = 0;
35
-
36
- return pathToCurve(path).map((seg) => {
37
- switch (seg[0]) {
38
- case 'M':
39
- [, x, y] = seg;
40
- return 0;
41
- default:
42
- len = getCubicSegArea(x, y, ...seg.slice(1));
43
- [x, y] = seg.slice(-2);
44
- return len;
45
- }
46
- }).reduce((a, b) => a + b, 0);
47
- }
@@ -1,12 +0,0 @@
1
- import pathLengthFactory from './pathLengthFactory';
2
-
3
- /**
4
- * Returns [x,y] coordinates of a point at a given length of a shape.
5
- *
6
- * @param {string | SVGPath.pathArray} pathInput the `pathArray` to look into
7
- * @param {number} distance the length of the shape to look at
8
- * @returns {{x: number, y: number}} the requested {x, y} point coordinates
9
- */
10
- export default function getPointAtLength(pathInput, distance) {
11
- return pathLengthFactory(pathInput, distance).point;
12
- }
@@ -1,11 +0,0 @@
1
- import getPropertiesAtLength from './getPropertiesAtLength';
2
-
3
- /**
4
- * Returns the segment at a given length.
5
- * @param {string | SVGPath.pathArray} pathInput the target `pathArray`
6
- * @param {number} distance the distance in path to look at
7
- * @returns {SVGPath.pathSegment?} the requested segment
8
- */
9
- export default function getSegmentAtLength(pathInput, distance) {
10
- return getPropertiesAtLength(pathInput, distance).segment;
11
- }
@@ -1,12 +0,0 @@
1
- import getPropertiesAtPoint from './getPropertiesAtPoint';
2
-
3
- /**
4
- * Returns the path segment which contains a given point.
5
- *
6
- * @param {string | SVGPath.pathArray} path the `pathArray` to look into
7
- * @param {{x: number, y: number}} point the point of the shape to look for
8
- * @returns {SVGPath.pathSegment?} the requested segment
9
- */
10
- export default function getSegmentOfPoint(path, point) {
11
- return getPropertiesAtPoint(path, point).segment;
12
- }
@@ -1,14 +0,0 @@
1
- import isPathArray from './isPathArray';
2
-
3
- /**
4
- * Iterates an array to check if it's a `pathArray`
5
- * with all absolute values.
6
- *
7
- * @param {string | SVGPath.pathArray} path the `pathArray` to be checked
8
- * @returns {boolean} iteration result
9
- */
10
- export default function isAbsoluteArray(path) {
11
- return isPathArray(path)
12
- // `isPathArray` also checks if it's `Array`
13
- && path.every(([x]) => x === x.toUpperCase());
14
- }
@@ -1,14 +0,0 @@
1
- import paramsCount from '../parser/paramsCount';
2
-
3
- /**
4
- * Iterates an array to check if it's an actual `pathArray`.
5
- *
6
- * @param {string | SVGPath.pathArray} path the `pathArray` to be checked
7
- * @returns {boolean} iteration result
8
- */
9
- export default function isPathArray(path) {
10
- return Array.isArray(path) && path.every((seg) => {
11
- const lk = seg[0].toLowerCase();
12
- return paramsCount[lk] === seg.length - 1 && 'achlmqstvz'.includes(lk);
13
- });
14
- }
@@ -1,13 +0,0 @@
1
- import getPropertiesAtPoint from './getPropertiesAtPoint';
2
-
3
- /**
4
- * Checks if a given point is in the stroke of a path.
5
- *
6
- * @param {string | SVGPath.pathArray} pathInput target path
7
- * @param {{x: number, y: number}} point the given `{x,y}` point
8
- * @returns {boolean} the query result
9
- */
10
- export default function isPointInStroke(pathInput, point) {
11
- const { distance } = getPropertiesAtPoint(pathInput, point);
12
- return Math.abs(distance) < 0.001; // 0.01 might be more permissive
13
- }
@@ -1,14 +0,0 @@
1
- import isPathArray from './isPathArray';
2
-
3
- /**
4
- * Iterates an array to check if it's a `pathArray`
5
- * with relative values.
6
- *
7
- * @param {string | SVGPath.pathArray} path the `pathArray` to be checked
8
- * @returns {boolean} iteration result
9
- */
10
- export default function isRelativeArray(path) {
11
- return isPathArray(path)
12
- // `isPathArray` checks if it's `Array`
13
- && path.slice(1).every(([pc]) => pc === pc.toLowerCase());
14
- }