Animation
Babulus treats animation as a deterministic function of frame. Every component renders from a single input:
render(frame: number) -> visual outputNo 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):
fadefade_upfade_downslide_leftslide_rightpopscale_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();