Animation
@onda-engine/react provides two ways to drive values from the frame: interpolate (map a frame through input/output ranges) and spring (natural, physics-based motion). Both are pure functions, so renders are reproducible.
interpolate
Section titled “interpolate”Maps input from inputRange to outputRange. Mirrors Remotion’s API.
function interpolate( input: number, inputRange: readonly number[], outputRange: readonly number[], options?: InterpolateOptions,): number
interface InterpolateOptions { easing?: EasingFn extrapolateLeft?: 'clamp' | 'extend' // default 'clamp' extrapolateRight?: 'clamp' | 'extend' // default 'clamp'}inputRangeandoutputRangemust be the same length (≥ 2) and ascending — otherwise it throws.- Out-of-range inputs clamp by default; pass
'extend'to extrapolate.
const opacity = interpolate(frame, [0, 30], [0, 1]) // fade in over 30 framesconst x = interpolate(frame, [0, 15, 30], [0, 100, 0]) // multi-segmentconst y = interpolate(frame, [0, 15], [150, 110], { easing: Easing.easeOutCubic })Easing
Section titled “Easing”Built-in easing presets (any (t: number) => number works too). These match onda-animation’s curves.
const Easing: { linear, easeInQuad, easeOutQuad, easeInOutQuad, easeInCubic, easeOutCubic, easeInOutCubic, smoothStep, easeInBack, easeOutBack,}
type EasingFn = (t: number) => numberinterpolate(frame, [0, 20], [0, 1], { easing: Easing.easeInOutCubic })cubicBezier
Section titled “cubicBezier”A CSS-style cubic-Bézier ease with control points (x1,y1), (x2,y2) and fixed endpoints (0,0)–(1,1). Returns an EasingFn. Matches onda-animation’s CubicBezier.
function cubicBezier(x1: number, y1: number, x2: number, y2: number): EasingFnconst ease = cubicBezier(0.25, 0.1, 0.25, 1) // "ease"const v = interpolate(frame, [0, 30], [0, 1], { easing: ease })spring
Section titled “spring”A deterministic, frame-keyed spring (a damped harmonic oscillator pulled from 0 toward 1, integrated at a fixed 1/fps step). A pure function of frame, so renders are reproducible. Underdamped configs overshoot.
interface SpringConfig { mass?: number // default 1 stiffness?: number // default 100 damping?: number // default 10}
interface SpringOptions { frame: number // e.g. from useCurrentFrame() fps: number // composition frame rate from?: number // default 0 to?: number // default 1 config?: SpringConfig}
function spring(options: SpringOptions): numberimport { spring, useCurrentFrame, useVideoConfig } from 'onda-engine/react'
function Pop() { const frame = useCurrentFrame() const { fps } = useVideoConfig() const scale = spring({ frame, fps, config: { stiffness: 120, damping: 12 } }) return <Rect scaleX={scale} scaleY={scale} width={100} height={100} fill="#3b82f6" />}Pass from / to to settle between arbitrary values:
const y = spring({ frame, fps, from: 200, to: 0 }) // slide up into placerandom
Section titled “random”random(seed: number | string): number — a deterministic value in [0, 1). Compositions must render identically every time (same frame → same pixels), so reach for this instead of Math.random().
import { random } from 'onda-engine/react'const jitter = random(`dot-${i}`) * 10 - 5 // stable per i, every rendernoise2D / noise3D
Section titled “noise2D / noise3D”Smooth, coherent value noise in [-1, 1] — seeded and deterministic — for organic motion (drift, wobble, jitter). Scale the inputs to set the frequency; animate a coordinate over frame for movement.
import { noise2D } from 'onda-engine/react'const y = baseY + noise2D('drift', frame * 0.05, 0) * 20- The
interpolateeasings andspringintegration mirror the Rustonda-animationruntime, so React-authored motion and a Rust-side timeline produce matching curves. - These drive opacity, translate, scale, and rotation (rotation is honored by the GPU backend). Skew, color, and path morphing aren’t available yet.