Timeline
Sequence everything visually. Per-property, per-bone, per-formula.
The animation timeline is where keyframes, easing curves, and playback controls come together. Each node gets its own horizontal track. Each property gets its own keyframe sequence.
Layout
Split panel: node list on the left, timeline canvas on the right.
Timeline: Walk───────────────────────────────────────────── Legs ◆━━━━━━━━◆━━━━━━━━◆ (0-2s, loop) Hands ◆━━━━━━━━━━━━◆━━━━━━━━━━━━◆ (0-3s, loop) Body ◆━━━━━━━━━━━━━━━━━━◆━━━━━━━━━━━━━━━━━━◆ (0-5s, loop) | | | | 0s 1s 2s 3s
Nodes listed vertically. Keyframe diamonds on horizontal tracks. Easing curves visible between consecutive keyframes. Current frame indicator as a vertical line.
Per-property keyframes
Keyframes are per-property, not per-node. Animate X without touching Y. Animate color without touching scale. Only properties with keyframes are interpolated — everything else passes through unchanged.
Node "Ball"├── x: ◆──────────────◆ (moves from 100 to 300)├── y: ◆─────◆─────◆ (bounces: 200 → 50 → 200)├── rotation: ◆──────────────◆ (spins 360)└── opacity: (no keyframes — stays at current value)
Each property can have its own easing function. Rotation eases in-out while position is linear — within the same node, the same time range.
Per-bone timelines
Each node has an independent timeline with its own loop length. No shared duration constraint.
Legs loop at 2 seconds. Hands loop at 3 seconds. Body breathes at 5 seconds. All within one animation clip called "Walk." The timelines advance independently, creating complex motion from simple individual loops.
title: "Independent loop lengths"
description: "Two shapes with different animation periods creating complex patterns"
nodes:
- type: ELLIPSE, name: "Orbit1", x: 200, y: 200, w: 20, h: 20, fill: "#E74C3C"
- type: ELLIPSE, name: "Orbit2", x: 200, y: 200, w: 16, h: 16, fill: "#3498DB"
formulas:
- node: "Orbit1", prop: "x", value: "200 + Math.cos(time * 2) * 80"
- node: "Orbit1", prop: "y", value: "200 + Math.sin(time * 2) * 80"
- node: "Orbit2", prop: "x", value: "200 + Math.cos(time * 3) * 60"
- node: "Orbit2", prop: "y", value: "200 + Math.sin(time * 3) * 60"
tools_visible: [select, play]
ui_visible: [properties, formulas]Keyframe editing
Add keyframes
Move to a frame. Change a property. A keyframe is created automatically at the current time with the new value.
Move keyframes
Drag diamonds left or right to retime. Drag a selection of keyframes to shift a range. Bars between keyframes are draggable to scale timing.
Easing curves
Each keyframe has an easing function controlling the transition into it. Visible as a curve between consecutive diamonds.
| Easing | Behavior |
|---|---|
| Linear | Constant speed |
| Ease-in | Slow start, fast end |
| Ease-out | Fast start, slow end |
| Ease-in-out | Slow both ends |
| Cubic bezier | Custom curve (2 control points) |
| Spring | Physics-based overshoot |
| Steps | Discrete jumps |
| Elastic | Bouncy overshoot |
| Bounce | Impact-style landing |
Per-property easing within the same keyframe — rotation bounces while position eases smoothly.
Formula keyframes
The unique part: keyframes can hold formulas, not just static values.
A keyframe at t=0 holds sin(time * 3) * 50 (procedural oscillation). A keyframe at t=2 holds mouse.x (reactive tracking). Between them, the system crossfades the formula outputs.
t=0: rotation = sin(time * 3) * 50 ← oscillating ─────────── crossfade ───────────t=2: rotation = mouse.x ← follows cursor
Classical tweening is the special case where every formula is a constant number.
Zoom and navigation
- Ctrl+Wheel — zoom timeline horizontally
- Middle mouse — pan
- Click frame header — jump to frame
- Drag current-frame line — scrub through time
Frame labels adapt to zoom level. At wide zoom, every frame shows a number. At tight zoom, only major frames (every 5th, 10th) get labels.
Playback controls
| Action | Control |
|---|---|
| Play/Pause | Space |
| Jump to start | Home |
| Jump to end | End |
| Step forward | Right arrow |
| Step backward | Left arrow |
| Set loop start | [ |
| Set loop end | ] |
| Toggle looping | L |
Integration with formulas
Animations and formulas coexist. Priority:
- Animation keyframe active — animation value wins
- Formula bound — formula evaluates
- Neither — static value
Formulas can reference time and frame to create procedural animation. Keyframes can hold formulas for sequenced procedural motion. The two systems compose — they don't fight.
State capture
Press Space to play:
- Current state of all nodes is captured (full snapshot)
- Animation timelines advance
- Formulas tick with
time,dt,frame - Physics simulation runs
Press Space again:
- Everything stops
- All nodes restore from the snapshot
- Changes during play are discarded
Non-destructive. Experiment freely. Nothing is lost.