Math Helpers
Naive frame-loop interpolation (lerp) produces variable animation speeds across differing refresh rates (60Hz vs 120Hz vs 240Hz). Motion math utilities provide pure, allocation-free, frame-rate-independent exponential damping and spatial intersection primitives.
The math module provides three pure mathematical building blocks optimized for animation runtime execution:
- damp(current, target, k, dt): Frame-rate independent exponential approach.
- clamp01(value): Bounds values to [0, 1] while normalizing negative zero.
- rayRectIntersect(x, y, vx, vy, rect): Slab-method predictive raycasting.
The functions contain zero internal state, perform zero memory allocations, and behave identically in browser main threads, web workers, and server runtimes.
◆dt-Aware Damping vs Fixed-Rate Lerp
Drag the tick rate slider. The naive lerp follower changes speed drastically because it interpolates by a fixed percentage per frame. The dt-aware damp follower maintains identical velocity.
Quick start
Import math helpers directly for use inside FrameConductor subscriptions or custom animation loops.
Always pass the live delta-time in seconds (dt) provided by the conductor callback.
Mathematical Foundations & Raycast Mechanics
Understanding exponential approach mathematics and the slab method ray-box intersection.
| Function | Mathematical Formula | Key Behavior |
|---|---|---|
| damp() | current + (target - current) * (1 - e^(-k*dt)) | Asymptotic approach; guarantees constant velocity regardless of FPS. |
| clamp01() | v <= 0 ? 0 : v > 1 ? 1 : v | Normalizes negative zero (-0) to positive zero (+0) to prevent shader glitches. |
| rayRectIntersect() | Slab method 2D raycasting | Returns exact arrival time in seconds, or null if ray misses. |
- • Point inside rect: Returns 0 immediately.
- • Heading toward rect: Returns positive seconds until boundary entry.
- • Heading away or trajectory misses: Returns null.
- • Zero velocity on one axis: Returns null if coordinate is outside that axis span.
API Reference
Syntax
Pure utility functions for frame-rate-independent physics and spatial calculations.
Parameters
| Parameters.field | Type | Default | Description |
|---|---|---|---|
| current / target | number | (none) | Initial numeric position and target destination. |
| k | number | (none) | Responsiveness rate per second (typical range 4 to 20). |
| dt | number | (none) | Delta-time elapsed in seconds since the previous frame. |
Return Value
Calculated numeric position, clamped value, or arrival time in seconds.
Exported Function Signatures
| Exported Function Signatures.field | Signature | Returns | Description |
|---|---|---|---|
| damp(current: number, target: number, k: number, dt: number) | number | Calculates next position along exponential approach curve. | |
| clamp01(v: number) | number | Clamps value to range [0, 1] with negative zero normalization. | |
| rayRectIntersect(x: number, y: number, vx: number, vy: number, rect: RectLike) | number | null | Returns seconds until ray intersects rect, or null on miss. |
Pure Functional Execution
Motion math utilities are pure functions without side-effects or persistent memory handles.
Lifecycle & Invariant Guarantees
- →Frame-rate independence: damp() guarantees mathematically identical position trajectories at 30Hz, 60Hz, 120Hz, and 240Hz.
- →Zero memory allocations: Constructed with primitive numbers and stack variables to eliminate garbage collection pressure.
- →Negative zero normalization: clamp01() normalizes -0 to +0 to prevent stringification artefacts in CSS transforms and WebGL uniforms.
- →Precise predictive intersection: rayRectIntersect() calculates exact slab-method boundary crossings in seconds.
◆Production Examples
Battle-tested production patterns ready to copy directly into your codebase.
Follow mouse cursor smoothly across both X and Y axes.
When NOT to use this
Rules & Gotchas
- →Pass live delta-time from conductor: Always pass the dt parameter provided by the FrameConductor callback. Passing a fixed constant turns damp into a basic lerp.
- →Treat k as a responsiveness factor per second: Higher k values tighten tracking toward the target; tune k by feel typically within the 4 to 20 range.
- →Damp underlying numeric values rather than DOM reads: Interpolate JavaScript state variables and write to DOM styles; reading values back from the DOM introduces rounding error.
- →Supply velocities in pixels per second: rayRectIntersect expects velocity in px/s and returns arrival time in seconds. Velocities from SensorBus match this directly.