Animation API
Reference for the AnimationBuilder you receive as aBuilder inside builder.animate((aBuilder) => ...).
The animation builder is a timeline compiler: you select targets, add tweens, and control the cursor. The output is a portable AnimationSpec.
Target selection
aBuilder.node(id)
Targets a node by id.
- Target form:
node:<id> - Returns:
AnimationBuilder(chainable)
aBuilder.edge(id) / aBuilder.edge(from, to, id?)
Targets an edge by id.
- Target form:
edge:<id>(commonlyedge:a->b) - Convenience:
aBuilder.edge('a', 'b')→aBuilder.edge('a->b') - Returns:
AnimationBuilder(chainable)
aBuilder.overlay(key)
Targets an overlay instance by key.
- Target form:
overlay:<key> - Returns:
AnimationBuilder(chainable)
Writing tweens
aBuilder.to(props, opts)
Adds tweens for the current target. One tween is emitted per numeric property in props.
Parameters:
| Param | Type | Description |
|---|---|---|
props | AnimatableProps | Target property values |
opts.duration | number | Duration in ms |
opts.easing | Ease | 'linear', 'easeIn', 'easeOut', 'easeInOut' |
opts.from | Record<string, number> | Explicit start values per property |
Time behavior:
- The tween starts at the current cursor position
- After
.to(...), the cursor advances byduration(sequential by default)
Throws if called without selecting a target first.
Animatable properties
| Target | Core properties |
|---|---|
| Node | x, y, opacity, scale, rotation |
| Edge | opacity, strokeDashoffset |
| Overlay | Any numeric param field |
Timeline control
aBuilder.wait(ms)
Advances the cursor by ms without adding tweens.
aBuilder.at(ms)
Sets the cursor to an absolute time offset. Use this to schedule parallel sequences:
builder.animate((aBuilder) => {
// Move A and B simultaneously
aBuilder.at(0).node('a');
aBuilder.to({ x: 320 }, { duration: 1200, easing: 'easeInOut' });
aBuilder.at(0).node('b');
aBuilder.to({ y: 150 }, { duration: 1200, easing: 'easeInOut' });
});
Custom properties
aBuilder.extendAdapter(callback)
Registers custom animatable properties for this animation spec:
builder.animate((aBuilder) => {
aBuilder.extendAdapter((register) => {
register('r', {
get: (el) => (el.shape.kind === 'circle' ? el.shape.r : 0),
set: (el, val) => {
if (el.shape.kind === 'circle') el.shape.r = val;
},
});
});
aBuilder.node('pulse').to({ r: 40 }, { duration: 500, from: { r: 20 } });
});
Per-element animation
Nodes and edges can define inline animations:
// Callback form
builder.node('a').animate((anim) => {
anim.to({ scale: 1.5, opacity: 0.5 }, { duration: 400, easing: 'easeOut' });
});
// Quick transition
builder.node('b').animateTo({ opacity: 0 }, { duration: 300, delay: 500 });
CSS / registry animations
For continuous effects, use named animations from the registry:
builder.edge('a', 'b').animate('flow'); // built-in
builder.edge('a', 'b').animate('pulse', { duration: '1.5s' }); // custom
Registering custom CSS animations
import { CoreAnimationRegistry } from 'vizcraft';
CoreAnimationRegistry.registerEdge('pulse', (edge, opts) => ({
keyframes: `@keyframes pulse-${edge.id} { 0%,100% { opacity: 1 } 50% { opacity: 0.3 } }`,
style: `animation: pulse-${edge.id} ${opts?.duration ?? '2s'} infinite;`,
}));
Playback
builder.play(container?, specs?) → PlaybackController
Starts playback of compiled animation specs.
PlaybackController
| Method | Description |
|---|---|
.play() | Resume playback |
.pause() | Pause playback |
.stop() | Stop and reset |
.seek(ms) | Jump to a specific time |
Mount with autoplay
builder.mount(container, { autoplay: true });
Output types
- AnimationSpec — the compiled timeline
- TweenSpec — individual tween unit
- AnimatableProps — property bag
- TweenOptions — tween configuration
- Ease — easing functions
- PlaybackController — playback control
Found a problem? Open an issue on GitHub.