/* Damped springs for values that retarget mid-flight, keeping their velocity, as a dragged or redirected lens does. A spring is an angular frequency (rad/s) and a damping ratio; the caller steps them in fixed substeps, which keeps stiff springs stable when frames drop. */ export type SpringConfig = { omega: number; zeta: number }; export type Spring = { value: number; velocity: number }; /** The substep, in seconds. */ export const STEP = 1 / 240; // iOS's measurements are in points of a 54 pt lens; glass converts them by its // own thickness. export const LENS_PT = 54; // Pressed, glass swells on a bouncy spring, and springs back on release... export const SWELL: SpringConfig = { omega: 17.6, zeta: 0.59 }; // ...to this much longer, and as much wider in proportion. export const SWELL_PT = 14.6; export function spring(value = 0): Spring { return { value, velocity: 0 }; } export function stepSpring(spring: Spring, target: number, { omega, zeta }: SpringConfig, dt: number) { spring.velocity += (omega * omega * (target - spring.value) - 2 * zeta * omega * spring.velocity) * dt; spring.value += spring.velocity * dt; }