svg-path-commander 2.1.2 → 2.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/README.md +4 -4
  2. package/dist/svg-path-commander.cjs +1 -1
  3. package/dist/svg-path-commander.cjs.map +1 -1
  4. package/dist/svg-path-commander.d.ts +755 -849
  5. package/dist/svg-path-commander.js +1 -1
  6. package/dist/svg-path-commander.js.map +1 -1
  7. package/dist/svg-path-commander.mjs +947 -611
  8. package/dist/svg-path-commander.mjs.map +1 -1
  9. package/package.json +14 -22
  10. package/.eslintrc.cjs +0 -225
  11. package/.prettierrc.json +0 -15
  12. package/dts.config.ts +0 -15
  13. package/src/convert/pathToAbsolute.ts +0 -18
  14. package/src/convert/pathToCurve.ts +0 -43
  15. package/src/convert/pathToRelative.ts +0 -18
  16. package/src/convert/pathToString.ts +0 -50
  17. package/src/index.ts +0 -454
  18. package/src/interface.ts +0 -130
  19. package/src/math/arcTools.ts +0 -396
  20. package/src/math/bezier.ts +0 -261
  21. package/src/math/cubicTools.ts +0 -124
  22. package/src/math/distanceSquareRoot.ts +0 -15
  23. package/src/math/lineTools.ts +0 -69
  24. package/src/math/midPoint.ts +0 -18
  25. package/src/math/polygonTools.ts +0 -48
  26. package/src/math/quadTools.ts +0 -100
  27. package/src/math/rotateVector.ts +0 -17
  28. package/src/math/roundTo.ts +0 -7
  29. package/src/options/options.ts +0 -9
  30. package/src/parser/error.ts +0 -2
  31. package/src/parser/finalizeSegment.ts +0 -35
  32. package/src/parser/invalidPathValue.ts +0 -2
  33. package/src/parser/isArcCommand.ts +0 -11
  34. package/src/parser/isDigit.ts +0 -12
  35. package/src/parser/isDigitStart.ts +0 -14
  36. package/src/parser/isMoveCommand.ts +0 -17
  37. package/src/parser/isPathCommand.ts +0 -28
  38. package/src/parser/isSpace.ts +0 -23
  39. package/src/parser/paramsCount.ts +0 -16
  40. package/src/parser/paramsParser.ts +0 -14
  41. package/src/parser/parsePathString.ts +0 -33
  42. package/src/parser/pathParser.ts +0 -29
  43. package/src/parser/scanFlag.ts +0 -29
  44. package/src/parser/scanParam.ts +0 -102
  45. package/src/parser/scanSegment.ts +0 -84
  46. package/src/parser/skipSpaces.ts +0 -17
  47. package/src/process/absolutizeSegment.ts +0 -63
  48. package/src/process/arcToCubic.ts +0 -128
  49. package/src/process/getSVGMatrix.ts +0 -70
  50. package/src/process/iterate.ts +0 -58
  51. package/src/process/lineToCubic.ts +0 -17
  52. package/src/process/normalizePath.ts +0 -33
  53. package/src/process/normalizeSegment.ts +0 -84
  54. package/src/process/optimizePath.ts +0 -63
  55. package/src/process/projection2d.ts +0 -52
  56. package/src/process/quadToCubic.ts +0 -31
  57. package/src/process/relativizeSegment.ts +0 -59
  58. package/src/process/reverseCurve.ts +0 -24
  59. package/src/process/reversePath.ts +0 -114
  60. package/src/process/roundPath.ts +0 -33
  61. package/src/process/roundSegment.ts +0 -9
  62. package/src/process/segmentToCubic.ts +0 -48
  63. package/src/process/shortenSegment.ts +0 -71
  64. package/src/process/splitCubic.ts +0 -29
  65. package/src/process/splitPath.ts +0 -63
  66. package/src/process/transformPath.ts +0 -110
  67. package/src/types.ts +0 -228
  68. package/src/util/distanceEpsilon.ts +0 -3
  69. package/src/util/getClosestPoint.ts +0 -15
  70. package/src/util/getDrawDirection.ts +0 -16
  71. package/src/util/getPathArea.ts +0 -70
  72. package/src/util/getPathBBox.ts +0 -98
  73. package/src/util/getPointAtLength.ts +0 -110
  74. package/src/util/getPropertiesAtLength.ts +0 -67
  75. package/src/util/getPropertiesAtPoint.ts +0 -84
  76. package/src/util/getSegmentAtLength.ts +0 -15
  77. package/src/util/getSegmentOfPoint.ts +0 -18
  78. package/src/util/getTotalLength.ts +0 -68
  79. package/src/util/isAbsoluteArray.ts +0 -18
  80. package/src/util/isCurveArray.ts +0 -15
  81. package/src/util/isNormalizedArray.ts +0 -16
  82. package/src/util/isPathArray.ts +0 -24
  83. package/src/util/isPointInStroke.ts +0 -16
  84. package/src/util/isRelativeArray.ts +0 -18
  85. package/src/util/isValidPath.ts +0 -27
  86. package/src/util/shapeParams.ts +0 -16
  87. package/src/util/shapeToPath.ts +0 -86
  88. package/src/util/shapeToPathArray.ts +0 -183
  89. package/test/class.test.ts +0 -504
  90. package/test/fixtures/getMarkup.ts +0 -17
  91. package/test/fixtures/shapeObjects.ts +0 -11
  92. package/test/fixtures/shapes.js +0 -104
  93. package/test/fixtures/simpleShapes.js +0 -75
  94. package/test/static.test.ts +0 -330
  95. package/vite.config.mts +0 -41
  96. package/vitest.config-ui.mts +0 -26
  97. package/vitest.config.mts +0 -26
