@@ -8,7 +8,7 @@ export function lerp(a: number, b: number, t: number) {
|
||||
|
||||
export function animate(
|
||||
duration: number,
|
||||
callback: (progress: number) => void | false,
|
||||
callback: (progress: number) => void | false
|
||||
) {
|
||||
const start = performance.now();
|
||||
const loop = (time: number) => {
|
||||
@@ -33,41 +33,37 @@ export function createNodePath({
|
||||
cornerBottom = 0,
|
||||
leftBump = false,
|
||||
rightBump = false,
|
||||
aspectRatio = 1,
|
||||
aspectRatio = 1
|
||||
} = {}) {
|
||||
return `M0,${cornerTop}
|
||||
${
|
||||
cornerTop
|
||||
? ` V${cornerTop}
|
||||
${cornerTop
|
||||
? ` V${cornerTop}
|
||||
Q0,0 ${cornerTop * aspectRatio},0
|
||||
H${100 - cornerTop * aspectRatio}
|
||||
Q100,0 100,${cornerTop}
|
||||
`
|
||||
: ` V0
|
||||
: ` V0
|
||||
H100
|
||||
`
|
||||
}
|
||||
}
|
||||
V${y - height / 2}
|
||||
${
|
||||
rightBump
|
||||
? ` C${100 - depth},${y - height / 2} ${100 - depth},${y + height / 2} 100,${y + height / 2}`
|
||||
: ` H100`
|
||||
}
|
||||
${
|
||||
cornerBottom
|
||||
? ` V${100 - cornerBottom}
|
||||
${rightBump
|
||||
? ` C${100 - depth},${y - height / 2} ${100 - depth},${y + height / 2} 100,${y + height / 2}`
|
||||
: ` H100`
|
||||
}
|
||||
${cornerBottom
|
||||
? ` V${100 - cornerBottom}
|
||||
Q100,100 ${100 - cornerBottom * aspectRatio},100
|
||||
H${cornerBottom * aspectRatio}
|
||||
Q0,100 0,${100 - cornerBottom}
|
||||
`
|
||||
: `${leftBump ? `V100 H0` : `V100`}`
|
||||
}
|
||||
${
|
||||
leftBump
|
||||
? ` V${y + height / 2} C${depth},${y + height / 2} ${depth},${y - height / 2} 0,${y - height / 2}`
|
||||
: ` H0`
|
||||
}
|
||||
Z`.replace(/\s+/g, " ");
|
||||
: `${leftBump ? `V100 H0` : `V100`}`
|
||||
}
|
||||
${leftBump
|
||||
? ` V${y + height / 2} C${depth},${y + height / 2} ${depth},${y - height / 2} 0,${y - height / 2}`
|
||||
: ` H0`
|
||||
}
|
||||
Z`.replace(/\s+/g, ' ');
|
||||
}
|
||||
|
||||
export const debounce = (fn: Function, ms = 300) => {
|
||||
@@ -78,14 +74,13 @@ export const debounce = (fn: Function, ms = 300) => {
|
||||
};
|
||||
};
|
||||
|
||||
export const clone: <T>(v: T) => T =
|
||||
"structedClone" in globalThis
|
||||
? globalThis.structuredClone
|
||||
: (obj) => JSON.parse(JSON.stringify(obj));
|
||||
export const clone: <T>(v: T) => T = 'structedClone' in globalThis
|
||||
? globalThis.structuredClone
|
||||
: (obj) => JSON.parse(JSON.stringify(obj));
|
||||
|
||||
export function withSubComponents<A, B extends Record<string, any>>(
|
||||
component: A,
|
||||
subcomponents: B,
|
||||
subcomponents: B
|
||||
): A & B {
|
||||
Object.keys(subcomponents).forEach((key) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@@ -93,3 +88,27 @@ export function withSubComponents<A, B extends Record<string, any>>(
|
||||
});
|
||||
return component as A & B;
|
||||
}
|
||||
|
||||
export function distanceFromPointToSegment(
|
||||
x1: number,
|
||||
y1: number,
|
||||
x2: number,
|
||||
y2: number,
|
||||
x0: number,
|
||||
y0: number
|
||||
): number {
|
||||
const dx = x2 - x1;
|
||||
const dy = y2 - y1;
|
||||
|
||||
if (dx === 0 && dy === 0) {
|
||||
return Math.hypot(x0 - x1, y0 - y1);
|
||||
}
|
||||
|
||||
const t = ((x0 - x1) * dx + (y0 - y1) * dy) / (dx * dx + dy * dy);
|
||||
const clampedT = Math.max(0, Math.min(1, t));
|
||||
|
||||
const px = x1 + clampedT * dx;
|
||||
const py = y1 + clampedT * dy;
|
||||
|
||||
return Math.hypot(x0 - px, y0 - py);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user