|
@@ -1,43 +1,52 @@
|
|
|
type PointType = { x: number; y: number };
|
|
|
|
|
|
type LineFunc = (
|
|
|
- (pointA: PointType, pointB: PointType) => { length: number; angle: number}
|
|
|
-);
|
|
|
+ pointA: PointType,
|
|
|
+ pointB: PointType
|
|
|
+) => { length: number; angle: number };
|
|
|
|
|
|
type ControlPointClosure = (
|
|
|
- (current: PointType, previous: PointType, next: PointType, reverse?: boolean) => number[]
|
|
|
-);
|
|
|
+ current: PointType,
|
|
|
+ previous: PointType,
|
|
|
+ next: PointType,
|
|
|
+ reverse?: boolean
|
|
|
+) => number[];
|
|
|
|
|
|
type ControlPointFunc = (
|
|
|
- (lineCale: LineFunc, smooth: number) => ControlPointClosure
|
|
|
-);
|
|
|
+ lineCale: LineFunc,
|
|
|
+ smooth: number
|
|
|
+) => ControlPointClosure;
|
|
|
|
|
|
type BezierCommandClosure = (
|
|
|
- (point: PointType, i: number, a: PointType[]) => string
|
|
|
-);
|
|
|
+ point: PointType,
|
|
|
+ i: number,
|
|
|
+ a: PointType[]
|
|
|
+) => string;
|
|
|
|
|
|
type BezierCommandFunc = (
|
|
|
- (controlPoint: ControlPointClosure) => BezierCommandClosure
|
|
|
-);
|
|
|
+ controlPoint: ControlPointClosure
|
|
|
+) => BezierCommandClosure;
|
|
|
|
|
|
type SvgPathFunc = (
|
|
|
- (points: PointType[], command: BezierCommandClosure) => string
|
|
|
-);
|
|
|
+ points: PointType[],
|
|
|
+ command: BezierCommandClosure
|
|
|
+) => string;
|
|
|
|
|
|
export const line: LineFunc = (pointA, pointB) => {
|
|
|
const lengthX = pointB.x - pointA.x;
|
|
|
const lengthY = pointB.y - pointA.y;
|
|
|
|
|
|
return {
|
|
|
- length: Math.sqrt((lengthX ** 2) + (lengthY ** 2)),
|
|
|
+ length: Math.sqrt(lengthX ** 2 + lengthY ** 2),
|
|
|
angle: Math.atan2(lengthY, lengthX),
|
|
|
};
|
|
|
};
|
|
|
|
|
|
-export const controlPoint: ControlPointFunc = (
|
|
|
- lineCale, smooth,
|
|
|
-) => (
|
|
|
- current, previous, next, reverse,
|
|
|
+export const controlPoint: ControlPointFunc = (lineCale, smooth) => (
|
|
|
+ current,
|
|
|
+ previous,
|
|
|
+ next,
|
|
|
+ reverse
|
|
|
): number[] => {
|
|
|
// When 'current' is the first or last point of the array
|
|
|
// 'previous' or 'next' don't exist.
|
|
@@ -56,7 +65,11 @@ export const controlPoint: ControlPointFunc = (
|
|
|
return [x, y];
|
|
|
};
|
|
|
|
|
|
-export const bezierCommand: BezierCommandFunc = controlPointCalc => (point, i, a): string => {
|
|
|
+export const bezierCommand: BezierCommandFunc = controlPointCalc => (
|
|
|
+ point,
|
|
|
+ i,
|
|
|
+ a
|
|
|
+): string => {
|
|
|
// start control point
|
|
|
const [cpsX, cpsY] = controlPointCalc(a[i - 1], a[i - 2], point);
|
|
|
// end control point
|
|
@@ -67,12 +80,9 @@ export const bezierCommand: BezierCommandFunc = controlPointCalc => (point, i, a
|
|
|
|
|
|
export const svgPath: SvgPathFunc = (points, command) => {
|
|
|
const d = points.reduce(
|
|
|
- (acc, point, i, a) => (i === 0 ? (
|
|
|
- `M ${point.x},${point.y}`
|
|
|
- ) : (
|
|
|
- `${acc} ${command(point, i, a)}`
|
|
|
- )),
|
|
|
- '',
|
|
|
+ (acc, point, i, a) =>
|
|
|
+ i === 0 ? `M ${point.x},${point.y}` : `${acc} ${command(point, i, a)}`,
|
|
|
+ ''
|
|
|
);
|
|
|
return d;
|
|
|
};
|