svg-path-commander 2.1.0 → 2.1.1
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 +61 -5
- package/dist/svg-path-commander.cjs +1 -1
- package/dist/svg-path-commander.cjs.map +1 -1
- package/dist/svg-path-commander.d.ts +119 -33
- package/dist/svg-path-commander.js +1 -1
- package/dist/svg-path-commander.js.map +1 -1
- package/dist/svg-path-commander.mjs +798 -828
- package/dist/svg-path-commander.mjs.map +1 -1
- package/package.json +3 -3
- package/src/convert/pathToAbsolute.ts +16 -70
- package/src/convert/pathToCurve.ts +36 -28
- package/src/convert/pathToRelative.ts +33 -62
- package/src/index.ts +13 -19
- package/src/interface.ts +1 -1
- package/src/math/arcTools.ts +248 -71
- package/src/math/bezier.ts +19 -27
- package/src/math/cubicTools.ts +67 -26
- package/src/math/distanceSquareRoot.ts +3 -1
- package/src/math/lineTools.ts +41 -26
- package/src/math/midPoint.ts +3 -1
- package/src/math/polygonArea.ts +3 -1
- package/src/math/polygonLength.ts +2 -1
- package/src/math/quadTools.ts +45 -26
- package/src/parser/parsePathString.ts +4 -4
- package/src/process/absolutizeSegment.ts +58 -0
- package/src/process/iterate.ts +33 -0
- package/src/process/normalizePath.ts +34 -28
- package/src/process/normalizeSegment.ts +8 -9
- package/src/process/projection2d.ts +2 -1
- package/src/process/relativizeSegment.ts +61 -0
- package/src/process/reversePath.ts +1 -1
- package/src/process/roundPath.ts +8 -10
- package/src/process/segmentToCubic.ts +1 -1
- package/src/process/shortenSegment.ts +3 -3
- package/src/process/splitCubic.ts +8 -7
- package/src/process/splitPath.ts +38 -4
- package/src/process/transformPath.ts +80 -73
- package/src/types.ts +35 -1
- package/src/util/getPathArea.ts +3 -3
- package/src/util/getPathBBox.ts +86 -19
- package/src/util/getPointAtLength.ts +98 -4
- package/src/util/getPropertiesAtLength.ts +2 -2
- package/src/util/getTotalLength.ts +71 -4
- package/test/class.test.ts +15 -14
- package/test/fixtures/shapes.js +27 -27
- package/test/fixtures/simpleShapes.js +18 -18
- package/test/static.test.ts +37 -17
- package/cypress.config.ts +0 -29
- package/src/process/fixArc.ts +0 -23
- package/src/process/replaceArc.ts +0 -52
- package/src/util/pathFactory.ts +0 -130
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import type { PathArray, PathCommand, PathSegment } from '../types';
|
|
2
|
-
import isNormalizedArray from '../util/isNormalizedArray';
|
|
3
|
-
import segmentToCubic from './segmentToCubic';
|
|
4
|
-
import paramsParser from '../parser/paramsParser';
|
|
5
|
-
import normalizePath from './normalizePath';
|
|
6
|
-
import fixArc from './fixArc';
|
|
7
|
-
import isAbsoluteArray from '../util/isAbsoluteArray';
|
|
8
|
-
import pathToAbsolute from '../convert/pathToAbsolute';
|
|
9
|
-
|
|
10
|
-
const replaceArc = (pathInput: PathArray | string): PathArray => {
|
|
11
|
-
const absolutePath = isAbsoluteArray(pathInput) ? pathInput : pathToAbsolute(pathInput);
|
|
12
|
-
const normalizedPath = isNormalizedArray(absolutePath) ? absolutePath : normalizePath(absolutePath);
|
|
13
|
-
const params = { ...paramsParser };
|
|
14
|
-
const allPathCommands = [] as PathCommand[]; // needed for arc to curve transformation
|
|
15
|
-
let segment = [] as unknown as PathSegment;
|
|
16
|
-
let seglen = 0;
|
|
17
|
-
let pathCommand = '';
|
|
18
|
-
const resultedPath = [] as unknown as PathArray;
|
|
19
|
-
let i = 0;
|
|
20
|
-
let ii = absolutePath.length;
|
|
21
|
-
|
|
22
|
-
for (i = 0; i < ii; i += 1) {
|
|
23
|
-
/* istanbul ignore else @preserve */
|
|
24
|
-
if (absolutePath[i]) [pathCommand] = absolutePath[i];
|
|
25
|
-
allPathCommands[i] = pathCommand as PathCommand;
|
|
26
|
-
|
|
27
|
-
/* istanbul ignore else @preserve */
|
|
28
|
-
if (pathCommand === 'A') {
|
|
29
|
-
segment = segmentToCubic(normalizedPath[i], params);
|
|
30
|
-
|
|
31
|
-
absolutePath[i] = segmentToCubic(normalizedPath[i], params);
|
|
32
|
-
fixArc(absolutePath, allPathCommands, i);
|
|
33
|
-
|
|
34
|
-
normalizedPath[i] = segmentToCubic(normalizedPath[i], params);
|
|
35
|
-
fixArc(normalizedPath, allPathCommands, i);
|
|
36
|
-
ii = Math.max(absolutePath.length, normalizedPath.length);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
segment = normalizedPath[i];
|
|
40
|
-
seglen = segment.length;
|
|
41
|
-
|
|
42
|
-
params.x1 = +segment[seglen - 2];
|
|
43
|
-
params.y1 = +segment[seglen - 1];
|
|
44
|
-
params.x2 = +segment[seglen - 4] || params.x1;
|
|
45
|
-
params.y2 = +segment[seglen - 3] || params.y1;
|
|
46
|
-
|
|
47
|
-
resultedPath.push(absolutePath[i]);
|
|
48
|
-
}
|
|
49
|
-
return resultedPath;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
export default replaceArc;
|
package/src/util/pathFactory.ts
DELETED
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import type { MSegment, PathArray, PathSegment, Point } from '../types';
|
|
2
|
-
// import type { LengthFactory } from '../interface';
|
|
3
|
-
import normalizePath from '../process/normalizePath';
|
|
4
|
-
import getLineSegmentProperties from '../math/lineTools';
|
|
5
|
-
import getArcSegmentProperties from '../math/arcTools';
|
|
6
|
-
import getCubicSegmentProperties from '../math/cubicTools';
|
|
7
|
-
import getQuadSegmentProperties from '../math/quadTools';
|
|
8
|
-
import DISTANCE_EPSILON from './distanceEpsilon';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Returns a {x,y} point at a given length
|
|
12
|
-
* of a shape, the shape total length and
|
|
13
|
-
* the shape minimum and maximum {x,y} coordinates.
|
|
14
|
-
*
|
|
15
|
-
* @param pathInput the `pathArray` to look into
|
|
16
|
-
* @param distance the length of the shape to look at
|
|
17
|
-
* @returns the path length, point, min & max
|
|
18
|
-
*/
|
|
19
|
-
const pathFactory = (pathInput: string | PathArray, distance?: number) => {
|
|
20
|
-
const path = normalizePath(pathInput);
|
|
21
|
-
const distanceIsNumber = typeof distance === 'number';
|
|
22
|
-
let isM = false;
|
|
23
|
-
let data = [] as number[];
|
|
24
|
-
let pathCommand = 'M';
|
|
25
|
-
let x = 0;
|
|
26
|
-
let y = 0;
|
|
27
|
-
let mx = 0;
|
|
28
|
-
let my = 0;
|
|
29
|
-
let seg = path[0] as PathSegment;
|
|
30
|
-
const MIN = [] as Point[];
|
|
31
|
-
const MAX = [] as Point[];
|
|
32
|
-
let min = { x: 0, y: 0 };
|
|
33
|
-
let max = { x: 0, y: 0 };
|
|
34
|
-
let POINT = min;
|
|
35
|
-
let LENGTH = 0;
|
|
36
|
-
let props = {
|
|
37
|
-
point: { x: 0, y: 0 },
|
|
38
|
-
length: 0,
|
|
39
|
-
bbox: {
|
|
40
|
-
min: { x: 0, y: 0 },
|
|
41
|
-
max: { x: 0, y: 0 },
|
|
42
|
-
},
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
for (let i = 0, ll = path.length; i < ll; i += 1) {
|
|
46
|
-
seg = path[i];
|
|
47
|
-
[pathCommand] = seg;
|
|
48
|
-
isM = pathCommand === 'M';
|
|
49
|
-
data = !isM ? [x, y, ...(seg.slice(1) as number[])] : data;
|
|
50
|
-
|
|
51
|
-
if (distanceIsNumber && distance < DISTANCE_EPSILON) {
|
|
52
|
-
POINT = min;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// this segment is always ZERO
|
|
56
|
-
/* istanbul ignore else @preserve */
|
|
57
|
-
if (isM) {
|
|
58
|
-
// remember mx, my for Z
|
|
59
|
-
[, mx, my] = seg as MSegment;
|
|
60
|
-
min = { x: mx, y: my };
|
|
61
|
-
max = { x: mx, y: my };
|
|
62
|
-
props = {
|
|
63
|
-
point: min,
|
|
64
|
-
length: 0,
|
|
65
|
-
bbox: { min, max },
|
|
66
|
-
};
|
|
67
|
-
} else if (pathCommand === 'L') {
|
|
68
|
-
props = getLineSegmentProperties(
|
|
69
|
-
...(data as [number, number, number, number]),
|
|
70
|
-
distanceIsNumber ? distance - LENGTH : undefined,
|
|
71
|
-
);
|
|
72
|
-
} else if (pathCommand === 'A') {
|
|
73
|
-
props = getArcSegmentProperties(
|
|
74
|
-
...(data as [number, number, number, number, number, number, number, number, number]),
|
|
75
|
-
distanceIsNumber ? distance - LENGTH : undefined,
|
|
76
|
-
);
|
|
77
|
-
} else if (pathCommand === 'C') {
|
|
78
|
-
props = getCubicSegmentProperties(
|
|
79
|
-
...(data as [number, number, number, number, number, number, number, number]),
|
|
80
|
-
distanceIsNumber ? distance - LENGTH : undefined,
|
|
81
|
-
);
|
|
82
|
-
} else if (pathCommand === 'Q') {
|
|
83
|
-
props = getQuadSegmentProperties(
|
|
84
|
-
...(data as [number, number, number, number, number, number]),
|
|
85
|
-
distanceIsNumber ? distance - LENGTH : undefined,
|
|
86
|
-
);
|
|
87
|
-
} else if (pathCommand === 'Z') {
|
|
88
|
-
data = [x, y, mx, my];
|
|
89
|
-
props = getLineSegmentProperties(
|
|
90
|
-
...(data as [number, number, number, number]),
|
|
91
|
-
distanceIsNumber ? distance - LENGTH : undefined,
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
if (distanceIsNumber && LENGTH < distance && LENGTH + props.length >= distance) {
|
|
96
|
-
POINT = props.point;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
MIN.push(props.bbox.min);
|
|
100
|
-
MAX.push(props.bbox.max);
|
|
101
|
-
LENGTH += props.length;
|
|
102
|
-
|
|
103
|
-
[x, y] = pathCommand !== 'Z' ? (seg.slice(-2) as [number, number]) : [mx, my];
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// native `getPointAtLength` behavior when the given distance
|
|
107
|
-
// is higher than total length
|
|
108
|
-
if (distanceIsNumber && distance > LENGTH - DISTANCE_EPSILON) {
|
|
109
|
-
POINT = { x, y };
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return {
|
|
113
|
-
point: POINT,
|
|
114
|
-
length: LENGTH,
|
|
115
|
-
get bbox() {
|
|
116
|
-
return {
|
|
117
|
-
min: {
|
|
118
|
-
x: Math.min(...MIN.map(n => n.x)),
|
|
119
|
-
y: Math.min(...MIN.map(n => n.y)),
|
|
120
|
-
},
|
|
121
|
-
max: {
|
|
122
|
-
x: Math.max(...MAX.map(n => n.x)),
|
|
123
|
-
y: Math.max(...MAX.map(n => n.y)),
|
|
124
|
-
},
|
|
125
|
-
};
|
|
126
|
-
},
|
|
127
|
-
};
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
export default pathFactory;
|