Skip to content

Commit a7d6372

Browse files
committed
cleanup
1 parent d7b6a2d commit a7d6372

29 files changed

+77
-70
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ A modern set of Typescript tools for manipulating the `d` (description) attribut
1616

1717

1818
While you may find familiar tools inside, this library brings ***new additions***:
19-
* the build in `getBBox`, `getPointAtLength` and `getTotalLength` are more reliable and much more accurate than the native methods, not to mention their world class performance ratings;
19+
* the build in `getBBox`, `getPointAtLength` and `getTotalLength` are more reliable and much more accurate than the native methods, not to mention their high [performance](https://github.com/thednp/svg-path-commander/issues/44) ratings;
2020
* thanks to the community contributions we've implemented useful tools like `getPropertiesAtLength`, `getSegmentOfPoint` or `isPointInStroke`;
2121
* a tool that can *reverse path draw direction* without altering path commands, even with specific shorthand path commands;
2222
* a unique tool that can *reverse path draw direction* for path strings with only 'C' path commands;
2323
* a new and unique tool to *apply transform functions to path commands* via the modern *DOMMatrix* API.
2424

2525
**The key differences with other libraries**:
26-
* Typescript sourced with modernized codebase and build tools; all inherited codebase has been modernized as well;
26+
* Typescript sourced with modernized codebase, all inherited codebase has been modernized as well;
2727
* along with the modern codebase, the library also comes with strong TypeScript definitions;
2828
* this library can create 3D to 2D projections, making your SVGs look like 3D but in the SVG coordinate system;
2929
* you can use this library in both web apps and Node.js, you are not restricted to a single environment;

dist/svg-path-commander.cjs

+1-1
Large diffs are not rendered by default.

dist/svg-path-commander.cjs.map

+1-1
Large diffs are not rendered by default.

dist/svg-path-commander.d.ts

+6-8
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,10 @@ export type Point = {
364364
x: number;
365365
y: number;
366366
};
367+
export type PointTuple = [
368+
number,
369+
number
370+
];
367371
/**
368372
* Creates a new SVGPathCommander instance with the following properties:
369373
* * segments: `pathArray`
@@ -407,14 +411,8 @@ declare class SVGPathCommander {
407411
x: number;
408412
y: number;
409413
}) => PointProperties;
410-
static polygonLength: (polygon: [
411-
number,
412-
number
413-
][]) => number;
414-
static polygonArea: (polygon: [
415-
number,
416-
number
417-
][]) => number;
414+
static polygonLength: (polygon: PointTuple[]) => number;
415+
static polygonArea: (polygon: PointTuple[]) => number;
418416
static getClosestPoint: (pathInput: string | PathArray, point: {
419417
x: number;
420418
y: number;

dist/svg-path-commander.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/svg-path-commander.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/svg-path-commander.mjs

+13-13
Original file line numberDiff line numberDiff line change
@@ -983,21 +983,21 @@ e.every(([t]) => t === t.toUpperCase()), H = (e) => {
983983
cy: 0,
984984
cz: 0
985985
};
986-
const t = yt(e), {
987-
min: { x: n, y: s },
988-
max: { x: r, y: i }
989-
} = t.bbox, o = r - n, c = i - s;
986+
const {
987+
min: { x: t, y: n },
988+
max: { x: s, y: r }
989+
} = yt(e).bbox, i = s - t, o = r - n;
990990
return {
991-
width: o,
992-
height: c,
993-
x: n,
994-
y: s,
995-
x2: r,
996-
y2: i,
997-
cx: n + o / 2,
998-
cy: s + c / 2,
991+
width: i,
992+
height: o,
993+
x: t,
994+
y: n,
995+
x2: s,
996+
y2: r,
997+
cx: t + i / 2,
998+
cy: n + o / 2,
999999
// an estimted guess
1000-
cz: Math.max(o, c) + Math.min(o, c) / 2
1000+
cz: Math.max(i, o) + Math.min(i, o) / 2
10011001
};
10021002
}, vt = (e, t, n) => {
10031003
if (e[n].length > 7) {

dist/svg-path-commander.mjs.map

+1-1
Large diffs are not rendered by default.

docs/svg-path-commander.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/svg-path-commander.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/convert/pathToAbsolute.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import type {
1313
SSegment,
1414
CSegment,
1515
MSegment,
16+
PointTuple,
1617
} from '../types';
1718

1819
/**
@@ -85,9 +86,7 @@ const pathToAbsolute = (pathInput: string | PathArray): AbsoluteArray => {
8586
} else if (absCommand === 'V') {
8687
[, y] = absoluteSegment as VSegment;
8788
} else {
88-
// x = absoluteSegment[segLength - 2];
89-
// y = absoluteSegment[segLength - 1];
90-
[x, y] = absoluteSegment.slice(-2) as [number, number];
89+
[x, y] = absoluteSegment.slice(-2) as PointTuple;
9190

9291
if (absCommand === 'M') {
9392
mx = x;

src/index.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { PathArray, TransformObjectValues } from './types';
1+
'use strict';
2+
import { PointTuple, PathArray, TransformObjectValues } from './types';
23
import type { Options, TransformEntries, TransformObject } from './interface';
34
export * from './types';
45
export * from './interface';
@@ -311,7 +312,7 @@ class SVGPathCommander {
311312
for (const [k, v] of Object.entries(source) as TransformEntries) {
312313
// istanbul ignore else @preserve
313314
if (k === 'skew' && Array.isArray(v)) {
314-
transform[k] = v.map(Number) as [number, number];
315+
transform[k] = v.map(Number) as PointTuple;
315316
} else if ((k === 'rotate' || k === 'translate' || k === 'origin' || k === 'scale') && Array.isArray(v)) {
316317
transform[k] = v.map(Number) as [number, number, number];
317318
} else if (k !== 'origin' && typeof Number(v) === 'number') transform[k] = Number(v);

src/math/bezier.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { type Point } from '../types';
1+
import type { PointTuple, Point } from '../types';
22

33
/**
44
* Tools from bezier.js by Mike 'Pomax' Kamermans
@@ -198,12 +198,12 @@ export const minmaxQ = (A: [number, number, number]) => {
198198
/* istanbul ignore else @preserve */
199199
if (A[1] >= A[0] ? A[2] >= A[1] : A[2] <= A[1]) {
200200
// if no extremum in ]0,1[
201-
return [min, max] as [number, number];
201+
return [min, max] as PointTuple;
202202
}
203203

204204
// check if the extremum E is min or max
205205
const E = (A[0] * A[2] - A[1] * A[1]) / (A[0] - 2 * A[1] + A[2]);
206-
return (E < min ? [E, max] : [min, E]) as [number, number];
206+
return (E < min ? [E, max] : [min, E]) as PointTuple;
207207
};
208208