@@ -1,110 +0,0 @@
1
- import getSVGMatrix from './getSVGMatrix';
2
- import projection2d from './projection2d';
3
- import defaultOptions from '../options/options';
4
- import type { AbsoluteArray, AbsoluteSegment, CSegment, LSegment, PathArray, TransformObjectValues } from '../types';
5
- import type { TransformObject } from '../interface';
6
- import iterate from './iterate';
7
- import parsePathString from '../parser/parsePathString';
8
- import segmentToCubic from './segmentToCubic';
9
- import normalizeSegment from './normalizeSegment';
10
- import paramsParser from '../parser/paramsParser';
11
- import absolutizeSegment from './absolutizeSegment';
12
-
13
- /**
14
- * Apply a 2D / 3D transformation to a `pathArray` instance.
15
- *
16
- * Since *SVGElement* doesn't support 3D transformation, this function
17
- * creates a 2D projection of the <path> element.
18
- *
19
- * @param path the `pathArray` to apply transformation
20
- * @param transform the transform functions `Object`
21
- * @returns the resulted `pathArray`
22
- */
23
- const transformPath = (pathInput: PathArray | string, transform?: Partial<TransformObject>) => {
24
- // last x and y transformed values
25
- let x = 0;
26
- let y = 0;
27
- // new x and y transformed
28
- let lx = 0;
29
- let ly = 0;
30
- // segment params iteration index and length
31
- let j = 0;
32
- let jj = 0;
33
- let pathCommand = 'M';
34
- // transform uses it's own set of params
35
- const transformParams = { ...paramsParser };
36
- const path = parsePathString(pathInput);
37
- const transformProps = transform && Object.keys(transform);
38
-
39
- // when used as a static method, invalidate somehow
40
- if (!transform || (transformProps && !transformProps.length)) return path.slice(0) as typeof path;
41
-
42
- // transform origin is extremely important
43
- if (!transform.origin) {
44
- Object.assign(transform, { origin: defaultOptions.origin });
45
- }
46
- const origin = transform.origin as [number, number, number];
47
- const matrixInstance = getSVGMatrix(transform as TransformObjectValues);
48
-
49
- if (matrixInstance.isIdentity) return path.slice(0) as typeof path;
50
-
51
- return iterate<AbsoluteArray>(path, (seg, index, lastX, lastY) => {
52
- transformParams.x = lastX;
53
- transformParams.y = lastY;
54
- [pathCommand] = seg;
55
- const absCommand = pathCommand.toUpperCase();
56
- const isRelative = absCommand !== pathCommand;
57
- const absoluteSegment = isRelative
58
- ? absolutizeSegment(seg, index, lastX, lastY)
59
- : (seg.slice(0) as AbsoluteSegment);
60
-
61
- let result =
62
- absCommand === 'A'
63
- ? segmentToCubic(absoluteSegment, transformParams)
64
- : ['V', 'H'].includes(absCommand)
65
- ? normalizeSegment(absoluteSegment, transformParams)
66
- : absoluteSegment;
67
-
68
- // update pathCommand
69
- pathCommand = result[0];
70
- const isLongArc = pathCommand === 'C' && result.length > 7;
71
- const tempSegment = (isLongArc ? result.slice(0, 7) : result.slice(0)) as AbsoluteSegment;
72
-
73
- if (isLongArc) {
74
- path.splice(index + 1, 0, ['C' as typeof pathCommand | number].concat(result.slice(7)) as CSegment);
75
- result = tempSegment as CSegment;
76
- }
77
-
78
- if (pathCommand === 'L') {
79
- [lx, ly] = projection2d(matrixInstance, [(result as LSegment)[1], (result as LSegment)[2]], origin);
80
-
81
- /* istanbul ignore else @preserve */
82
- if (x !== lx && y !== ly) {
83
- result = ['L', lx, ly];
84
- } else if (y === ly) {
85
- result = ['H', lx];
86
- } else if (x === lx) {
87
- result = ['V', ly];
88
- }
89
- } else {
90
- for (j = 1, jj = result.length; j < jj; j += 2) {
91
- [lx, ly] = projection2d(matrixInstance, [+result[j], +result[j + 1]], origin);
92
- result[j] = lx;
93
- result[j + 1] = ly;
94
- }
95
- }
96
- // now update x and y
97
- x = lx;
98
- y = ly;
99
-
100
- const seglen = tempSegment.length;
101
- transformParams.x1 = +tempSegment[seglen - 2];
102
- transformParams.y1 = +tempSegment[seglen - 1];
103
- transformParams.x2 = +tempSegment[seglen - 4] || transformParams.x1;
104
- transformParams.y2 = +tempSegment[seglen - 3] || transformParams.y1;
105
-
106
- return result;
107
- });
108
- };
109
-
110
- export default transformPath;
package/src/types.ts DELETED
@@ -1,228 +0,0 @@
1
- import type { LineAttr, CircleAttr, PolyAttr, RectAttr, EllipseAttr, GlyphAttr, TransformObject } from './interface';
2
-
3
- export type SpaceNumber =
4
- | 0x1680
5
- | 0x180e
6
- | 0x2000
7
- | 0x2001
8
- | 0x2002
9
- | 0x2003
10
- | 0x2004
11
- | 0x2005
12
- | 0x2006
13
- | 0x2007
14
- | 0x2008
15
- | 0x2009
16
- | 0x200a
17
- | 0x202f
18
- | 0x205f
19
- | 0x3000
20
- | 0xfeff
21
- | 0x0a
22
- | 0x0d
23
- | 0x2028
24
- | 0x2029
25
- | 0x20
26
- | 0x09
27
- | 0x0b
28
- | 0x0c
29
- | 0xa0
30
- | 0x1680;
31
-
32
- export type PathCommandNumber = 0x6d | 0x7a | 0x6c | 0x68 | 0x76 | 0x63 | 0x73 | 0x71 | 0x74 | 0x61;
33
-
34
- export type DigitNumber = 0x30 | 0x31 | 0x32 | 0x33 | 0x34 | 0x35 | 0x36 | 0x37 | 0x38 | 0x39;
35
-
36
- // custom types
37
- export type MCommand = 'M';
38
- export type mCommand = 'm';
39
-
40
- export type LCommand = 'L';
41
- export type lCommand = 'l';
42
-
43
- export type VCommand = 'V';
44
- export type vCommand = 'v';
45
-
46
- export type HCommand = 'H';
47
- export type hCommand = 'h';
48
-
49
- export type ZCommand = 'Z';
50
- export type zCommand = 'z';
51
-
52
- export type CCommand = 'C';
53
- export type cCommand = 'c';
54
-
55
- export type SCommand = 'S';
56
- export type sCommand = 's';
57
-
58
- export type QCommand = 'Q';
59
- export type qCommand = 'q';
60
-
61
- export type TCommand = 'T';
62
- export type tCommand = 't';
63
-
64
- export type ACommand = 'A';
65
- export type aCommand = 'a';
66
-
67
- export type AbsoluteCommand =
68
- | MCommand
69
- | LCommand
70
- | VCommand
71
- | HCommand
72
- | ZCommand
73
- | CCommand
74
- | SCommand
75
- | QCommand
76
- | TCommand
77
- | ACommand;
78
-
79
- export type RelativeCommand =
80
- | mCommand
81
- | lCommand
82
- | vCommand
83
- | hCommand
84
- | zCommand
85
- | cCommand
86
- | sCommand
87
- | qCommand
88
- | tCommand
89
- | aCommand;
90
-
91
- export type PathCommand = AbsoluteCommand | RelativeCommand;
92
-
93
- export type MSegment = [MCommand, number, number];
94
- export type mSegment = [mCommand, number, number];
95
- export type MoveSegment = MSegment | mSegment;
96
-
97
- export type LSegment = [LCommand, number, number];
98
- export type lSegment = [lCommand, number, number];
99
- export type LineSegment = LSegment | lSegment;
100
-
101
- export type VSegment = [VCommand, number];
102
- export type vSegment = [vCommand, number];
103
- export type VertLineSegment = vSegment | VSegment;
104
-
105
- export type HSegment = [HCommand, number];
106
- export type hSegment = [hCommand, number];
107
- export type HorLineSegment = HSegment | hSegment;
108
-
109
- export type ZSegment = [ZCommand];
110
- export type zSegment = [zCommand];
111
- export type CloseSegment = ZSegment | zSegment;
112
-
113
- export type CSegment = [CCommand, number, number, number, number, number, number];
114
- export type cSegment = [cCommand, number, number, number, number, number, number];
115
- export type CubicSegment = CSegment | cSegment;
116
-
117
- export type SSegment = [SCommand, number, number, number, number];
118
- export type sSegment = [sCommand, number, number, number, number];
119
- export type ShortCubicSegment = SSegment | sSegment;
120
-
121
- export type QSegment = [QCommand, number, number, number, number];
122
- export type qSegment = [qCommand, number, number, number, number];
123
- export type QuadSegment = QSegment | qSegment;
124
-
125
- export type TSegment = [TCommand, number, number];
126
- export type tSegment = [tCommand, number, number];
127
- export type ShortQuadSegment = TSegment | tSegment;
128
-
129
- export type ASegment = [ACommand, number, number, number, number, number, number, number];
130
- export type aSegment = [aCommand, number, number, number, number, number, number, number];
131
- export type ArcSegment = ASegment | aSegment;
132
-
133
- export type PathSegment =
134
- | MoveSegment
135
- | LineSegment
136
- | VertLineSegment
137
- | HorLineSegment
138
- | CloseSegment
139
- | CubicSegment
140
- | ShortCubicSegment
141
- | QuadSegment
142
- | ShortQuadSegment
143
- | ArcSegment;
144
-
145
- export type ShortSegment = VertLineSegment | HorLineSegment | ShortCubicSegment | ShortQuadSegment | CloseSegment;
146
-
147
- export type AbsoluteSegment =
148
- | MSegment
149
- | LSegment
150
- | VSegment
151
- | HSegment
152
- | CSegment
153
- | SSegment
154
- | QSegment
155
- | TSegment
156
- | ASegment
157
- | ZSegment;
158
-
159
- export type RelativeSegment =
160
- | mSegment
161
- | lSegment
162
- | vSegment
163
- | hSegment
164
- | cSegment
165
- | sSegment
166
- | qSegment
167
- | tSegment
168
- | aSegment
169
- | zSegment;
170
-
171
- export type NormalSegment = MSegment | LSegment | CSegment | QSegment | ASegment | ZSegment;
172
-
173
- export type PathArray = [MSegment | mSegment, ...PathSegment[]];
174
- export type AbsoluteArray = [MSegment, ...AbsoluteSegment[]];
175
- export type RelativeArray = [MSegment, ...RelativeSegment[]];
176
- export type NormalArray = [MSegment, ...NormalSegment[]];
177
- export type CurveArray = [MSegment, ...CSegment[]];
178
- export type PolygonArray = [MSegment, ...LSegment[], ZSegment];
179
- export type PolylineArray = [MSegment, ...LSegment[]];
180
-
181
- export type ShapeTypes =
182
- | SVGPolylineElement
183
- | SVGPolygonElement
184
- | SVGLineElement
185
- | SVGEllipseElement
186
- | SVGCircleElement
187
- | SVGRectElement;
188
-
189
- export type ShapeTags = 'line' | 'polyline' | 'polygon' | 'ellipse' | 'circle' | 'rect' | 'glyph';
190
-
191
- export type ShapeOps = LineAttr | PolyAttr | PolyAttr | EllipseAttr | CircleAttr | RectAttr | GlyphAttr;
192
-
193
- export type TransformObjectValues = Partial<TransformObject> & { origin: [number, number, number] };
194
-
195
- export type Point = {
196
- x: number;
197
- y: number;
198
- };
199
-
200
- export type PointTuple = [number, number];
201
-
202
- export type DerivedPoint = Point & { t: number };
203
- export type QuadPoints = [Point, Point, Point, Point, Point, Point];
204
- export type CubicPoints = [Point, Point, Point, Point, Point, Point, Point, Point];
205
- export type DerivedQuadPoints = [DerivedPoint, DerivedPoint, DerivedPoint, DerivedPoint, DerivedPoint, DerivedPoint];
206
- export type DerivedCubicPoints = [
207
- DerivedPoint,
208
- DerivedPoint,
209
- DerivedPoint,
210
- DerivedPoint,
211
- DerivedPoint,
212
- DerivedPoint,
213
- DerivedPoint,
214
- DerivedPoint,
215
- ];
216
- export type QuadCoordinates = [number, number, number, number, number, number];
217
- export type CubicCoordinates = [number, number, number, number, number, number, number, number];
218
- export type ArcCoordinates = [number, number, number, number, number, number, number, number, number];
219
- export type LineCoordinates = [number, number, number, number];
220
-
221
- export type DeriveCallback = (t: number) => Point;
222
-
223
- export type IteratorCallback = (
224
- segment: PathSegment,
225
- index: number,
226
- lastX: number,
227
- lastY: number,
228
- ) => PathSegment | false | void | undefined;
@@ -1,3 +0,0 @@
1
- const DISTANCE_EPSILON = 0.00001;
2
-
3
- export default DISTANCE_EPSILON;
@@ -1,15 +0,0 @@
1
- import type { PathArray } from '../types';
2
- import getPropertiesAtPoint from './getPropertiesAtPoint';
3
-
4
- /**
5
- * Returns the point in path closest to a given point.
6
- *
7
- * @param pathInput target `pathArray`
8
- * @param point the given point
9
- * @returns the best match
10
- */
11
- const getClosestPoint = (pathInput: string | PathArray, point: { x: number; y: number }) => {
12
- return getPropertiesAtPoint(pathInput, point).closest;
13
- };
14
-
15
- export default getClosestPoint;
@@ -1,16 +0,0 @@
1
- import getPathArea from './getPathArea';
2
- import pathToCurve from '../convert/pathToCurve';
3
- import type { PathArray } from '../types';
4
-
5
- /**
6
- * Check if a path is drawn clockwise and returns true if so,
7
- * false otherwise.
8
- *
9
- * @param path the path string or `pathArray`
10
- * @returns true when clockwise or false if not
11
- */
12
- const getDrawDirection = (path: string | PathArray) => {
13
- return getPathArea(pathToCurve(path)) >= 0;
14
- };
15
-
16
- export default getDrawDirection;
@@ -1,70 +0,0 @@
1
- import pathToCurve from '../convert/pathToCurve';
2
- import type { PointTuple, PathArray } from '../types';
3
-
4
- /**
5
- * Returns the area of a single cubic-bezier segment.
6
- *
7
- * http://objectmix.com/graphics/133553-area-closed-bezier-curve.html
8
- *
9
- * @param x1 the starting point X
10
- * @param y1 the starting point Y
11
- * @param c1x the first control point X
12
- * @param c1y the first control point Y
13
- * @param c2x the second control point X
14
- * @param c2y the second control point Y
15
- * @param x2 the ending point X
16
- * @param y2 the ending point Y
17
- * @returns the area of the cubic-bezier segment
18
- */
19
- const getCubicSegArea = (
20
- x1: number,
21
- y1: number,
22
- c1x: number,
23
- c1y: number,
24
- c2x: number,
25
- c2y: number,
26
- x2: number,
27
- y2: number,
28
- ) => {
29
- return (
30
- (3 *
31
- ((y2 - y1) * (c1x + c2x) -
32
- (x2 - x1) * (c1y + c2y) +
33
- c1y * (x1 - c2x) -
34
- c1x * (y1 - c2y) +
35
- y2 * (c2x + x1 / 3) -
36
- x2 * (c2y + y1 / 3))) /
37
- 20
38
- );
39
- };
40
-
41
- /**
42
- * Returns the area of a shape.
43
- *
44
- * @author Jürg Lehni & Jonathan Puckey
45
- *
46
- * @see https://github.com/paperjs/paper.js/blob/develop/src/path/Path.js
47
- *
48
- * @param path the shape `pathArray`
49
- * @returns the length of the cubic-bezier segment
50
- */
51
- const getPathArea = (path: PathArray) => {
52
- let x = 0;
53
- let y = 0;
54
- let len = 0;
55
-
56
- return pathToCurve(path)
57
- .map(seg => {
58
- switch (seg[0]) {
59
- case 'M':
60
- [, x, y] = seg;
61
- return 0;
62
- default:
63
- len = getCubicSegArea(x, y, seg[1], seg[2], seg[3], seg[4], seg[5], seg[6]);
64
- [x, y] = seg.slice(-2) as PointTuple;
65
- return len;
66
- }
67
- })
68
- .reduce((a, b) => a + b, 0);
69
- };
70
- export default getPathArea;
@@ -1,98 +0,0 @@
1
- import iterate from '../process/iterate';
2
- import { PathBBox } from '../interface';
3
- import { MSegment, PathArray, Point } from '../types';
4
- import { getLineBBox } from '../math/lineTools';
5
- import { getArcBBox } from '../math/arcTools';
6
- import { getCubicBBox } from '../math/cubicTools';
7
- import { getQuadBBox } from '../math/quadTools';
8
- import parsePathString from '../parser/parsePathString';
9
- import paramsParser from '../parser/paramsParser';
10
- import normalizeSegment from '../process/normalizeSegment';
11
-
12
- const getPathBBox = (pathInput: PathArray | string) => {
13
- if (!pathInput) {
14
- return {
15
- x: 0,
16
- y: 0,
17
- width: 0,
18
- height: 0,
19
- x2: 0,
20
- y2: 0,
21
- cx: 0,
22
- cy: 0,
23
- cz: 0,
24
- };
25
- }
26
-
27
- const path = parsePathString(pathInput);
28
- let data = [] as number[];
29
- let pathCommand = 'M';
30
- const x = 0;
31
- const y = 0;
32
- let mx = 0;
33
- let my = 0;
34
- const MIN = [] as Point[];
35
- const MAX = [] as Point[];
36
- let min = { x, y };
37
- let max = { x, y };
38
- const params = { ...paramsParser };
39
-
40
- iterate(path, (seg, _, lastX, lastY) => {
41
- params.x = lastX;
42
- params.y = lastY;
43
- const result = normalizeSegment(seg, params);
44
- [pathCommand] = result;
45
- data = [lastX, lastY].concat(result.slice(1) as number[]);
46
-
47
- // this segment is always ZERO
48
- /* istanbul ignore else @preserve */
49
- if (pathCommand === 'M') {
50
- // remember mx, my for Z
51
- [, mx, my] = result as MSegment;
52
- min = { x: mx, y: my };
53
- max = { x: mx, y: my };
54
- } else if (pathCommand === 'L') {
55
- ({ min, max } = getLineBBox(data[0], data[1], data[2], data[3]));
56
- } else if (pathCommand === 'A') {
57
- ({ min, max } = getArcBBox(data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8]));
58
- } else if (pathCommand === 'C') {
59
- ({ min, max } = getCubicBBox(data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]));
60
- } else if (pathCommand === 'Q') {
61
- ({ min, max } = getQuadBBox(data[0], data[1], data[2], data[3], data[4], data[5]));
62
- } else if (pathCommand === 'Z') {
63
- data = [lastX, lastY, mx, my];
64
- ({ min, max } = getLineBBox(data[0], data[1], data[2], data[3]));
65
- }
66
-
67
- MIN.push(min);
68
- MAX.push(max);
69
-
70
- const seglen = result.length;
71
- params.x1 = +result[seglen - 2];
72
- params.y1 = +result[seglen - 1];
73
- params.x2 = +result[seglen - 4] || params.x1;
74
- params.y2 = +result[seglen - 3] || params.y1;
75
- });
76
-
77
- const xMin = Math.min(...MIN.map(n => n.x));
78
- const xMax = Math.max(...MAX.map(n => n.x));
79
- const yMin = Math.min(...MIN.map(n => n.y));
80
- const yMax = Math.max(...MAX.map(n => n.y));
81
- const width = xMax - xMin;
82
- const height = yMax - yMin;
83
-
84
- return {
85
- width,
86
- height,
87
- x: xMin,
88
- y: yMin,
89
- x2: xMax,
90
- y2: yMax,
91
- cx: xMin + width / 2,
92
- cy: yMin + height / 2,
93
- // an estimated guess
94
- cz: Math.max(width, height) + Math.min(width, height) / 2,
95
- } satisfies PathBBox;
96
- };
97
-
98
- export default getPathBBox;
@@ -1,110 +0,0 @@
1
- import DISTANCE_EPSILON from './distanceEpsilon';
2
- import type { MSegment, PathArray, PointTuple } from '../types';
3
- import iterate from '../process/iterate';
4
- import { getLineLength, getPointAtLineLength } from '../math/lineTools';
5
- import { getArcLength, getPointAtArcLength } from '../math/arcTools';
6
- import { getCubicLength, getPointAtCubicLength } from '../math/cubicTools';
7
- import { getQuadLength, getPointAtQuadLength } from '../math/quadTools';
8
- import normalizePath from '../process/normalizePath';
9
-
10
- /**
11
- * Returns [x,y] coordinates of a point at a given length of a shape.
12
- *
13
- * @param pathInput the `pathArray` to look into
14
- * @param distance the length of the shape to look at
15
- * @returns the requested {x, y} point coordinates
16
- */
17
- const getPointAtLength = (pathInput: string | PathArray, distance?: number) => {
18
- const path = normalizePath(pathInput);
19
- let isM = false;
20
- let data = [] as number[];
21
- let pathCommand = 'M';
22
- let x = 0;
23
- let y = 0;
24
- let [mx, my] = path[0].slice(1) as PointTuple;
25
- const distanceIsNumber = typeof distance === 'number';
26
- let point = { x: mx, y: my };
27
- let length = 0;
28
- let POINT = point;
29
- let totalLength = 0;
30
-
31
- if (!distanceIsNumber || distance < DISTANCE_EPSILON) return point;
32
-
33
- // for (let i = 0; i < pathLen; i += 1) {
34
- iterate(path, (seg, _, lastX, lastY) => {
35
- [pathCommand] = seg;
36
- isM = pathCommand === 'M';
37
- data = !isM ? [lastX, lastY].concat(seg.slice(1) as number[]) : data;
38
-
39
- // this segment is always ZERO
40
- /* istanbul ignore else @preserve */
41
- if (isM) {
42
- // remember mx, my for Z
43
- [, mx, my] = seg as MSegment;
44
- point = { x: mx, y: my };
45
- length = 0;
46
- } else if (pathCommand === 'L') {
47
- point = getPointAtLineLength(data[0], data[1], data[2], data[3], distance - totalLength);
48
- length = getLineLength(data[0], data[1], data[2], data[3]);
49
- } else if (pathCommand === 'A') {
50
- point = getPointAtArcLength(
51
- data[0],
52
- data[1],
53
- data[2],
54
- data[3],
55
- data[4],
56
- data[5],
57
- data[6],
58
- data[7],
59
- data[8],
60
- distance - totalLength,
61
- );
62
- length = getArcLength(data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8]);
63
- } else if (pathCommand === 'C') {
64
- point = getPointAtCubicLength(
65
- data[0],
66
- data[1],
67
- data[2],
68
- data[3],
69
- data[4],
70
- data[5],
71
- data[6],
72
- data[7],
73
- distance - totalLength,
74
- );
75
- length = getCubicLength(data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
76
- } else if (pathCommand === 'Q') {
77
- point = getPointAtQuadLength(data[0], data[1], data[2], data[3], data[4], data[5], distance - totalLength);
78
- length = getQuadLength(data[0], data[1], data[2], data[3], data[4], data[5]);
79
- } else if (pathCommand === 'Z') {
80
- data = [lastX, lastY, mx, my];
81
- point = { x: mx, y: my };
82
-
83
- length = getLineLength(data[0], data[1], data[2], data[3]);
84
- }
85
-
86
- [x, y] = data.slice(-2);
87
-
88
- if (totalLength < distance) {
89
- POINT = point;
90
- } else {
91
- // totalLength >= distance
92
- // stop right here
93
- // stop iterator now!
94
- return false;
95
- }
96
-
97
- totalLength += length;
98
- return;
99
- });
100
-
101
- // native `getPointAtLength` behavior when the given distance
102
- // is higher than total length
103
- if (distance > totalLength - DISTANCE_EPSILON) {
104
- return { x, y };
105
- }
106
-
107
- return POINT;
108
- };
109
-
110
- export default getPointAtLength;