Animation

Canonical docs now live at videoml.org/docs/stdlib.

Babulus treats animation as a deterministic function of frame. Every component renders from a single input:

render(frame: number) -> visual output

No global timers. No CSS keyframes. No independent loops. This keeps previews and renders perfectly synchronized across all animation engines.


Why frame-driven matters

  • Deterministic previews: scrub any frame and see the exact output.
  • Deterministic renders: the same input always yields the same output.
  • Cross-engine synchronization: layout, data viz, generative art, and 3D all share the same timeline.

Unified engine integration

Babulus integrates multiple animation engines behind a consistent frame contract. You can mix and match these components in the same scene:

  • Framer Motion for layout and orchestration
  • D3 for animated data visualization
  • Processing / p5.js for generative art & special effects
  • Three.js for spatial 3D scenes
  • Anime.js for low-level motion on DOM targets (frame-driven via seek)
  • Lottie (After Effects) for motion graphic assets
  • Text Effects for named-effect kinetic typography (built on Anime.js)

Base classes

Each engine is wrapped by a frame-driven base class in the Babulus standard library. Extend these classes and you inherit:

  • Frame synchronization
  • Deterministic rendering
  • Automatic sizing to video dimensions
class MySketch extends P5SketchBase {
  drawFrame(p5, frame, fps, size) {
    // draw based on frame
  }
}

View code (demo reel)
<scene id="reel" ...>
  <!-- Framer / D3 / p5 / Three / Lottie / Text / Anime / Mix -->
</scene>

Framer Motion (Layout + Motion Graphics)

Frame-driven motion using Framer Motion components and Babulus frame helpers.

View code (framer)
layer.framerMotionDemo({
  size: 240,
  accent: 'var(--color-accent)'
});

D3 (Data Visualization)

Frame-synchronized chart transitions without time-based D3 transitions.

View code (d3)
layer.d3BarChart({
  valuesA: [4, 7, 5, 8, 6],
  valuesB: [6, 3, 9, 4, 7]
});

Processing / p5.js (Generative Art)

Procedural visuals driven by frame, not time.

View code (p5)
layer.processingSketch({
  particleCount: 28
});

Three.js (3D Scenes)

Frame-driven 3D rendering with deterministic camera + object motion.

View code (three)
layer.threeOrbit({
  cubeSize: 160
});

Lottie (After Effects)

After Effects animations rendered frame-by-frame in sync with the timeline.

View code (lottie)
layer.lottieBadge({
  size: 280
});

Text Effects (Named effects)

A high-level vocabulary for text animation: named effects, units (chars/words/lines), and deterministic timing.

View code (text effects)
layer.component('text', 'TextEffectsDemo', {});

Text Effects Cookbook

Curated effects (stable names with predictable motion):

  • fade
  • fade_up
  • fade_down
  • slide_left
  • slide_right
  • pop
  • scale_in

If a cue is present, the default start is { kind: "cue" } (no manual frame math required).

View code (title effect)
layer.title({
  text: "Frame-driven titles",
  textEffect: {
    effect: "fade_up",
    unit: "words",
    durationFrames: 24,
    staggerFrames: 4,
    start: { kind: "cue" }
  }
});

See Components for more text effect examples with Title + Subtitle.

Anime.js (Low-level harness)

Full control over DOM-target animation while staying frame-driven via seek().

View code (anime)
layer.component('anime', 'AnimeHarnessDemo', {});

Mix-and-match scenes

Use multiple engines in the same scene. Because everything is frame-driven, all layers stay perfectly synchronized.

View code (mix + match)
layer.mixAndMatchDemo();