Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0138YqDj3ttfayRwuMKKrqVj
57 lines
1.8 KiB
TypeScript
57 lines
1.8 KiB
TypeScript
/** Easing and timing helpers shared by every motion template. All pure. */
|
|
|
|
export function clamp(value: number, min = 0, max = 1): number {
|
|
return Math.min(max, Math.max(min, value));
|
|
}
|
|
|
|
export function lerp(from: number, to: number, amount: number): number {
|
|
return from + (to - from) * amount;
|
|
}
|
|
|
|
/** Linear progress 0..1 of `t` through the window [start, end]. */
|
|
export function progress(t: number, start: number, end: number): number {
|
|
if (end <= start) return t >= end ? 1 : 0;
|
|
return clamp((t - start) / (end - start));
|
|
}
|
|
|
|
export function easeInCubic(x: number): number {
|
|
return x * x * x;
|
|
}
|
|
|
|
export function easeOutCubic(x: number): number {
|
|
return 1 - (1 - x) ** 3;
|
|
}
|
|
|
|
export function easeInOutCubic(x: number): number {
|
|
return x < 0.5 ? 4 * x * x * x : 1 - (-2 * x + 2) ** 3 / 2;
|
|
}
|
|
|
|
export function easeOutExpo(x: number): number {
|
|
return x >= 1 ? 1 : 1 - 2 ** (-10 * x);
|
|
}
|
|
|
|
/** Overshoots slightly before settling; for pop-in reveals. */
|
|
export function easeOutBack(x: number): number {
|
|
const c1 = 1.70158;
|
|
const c3 = c1 + 1;
|
|
return 1 + c3 * (x - 1) ** 3 + c1 * (x - 1) ** 2;
|
|
}
|
|
|
|
/**
|
|
* Opacity envelope for a clip of `durationMs`: fades in over `inMs` and out
|
|
* over the last `outMs`.
|
|
*/
|
|
export function fadeEnvelope(t: number, durationMs: number, inMs: number, outMs: number): number {
|
|
const fadeIn = inMs > 0 ? easeOutCubic(progress(t, 0, inMs)) : 1;
|
|
const fadeOut = outMs > 0 ? 1 - easeInCubic(progress(t, durationMs - outMs, durationMs)) : 1;
|
|
return clamp(Math.min(fadeIn, fadeOut));
|
|
}
|
|
|
|
/** Deterministic pseudo-random value in [0, 1) for integer seeds. */
|
|
export function hash01(a: number, b = 0): number {
|
|
let h = Math.imul(a ^ 0x9e3779b9, 0x85ebca6b) ^ Math.imul(b + 0x632be5ab, 0xc2b2ae35);
|
|
h = Math.imul(h ^ (h >>> 15), 0x2c1b3c6d);
|
|
h = Math.imul(h ^ (h >>> 12), 0x297a2d39);
|
|
return ((h ^ (h >>> 15)) >>> 0) / 4294967296;
|
|
}
|