Imperative Timeline
Overview
Section titled “Overview”The Timeline class lets you build animation sequences imperatively instead of with JSX. This is useful for dynamic or data-driven animations where the structure isn’t known at author time.
Constructor
Section titled “Constructor”const tl = new Timeline(fps);| Parameter | Type | Description |
|---|---|---|
fps | number | Frames per second for the timeline |
Methods
Section titled “Methods”| Method | Signature | Description |
|---|---|---|
play | play(type, id, opts?) | Add an animation and advance the cursor past it |
add | add(type, id, opts?) | Add an animation at the current cursor without advancing |
wait | wait(seconds) | Insert a pause (in seconds) at the current cursor |
compile | compile() | Returns { actions, totalFrames } |
play— appends an animation sequentially. The cursor moves forward by its duration, so the next call starts after it finishes.add— layers an animation at the current cursor position (parallel). The cursor does not move.wait— advances the cursor by the given number of seconds (converted to frames using the timeline’s fps).compile— finalizes the timeline and returns the list of actions with their computed start frames, plus the total frame count.
Code Example
Section titled “Code Example”import { Player, useCurrentFrame, interpolate, Circle } from '@elucim/core';
function AnimatedCircle() { const frame = useCurrentFrame(); const x = interpolate(frame, [0, 60], [100, 400], { easing: 'easeInOutCubic' }); return <Circle cx={x} cy={125} r={30} fill="#6c5ce7" />;}
<Player width={500} height={250} fps={30} durationInFrames={90}> <AnimatedCircle /></Player>// The imperative timeline using useCurrentFrame and interpolate// is a React-only feature. For DSL-based animations, use the// declarative animation properties (fadeIn, draw, transform, etc.){ "width": 500, "height": 250, "fps": 30, "durationInFrames": 90, "children": [ { "type": "circle", "cx": 250, "cy": 125, "r": 30, "fill": "#6c5ce7", "transform": { "fromTranslateX": -150, "toTranslateX": 150, "easing": "easeInOutCubic" } } ]}Example
Section titled “Example”import { Timeline } from 'elucim';
const tl = new Timeline(30);
tl.play('fadeIn', 'title', { duration: 30 });tl.wait(0.5);tl.play('draw', 'axis', { duration: 45 });tl.add('fadeIn', 'label-x', { duration: 20 });tl.add('fadeIn', 'label-y', { duration: 20 });tl.wait(1);tl.play('fadeOut', 'title', { duration: 30 });
const { actions, totalFrames } = tl.compile();// actions: ordered list with { type, id, startFrame, opts }// totalFrames: total length of the compiled timelineIn this example, label-x and label-y fade in concurrently (both added with add), while the rest of the sequence plays one step at a time.