209209
/**
@@ -219,7 +219,7 @@ export const minmaxC = (A: [number, number, number, number]) => {
219219
if (Math.abs(K) < CBEZIER_MINMAX_EPSILON) {
220220
if (A[0] === A[3] && A[0] === A[1]) {
221221
// no curve, point targeting same location
222-
return [A[0], A[3]] as [number, number];
222+
return [A[0], A[3]] as PointTuple;
223223
}
224224

225225
return minmaxQ([A[0], -0.5 * A[0] + 1.5 * A[1], A[0] - 3 * A[1] + 3 * A[2]]);
@@ -230,7 +230,7 @@ export const minmaxC = (A: [number, number, number, number]) => {
230230

231231
// if the polynomial is monotone in [0,1]
232232
if (T <= 0) {
233-
return [Math.min(A[0], A[3]), Math.max(A[0], A[3])] as [number, number];
233+
return [Math.min(A[0], A[3]), Math.max(A[0], A[3])] as PointTuple;
234234
}
235235
const S = Math.sqrt(T);
236236

@@ -257,5 +257,5 @@ export const minmaxC = (A: [number, number, number, number]) => {
257257
}
258258
}
259259

260-
return [min, max] as [number, number];
260+
return [min, max] as PointTuple;
261261
};

src/math/distanceSquareRoot.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { type PointTuple } from '../types';
2+
13
/**
24
* Returns the square root of the distance
35
* between two given points.
@@ -6,7 +8,7 @@
68
* @param b the second point coordinates
79
* @returns the distance value
810
*/
9-
const distanceSquareRoot = (a: [number, number], b: [number, number]): number => {
11+
const distanceSquareRoot = (a: PointTuple, b: PointTuple): number => {
1012
return Math.sqrt((a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]));
1113
};
1214

