svg-path-commander 2.1.3 → 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.
- package/README.md +4 -4
- package/dist/svg-path-commander.cjs +1 -1
- package/dist/svg-path-commander.cjs.map +1 -1
- package/dist/svg-path-commander.d.ts +755 -830
- package/dist/svg-path-commander.js +1 -1
- package/dist/svg-path-commander.js.map +1 -1
- package/dist/svg-path-commander.mjs +287 -56
- package/dist/svg-path-commander.mjs.map +1 -1
- package/package.json +14 -22
- package/.eslintrc.cjs +0 -225
- package/.prettierrc.json +0 -15
- package/dts.config.ts +0 -15
- package/src/convert/pathToAbsolute.ts +0 -18
- package/src/convert/pathToCurve.ts +0 -43
- package/src/convert/pathToRelative.ts +0 -18
- package/src/convert/pathToString.ts +0 -50
- package/src/index.ts +0 -454
- package/src/interface.ts +0 -130
- package/src/math/arcTools.ts +0 -388
- package/src/math/bezier.ts +0 -261
- package/src/math/cubicTools.ts +0 -123
- package/src/math/distanceSquareRoot.ts +0 -15
- package/src/math/lineTools.ts +0 -61
- package/src/math/midPoint.ts +0 -18
- package/src/math/polygonTools.ts +0 -48
- package/src/math/quadTools.ts +0 -98
- package/src/math/rotateVector.ts +0 -17
- package/src/math/roundTo.ts +0 -7
- package/src/options/options.ts +0 -9
- package/src/parser/error.ts +0 -2
- package/src/parser/finalizeSegment.ts +0 -35
- package/src/parser/invalidPathValue.ts +0 -2
- package/src/parser/isArcCommand.ts +0 -11
- package/src/parser/isDigit.ts +0 -12
- package/src/parser/isDigitStart.ts +0 -14
- package/src/parser/isMoveCommand.ts +0 -17
- package/src/parser/isPathCommand.ts +0 -28
- package/src/parser/isSpace.ts +0 -23
- package/src/parser/paramsCount.ts +0 -16
- package/src/parser/paramsParser.ts +0 -14
- package/src/parser/parsePathString.ts +0 -33
- package/src/parser/pathParser.ts +0 -29
- package/src/parser/scanFlag.ts +0 -29
- package/src/parser/scanParam.ts +0 -102
- package/src/parser/scanSegment.ts +0 -84
- package/src/parser/skipSpaces.ts +0 -17
- package/src/process/absolutizeSegment.ts +0 -67
- package/src/process/arcToCubic.ts +0 -128
- package/src/process/getSVGMatrix.ts +0 -70
- package/src/process/iterate.ts +0 -58
- package/src/process/lineToCubic.ts +0 -17
- package/src/process/normalizePath.ts +0 -33
- package/src/process/normalizeSegment.ts +0 -84
- package/src/process/optimizePath.ts +0 -62
- package/src/process/projection2d.ts +0 -52
- package/src/process/quadToCubic.ts +0 -31
- package/src/process/relativizeSegment.ts +0 -63
- package/src/process/reverseCurve.ts +0 -24
- package/src/process/reversePath.ts +0 -114
- package/src/process/roundPath.ts +0 -33
- package/src/process/roundSegment.ts +0 -9
- package/src/process/segmentToCubic.ts +0 -48
- package/src/process/shortenSegment.ts +0 -71
- package/src/process/splitCubic.ts +0 -29
- package/src/process/splitPath.ts +0 -63
- package/src/process/transformPath.ts +0 -114
- package/src/types.ts +0 -228
- package/src/util/distanceEpsilon.ts +0 -3
- package/src/util/getClosestPoint.ts +0 -15
- package/src/util/getDrawDirection.ts +0 -16
- package/src/util/getPathArea.ts +0 -70
- package/src/util/getPathBBox.ts +0 -171
- package/src/util/getPointAtLength.ts +0 -110
- package/src/util/getPropertiesAtLength.ts +0 -67
- package/src/util/getPropertiesAtPoint.ts +0 -84
- package/src/util/getSegmentAtLength.ts +0 -15
- package/src/util/getSegmentOfPoint.ts +0 -18
- package/src/util/getTotalLength.ts +0 -133
- package/src/util/isAbsoluteArray.ts +0 -18
- package/src/util/isCurveArray.ts +0 -15
- package/src/util/isNormalizedArray.ts +0 -16
- package/src/util/isPathArray.ts +0 -24
- package/src/util/isPointInStroke.ts +0 -16
- package/src/util/isRelativeArray.ts +0 -18
- package/src/util/isValidPath.ts +0 -27
- package/src/util/shapeParams.ts +0 -16
- package/src/util/shapeToPath.ts +0 -86
- package/src/util/shapeToPathArray.ts +0 -183
- package/test/class.test.ts +0 -506
- package/test/fixtures/getMarkup.ts +0 -17
- package/test/fixtures/shapeObjects.ts +0 -11
- package/test/fixtures/shapes.js +0 -104
- package/test/fixtures/simpleShapes.js +0 -87
- package/test/static.test.ts +0 -330
- package/vite.config.mts +0 -41
- package/vitest.config-ui.mts +0 -31
- package/vitest.config.mts +0 -31
|
@@ -1,114 +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 absolutizeSegment from './absolutizeSegment';
|
|
9
|
-
import arcToCubic from './arcToCubic';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Apply a 2D / 3D transformation to a `pathArray` instance.
|
|
13
|
-
*
|
|
14
|
-
* Since *SVGElement* doesn't support 3D transformation, this function
|
|
15
|
-
* creates a 2D projection of the <path> element.
|
|
16
|
-
*
|
|
17
|
-
* @param path the `pathArray` to apply transformation
|
|
18
|
-
* @param transform the transform functions `Object`
|
|
19
|
-
* @returns the resulted `pathArray`
|
|
20
|
-
*/
|
|
21
|
-
const transformPath = (pathInput: PathArray | string, transform?: Partial<TransformObject>) => {
|
|
22
|
-
// last x and y transformed values
|
|
23
|
-
let x = 0;
|
|
24
|
-
let y = 0;
|
|
25
|
-
// new x and y transformed
|
|
26
|
-
let lx = 0;
|
|
27
|
-
let ly = 0;
|
|
28
|
-
// segment params iteration index and length
|
|
29
|
-
let j = 0;
|
|
30
|
-
let jj = 0;
|
|
31
|
-
let pathCommand = 'M';
|
|
32
|
-
// transform uses it's own set of params
|
|
33
|
-
const path = parsePathString(pathInput);
|
|
34
|
-
const transformProps = transform && Object.keys(transform);
|
|
35
|
-
|
|
36
|
-
// when used as a static method, invalidate somehow
|
|
37
|
-
if (!transform || (transformProps && !transformProps.length)) return path.slice(0) as typeof path;
|
|
38
|
-
|
|
39
|
-
// transform origin is extremely important
|
|
40
|
-
if (!transform.origin) {
|
|
41
|
-
Object.assign(transform, { origin: defaultOptions.origin });
|
|
42
|
-
}
|
|
43
|
-
const origin = transform.origin as [number, number, number];
|
|
44
|
-
const matrixInstance = getSVGMatrix(transform as TransformObjectValues);
|
|
45
|
-
|
|
46
|
-
if (matrixInstance.isIdentity) return path.slice(0) as typeof path;
|
|
47
|
-
|
|
48
|
-
return iterate<AbsoluteArray>(path, (seg, index, lastX, lastY) => {
|
|
49
|
-
[pathCommand] = seg;
|
|
50
|
-
const absCommand = pathCommand.toUpperCase();
|
|
51
|
-
const isRelative = absCommand !== pathCommand;
|
|
52
|
-
const absoluteSegment = isRelative
|
|
53
|
-
? absolutizeSegment(seg, index, lastX, lastY)
|
|
54
|
-
: (seg.slice(0) as AbsoluteSegment);
|
|
55
|
-
|
|
56
|
-
let result =
|
|
57
|
-
absCommand === 'A'
|
|
58
|
-
? // ? segmentToCubic(absoluteSegment, transformParams)
|
|
59
|
-
(['C' as string | number].concat(
|
|
60
|
-
arcToCubic(
|
|
61
|
-
lastX,
|
|
62
|
-
lastY,
|
|
63
|
-
absoluteSegment[1] as number,
|
|
64
|
-
absoluteSegment[2] as number,
|
|
65
|
-
absoluteSegment[3] as number,
|
|
66
|
-
absoluteSegment[4] as number,
|
|
67
|
-
absoluteSegment[5] as number,
|
|
68
|
-
absoluteSegment[6] as number,
|
|
69
|
-
absoluteSegment[7] as number,
|
|
70
|
-
),
|
|
71
|
-
) as CSegment)
|
|
72
|
-
: absCommand === 'V'
|
|
73
|
-
? (['L', lastX, absoluteSegment[1]] as LSegment)
|
|
74
|
-
: absCommand === 'H'
|
|
75
|
-
? (['L', absoluteSegment[1], lastY] as LSegment)
|
|
76
|
-
: absoluteSegment;
|
|
77
|
-
|
|
78
|
-
// update pathCommand
|
|
79
|
-
pathCommand = result[0];
|
|
80
|
-
const isLongArc = pathCommand === 'C' && result.length > 7;
|
|
81
|
-
const tempSegment = (isLongArc ? result.slice(0, 7) : result.slice(0)) as AbsoluteSegment;
|
|
82
|
-
|
|
83
|
-
if (isLongArc) {
|
|
84
|
-
path.splice(index + 1, 0, ['C' as typeof pathCommand | number].concat(result.slice(7)) as CSegment);
|
|
85
|
-
result = tempSegment as CSegment;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (pathCommand === 'L') {
|
|
89
|
-
[lx, ly] = projection2d(matrixInstance, [(result as LSegment)[1], (result as LSegment)[2]], origin);
|
|
90
|
-
|
|
91
|
-
/* istanbul ignore else @preserve */
|
|
92
|
-
if (x !== lx && y !== ly) {
|
|
93
|
-
result = ['L', lx, ly];
|
|
94
|
-
} else if (y === ly) {
|
|
95
|
-
result = ['H', lx];
|
|
96
|
-
} else if (x === lx) {
|
|
97
|
-
result = ['V', ly];
|
|
98
|
-
}
|
|
99
|
-
} else {
|
|
100
|
-
for (j = 1, jj = result.length; j < jj; j += 2) {
|
|
101
|
-
[lx, ly] = projection2d(matrixInstance, [+result[j], +result[j + 1]], origin);
|
|
102
|
-
result[j] = lx;
|
|
103
|
-
result[j + 1] = ly;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
// now update x and y
|
|
107
|
-
x = lx;
|
|
108
|
-
y = ly;
|
|
109
|
-
|
|
110
|
-
return result;
|
|
111
|
-
});
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
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,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;
|
package/src/util/getPathArea.ts
DELETED
|
@@ -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;
|
package/src/util/getPathBBox.ts
DELETED
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import iterate from '../process/iterate';
|
|
2
|
-
import { PathBBox } from '../interface';
|
|
3
|
-
import { LSegment, MSegment, PathArray, PointTuple } 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 absolutizeSegment from '../process/absolutizeSegment';
|
|
10
|
-
|
|
11
|
-
const getPathBBox = (pathInput: PathArray | string) => {
|
|
12
|
-
if (!pathInput) {
|
|
13
|
-
return {
|
|
14
|
-
x: 0,
|
|
15
|
-
y: 0,
|
|
16
|
-
width: 0,
|
|
17
|
-
height: 0,
|
|
18
|
-
x2: 0,
|
|
19
|
-
y2: 0,
|
|
20
|
-
cx: 0,
|
|
21
|
-
cy: 0,
|
|
22
|
-
cz: 0,
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const path = parsePathString(pathInput);
|
|
27
|
-
let pathCommand = 'M';
|
|
28
|
-
let mx = 0;
|
|
29
|
-
let my = 0;
|
|
30
|
-
const { max, min } = Math;
|
|
31
|
-
let xMin = Infinity;
|
|
32
|
-
let yMin = Infinity;
|
|
33
|
-
let xMax = -Infinity;
|
|
34
|
-
let yMax = -Infinity;
|
|
35
|
-
let minX = 0;
|
|
36
|
-
let minY = 0;
|
|
37
|
-
let maxX = 0;
|
|
38
|
-
let maxY = 0;
|
|
39
|
-
let paramX1 = 0;
|
|
40
|
-
let paramY1 = 0;
|
|
41
|
-
let paramX2 = 0;
|
|
42
|
-
let paramY2 = 0;
|
|
43
|
-
let paramQX = 0;
|
|
44
|
-
let paramQY = 0;
|
|
45
|
-
|
|
46
|
-
iterate(path, (seg, index, lastX, lastY) => {
|
|
47
|
-
[pathCommand] = seg;
|
|
48
|
-
const absCommand = pathCommand.toUpperCase();
|
|
49
|
-
const isRelative = absCommand !== pathCommand;
|
|
50
|
-
const absoluteSegment = isRelative ? absolutizeSegment(seg, index, lastX, lastY) : (seg.slice(0) as typeof seg);
|
|
51
|
-
|
|
52
|
-
const normalSegment =
|
|
53
|
-
absCommand === 'V'
|
|
54
|
-
? (['L', lastX, absoluteSegment[1]] as LSegment)
|
|
55
|
-
: absCommand === 'H'
|
|
56
|
-
? (['L', absoluteSegment[1], lastY] as LSegment)
|
|
57
|
-
: absoluteSegment;
|
|
58
|
-
|
|
59
|
-
[pathCommand] = normalSegment;
|
|
60
|
-
|
|
61
|
-
if (!'TQ'.includes(absCommand)) {
|
|
62
|
-
// optional but good to be cautious
|
|
63
|
-
paramQX = 0;
|
|
64
|
-
paramQY = 0;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// this segment is always ZERO
|
|
68
|
-
/* istanbul ignore else @preserve */
|
|
69
|
-
if (pathCommand === 'M') {
|
|
70
|
-
[, mx, my] = normalSegment as MSegment;
|
|
71
|
-
minX = mx;
|
|
72
|
-
minY = my;
|
|
73
|
-
maxX = mx;
|
|
74
|
-
maxY = my;
|
|
75
|
-
} else if (pathCommand === 'L') {
|
|
76
|
-
[minX, minY, maxX, maxY] = getLineBBox(lastX, lastY, normalSegment[1] as number, normalSegment[2] as number);
|
|
77
|
-
} else if (pathCommand === 'A') {
|
|
78
|
-
[minX, minY, maxX, maxY] = getArcBBox(
|
|
79
|
-
lastX,
|
|
80
|
-
lastY,
|
|
81
|
-
normalSegment[1] as number,
|
|
82
|
-
normalSegment[2] as number,
|
|
83
|
-
normalSegment[3] as number,
|
|
84
|
-
normalSegment[4] as number,
|
|
85
|
-
normalSegment[5] as number,
|
|
86
|
-
normalSegment[6] as number,
|
|
87
|
-
normalSegment[7] as number,
|
|
88
|
-
);
|
|
89
|
-
} else if (pathCommand === 'S') {
|
|
90
|
-
const cp1x = paramX1 * 2 - paramX2;
|
|
91
|
-
const cp1y = paramY1 * 2 - paramY2;
|
|
92
|
-
|
|
93
|
-
[minX, minY, maxX, maxY] = getCubicBBox(
|
|
94
|
-
lastX,
|
|
95
|
-
lastY,
|
|
96
|
-
cp1x,
|
|
97
|
-
cp1y,
|
|
98
|
-
normalSegment[1] as number,
|
|
99
|
-
normalSegment[2] as number,
|
|
100
|
-
normalSegment[3] as number,
|
|
101
|
-
normalSegment[4] as number,
|
|
102
|
-
);
|
|
103
|
-
} else if (pathCommand === 'C') {
|
|
104
|
-
[minX, minY, maxX, maxY] = getCubicBBox(
|
|
105
|
-
lastX,
|
|
106
|
-
lastY,
|
|
107
|
-
normalSegment[1] as number,
|
|
108
|
-
normalSegment[2] as number,
|
|
109
|
-
normalSegment[3] as number,
|
|
110
|
-
normalSegment[4] as number,
|
|
111
|
-
normalSegment[5] as number,
|
|
112
|
-
normalSegment[6] as number,
|
|
113
|
-
);
|
|
114
|
-
} else if (pathCommand === 'T') {
|
|
115
|
-
paramQX = paramX1 * 2 - paramQX;
|
|
116
|
-
paramQY = paramY1 * 2 - paramQY;
|
|
117
|
-
[minX, minY, maxX, maxY] = getQuadBBox(
|
|
118
|
-
lastX,
|
|
119
|
-
lastY,
|
|
120
|
-
paramQX,
|
|
121
|
-
paramQY,
|
|
122
|
-
normalSegment[1] as number,
|
|
123
|
-
normalSegment[2] as number,
|
|
124
|
-
);
|
|
125
|
-
} else if (pathCommand === 'Q') {
|
|
126
|
-
paramQX = normalSegment[1] as number;
|
|
127
|
-
paramQY = normalSegment[2] as number;
|
|
128
|
-
[minX, minY, maxX, maxY] = getQuadBBox(
|
|
129
|
-
lastX,
|
|
130
|
-
lastY,
|
|
131
|
-
normalSegment[1] as number,
|
|
132
|
-
normalSegment[2] as number,
|
|
133
|
-
normalSegment[3] as number,
|
|
134
|
-
normalSegment[4] as number,
|
|
135
|
-
);
|
|
136
|
-
} else if (pathCommand === 'Z') {
|
|
137
|
-
[minX, minY, maxX, maxY] = getLineBBox(lastX, lastY, mx, my);
|
|
138
|
-
}
|
|
139
|
-
xMin = min(minX, xMin);
|
|
140
|
-
yMin = min(minY, yMin);
|
|
141
|
-
xMax = max(maxX, xMax);
|
|
142
|
-
yMax = max(maxY, yMax);
|
|
143
|
-
|
|
144
|
-
// update params
|
|
145
|
-
[paramX1, paramY1] = pathCommand === 'Z' ? [mx, my] : (normalSegment.slice(-2) as PointTuple);
|
|
146
|
-
[paramX2, paramY2] =
|
|
147
|
-
pathCommand === 'C'
|
|
148
|
-
? ([normalSegment[3], normalSegment[4]] as PointTuple)
|
|
149
|
-
: pathCommand === 'S'
|
|
150
|
-
? ([normalSegment[1], normalSegment[2]] as PointTuple)
|
|
151
|
-
: [paramX1, paramY1];
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
const width = xMax - xMin;
|
|
155
|
-
const height = yMax - yMin;
|
|
156
|
-
|
|
157
|
-
return {
|
|
158
|
-
width,
|
|
159
|
-
height,
|
|
160
|
-
x: xMin,
|
|
161
|
-
y: yMin,
|
|
162
|
-
x2: xMax,
|
|
163
|
-
y2: yMax,
|
|
164
|
-
cx: xMin + width / 2,
|
|
165
|
-
cy: yMin + height / 2,
|
|
166
|
-
// an estimated guess
|
|
167
|
-
cz: Math.max(width, height) + Math.min(width, height) / 2,
|
|
168
|
-
} satisfies PathBBox;
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
export default getPathBBox;
|