@vectorvesper/motionCore Engine · Pure Math Utilities

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

DAMP (dt-AWARE) NAIVE LERP TARGET
Demo loads on scroll

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.

FunctionMathematical FormulaKey Behavior
damp()current + (target - current) * (1 - e^(-k*dt))Asymptotic approach; guarantees constant velocity regardless of FPS.
clamp01()v <= 0 ? 0 : v > 1 ? 1 : vNormalizes negative zero (-0) to positive zero (+0) to prevent shader glitches.
rayRectIntersect()Slab method 2D raycastingReturns exact arrival time in seconds, or null if ray misses.
rayRectIntersect Collision Cases
  • 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.fieldTypeDefaultDescription
current / targetnumber(none)Initial numeric position and target destination.
knumber(none)Responsiveness rate per second (typical range 4 to 20).
dtnumber(none)Delta-time elapsed in seconds since the previous frame.

Return Value

number | null

Calculated numeric position, clamped value, or arrival time in seconds.

Exported Function Signatures

Exported Function Signatures.fieldSignatureReturnsDescription
damp(current: number, target: number, k: number, dt: number)numberCalculates next position along exponential approach curve.
clamp01(v: number)numberClamps value to range [0, 1] with negative zero normalization.
rayRectIntersect(x: number, y: number, vx: number, vy: number, rect: RectLike)number | nullReturns 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.

1. Zero Teardown RequiredStateless Execution
2. Worker & Server SafeUniversal Execution

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

Animations that must reach an exact completion deadline (e.g. 300ms modal open).
→ instead Use CSS transitions or tweened animations. damp() approaches asymptotically and never reaches 100% mathematically.
Physical spring simulations requiring bounce and overshoot.
→ instead Use a dedicated second-order spring solver. Exponential damping cannot overshoot.
Predicting final position after a fixed acceleration trajectory.
→ instead Use standard kinematic equations (v^2 / 2a). rayRectIntersect determines ray-box entry time only.

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.

Related Motion Components