src/math/lineTools.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ import distanceSquareRoot from './distanceSquareRoot';
1414
const getSegmentProperties = (x1: number, y1: number, x2: number, y2: number, distance?: number) => {
1515
const { min, max } = Math;
1616
let point = { x: 0, y: 0 };
17-
const length = () => distanceSquareRoot([x1, y1], [x2, y2]);
17+
const getLength = () => distanceSquareRoot([x1, y1], [x2, y2]);
1818

1919
/* istanbul ignore else @preserve */
2020
if (typeof distance === 'number') {
21-
const currentLength = length();
21+
const currentLength = getLength();
2222
if (distance <= 0) {
2323
point = { x: x1, y: y1 };
2424
} else if (distance >= currentLength) {
@@ -32,7 +32,7 @@ const getSegmentProperties = (x1: number, y1: number, x2: number, y2: number, di
3232
return {
3333
point,
3434
get length() {
35-
return length();
35+
return getLength();
3636
},
3737
get bbox() {
3838
return {

src/math/midPoint.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { PointTuple } from '../types';
2+
13
/**
24
* Returns the coordinates of a specified distance
35
* ratio between two points.
@@ -7,7 +9,7 @@
79
* @param t the ratio
810
* @returns the midpoint coordinates
911
*/
10-
const midPoint = (a: [number, number], b: [number, number], t: number): [number, number] => {
12+
const midPoint = (a: PointTuple, b: PointTuple, t: number): PointTuple => {
1113
const [ax, ay] = a;
1214
const [bx, by] = b;
1315
return [ax + (bx - ax) * t, ay + (by - ay) * t];

src/math/polygonArea.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { type PointTuple } from '../types';
2+
13
/**
24
* d3-polygon-area
35
* https://github.com/d3/d3-polygon
@@ -7,7 +9,7 @@
79
* @param polygon an array of coordinates
810
* @returns the polygon area
911
*/
10-
const polygonArea = (polygon: [number, number][]): number => {
12+
const polygonArea = (polygon: PointTuple[]): number => {
1113
const n = polygon.length;
1214
let i = -1;
1315
let a;

src/math/polygonLength.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { type PointTuple } from '../types';
12
import distanceSquareRoot from './distanceSquareRoot';
23

34
/**
@@ -9,7 +10,7 @@ import distanceSquareRoot from './distanceSquareRoot';
910
* @param polygon an array of coordinates
1011
* @returns {number} the polygon length
1112
*/
12-
const polygonLength = (polygon: [number, number][]): number => {
13+
const polygonLength = (polygon: PointTuple[]): number => {
1314
return polygon.reduce((length, point, i) => {
1415
if (i) {
1516
return length + distanceSquareRoot(polygon[i - 1], point);

src/process/normalizeSegment.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { ParserParams } from '../interface';
2-
import type { NormalSegment, PathSegment } from '../types';
2+
import type { NormalSegment, PointTuple, PathSegment } from '../types';
33

44
/**
55
* Normalizes a single segment of a `pathArray` object.
@@ -35,9 +35,9 @@ const normalizeSegment = (segment: PathSegment, params: ParserParams): NormalSeg
3535
const qy = py1 * 2 - (params.qy ? params.qy : /* istanbul ignore next */ 0);
3636
params.qx = qx;
3737
params.qy = qy;
38-
result = ['Q', qx, qy, ...(values as [number, number])];
38+
result = ['Q', qx, qy, ...(values as PointTuple)];
3939
} else if (pathCommand === 'Q') {
40-
const [nqx, nqy] = values as [number, number];
40+
const [nqx, nqy] = values as PointTuple;
4141
params.qx = nqx;
4242
params.qy = nqy;
4343
}

src/process/projection2d.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import CSSMatrix from '@thednp/dommatrix';
2+
import { type PointTuple } from '../types';
23

34
/**
45
* Transforms a specified point using a matrix, returning a new
@@ -34,7 +35,7 @@ const translatePoint = (cssm: CSSMatrix, v: [number, number, number, number]): [
3435
* @param origin the [x,y,z] transform origin
3536
* @returns the projected [x,y] coordinates
3637
*/
37-
const projection2d = (m: CSSMatrix, point2D: [number, number], origin: [number, number, number]): [number, number] => {
38+
const projection2d = (m: CSSMatrix, point2D: PointTuple, origin: [number, number, number]): PointTuple => {
3839
const [originX, originY, originZ] = origin;
3940
const [x, y, z] = translatePoint(m, [...point2D, 0, 1]);
4041

src/process/reversePath.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import type {
99
SSegment,
1010
TSegment,
1111
VSegment,
12-
} from 'src/types';
12+
} from '../types';
1313
import pathToAbsolute from '../convert/pathToAbsolute';
1414
import normalizePath from './normalizePath';
1515

src/process/roundPath.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { PathArray } from 'src/types';
1+
import type { PathArray } from '../types';
22
import defaultOptions from '../options/options';
33

44
/**

src/process/shortenSegment.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ParserParams } from 'src/interface';
1+
import type { ParserParams } from '../interface';
22
import type {
33
AbsoluteSegment,
44
HSegment,

src/process/splitCubic.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import midPoint from '../math/midPoint';
2-
import type { CubicSegment } from '../types';
2+
import type { CubicSegment, PointTuple } from '../types';
33

44
/**
55
* Split a cubic-bezier segment into two.
@@ -9,10 +9,10 @@ import type { CubicSegment } from '../types';
99
*/
1010
const splitCubic = (pts: number[] /* , ratio */): [CubicSegment, CubicSegment] => {
1111
const t = /* ratio || */ 0.5;
12-
const p0 = pts.slice(0, 2) as [number, number];
13-
const p1 = pts.slice(2, 4) as [number, number];
14-
const p2 = pts.slice(4, 6) as [number, number];
15-
const p3 = pts.slice(6, 8) as [number, number];
12+
const p0 = pts.slice(0, 2) as PointTuple;
13+
const p1 = pts.slice(2, 4) as PointTuple;
14+
const p2 = pts.slice(4, 6) as PointTuple;
15+
const p3 = pts.slice(6, 8) as PointTuple;
1616
const p4 = midPoint(p0, p1, t);
1717
const p5 = midPoint(p1, p2, t);
1818
const p6 = midPoint(p2, p3, t);

src/types.ts

+2
Original file line numberDiff line numberDiff line change
@@ -196,3 +196,5 @@ export type Point = {
196196
x: number;
197197
y: number;
198198
};
199+
200+
export type PointTuple = [number, number];

src/util/getPathArea.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import pathToCurve from '../convert/pathToCurve';
2-
import type { PathArray } from '../types';
2+
import type { PointTuple, PathArray } from '../types';
33

44
/**
55
* Returns the area of a single cubic-bezier segment.
@@ -61,7 +61,7 @@ const getPathArea = (path: PathArray) => {
6161
return 0;
6262
default:
6363
len = getCubicSegArea(x, y, ...(seg.slice(1) as [number, number, number, number, number, number]));
64-
[x, y] = seg.slice(-2) as [number, number];
64+
[x, y] = seg.slice(-2) as PointTuple;
6565
return len;
6666
}
6767
})

src/util/getPathBBox.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { PathBBox } from 'src/interface';
2-
import { PathArray } from 'src/types';
1+
import { PathBBox } from '../interface';
2+
import { PathArray } from '../types';
33
import pathFactory from './pathFactory';
44

55
/**
@@ -23,11 +23,10 @@ const getPathBBox = (path: PathArray | string): PathBBox => {
2323
};
2424
}
2525

26-
const props = pathFactory(path);
2726
const {
2827
min: { x: xMin, y: yMin },
2928
max: { x: xMax, y: yMax },
30-
} = props.bbox;
29+
} = pathFactory(path).bbox;
3130

3231
const width = xMax - xMin;
3332
const height = yMax - yMin;

src/util/getPropertiesAtLength.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { PathArray, PathSegment } from '../types';
1+
import type { PointTuple, PathArray, PathSegment } from '../types';
22
import type { SegmentProperties } from '../interface';
33
import parsePathString from '../parser/parsePathString';
44
import getTotalLength from './getTotalLength';
@@ -20,7 +20,7 @@ const getPropertiesAtLength = (pathInput: string | PathArray, distance?: number)
2020
let lengthAtSegment = 0;
2121
let length = 0;
2222
let segment = pathArray[0] as PathSegment;
23-
const [x, y] = segment.slice(-2) as [number, number];
23+
const [x, y] = segment.slice(-2) as PointTuple;
2424
const point = { x, y };
2525

2626
// If the path is empty, return 0.

src/util/pathFactory.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { MSegment, PathArray, PathSegment, Point } from '../types';
1+
import type { MSegment, PathArray, PathSegment, Point, PointTuple } from '../types';
22
// import type { LengthFactory } from '../interface';
33
import normalizePath from '../process/normalizePath';
44
import getLineSegmentProperties from '../math/lineTools';
@@ -100,7 +100,7 @@ const pathFactory = (pathInput: string | PathArray, distance?: number) => {
100100
MAX.push(props.bbox.max);
101101
LENGTH += props.length;
102102

103-
[x, y] = pathCommand !== 'Z' ? (seg.slice(-2) as [number, number]) : [mx, my];
103+
[x, y] = pathCommand !== 'Z' ? (seg.slice(-2) as PointTuple) : [mx, my];
104104
}
105105

106106
// native `getPointAtLength` behavior when the given distance

0 commit comments

Comments
 (0)