Introduction
Stew Engine is the animation engine behind Stew Factory. It reads an animation as plain JSON and plays it on SVG, right in the browser.
What it does
You describe what moves as data: a clip, with a track for each thing that moves and keyframes on each track. Stew Engine reads that once, then draws every frame on your SVG, writing only what changed.
The scene below is playing on Stew Engine. The JSON under it is the exact object it plays.
{
"duration": 2.4,
"pivots": {
"hopper": { "x": 144, "y": 214 },
"star": { "x": 330, "y": 150 }
},
"tracks": [
{
"targetUid": "hopper",
"property": "y",
"keyframes": [
{ "time": 0, "value": 0, "easing": "power2.out" },
{ "time": 0.45, "value": -72, "easing": "power2.in" },
{ "time": 0.9, "value": 0 },
{ "time": 1.2, "value": 0, "easing": "power2.out" },
{ "time": 1.65, "value": -72, "easing": "power2.in" },
{ "time": 2.1, "value": 0 }
]
},
{
"targetUid": "hopper",
"property": "scaleY",
"keyframes": [
{ "time": 0.9, "value": 1, "easing": "power2.out" },
{ "time": 0.98, "value": 0.78, "easing": "power2.inOut" },
{ "time": 1.14, "value": 1 },
{ "time": 2.1, "value": 1, "easing": "power2.out" },
{ "time": 2.18, "value": 0.78, "easing": "power2.inOut" },
{ "time": 2.34, "value": 1 }
]
},
{
"targetUid": "star",
"property": "rotate",
"keyframes": [
{ "time": 0, "value": 0, "easing": "back.inOut(1.4)" },
{ "time": 1.2, "value": 144, "easing": "back.inOut(1.4)" },
{ "time": 2.4, "value": 288 }
]
},
{
"targetUid": "line",
"property": "draw",
"keyframes": [
{ "time": 0.2, "value": 0, "easing": "power2.inOut" },
{ "time": 1.3, "value": 1 }
]
},
{
"targetUid": "line",
"property": "opacity",
"keyframes": [
{ "time": 1.9, "value": 1, "easing": "power1.in" },
{ "time": 2.3, "value": 0 }
]
}
]
}How it fits together
Three calls take a clip from data to motion. One more puts everything back.
compile(doc)- Reads the clip into a Program: flat lists of numbers, worked out once, before anything plays.
svgDrawer(program, bind)- Draws a moment on the SVG.
bindsays which elements each target is written to. createPlayer(program, drawer)- Plays it: play, pause, reverse, seek, glide, speed and repeat, on the page's frame clock.
player.destroy()- Stops, and puts the artwork back exactly as it was before the first frame.
What's inside
The engine is a few small parts, each with one job. It imports nothing: no packages, no app code.
format- The input: Stew animation data, the same JSON Stew Factory saves.
compile- The data into a program of number lists, once.
eval- A program and a moment into a pose. Pure math, no page access.
apply- The pose onto the SVG, and the stage several players share.
path- Path data into curves and back, and distances along a path.
clock- Where time comes from: the page's frame loop, or a clock you step yourself.
player- Ties them together.
start- What starts a clip (load, click, hover, in view, scroll) and rules that play it on an event.
interact- The pointer's actions: follow, run away and drag, on a shape or a single node.
Where it runs today
Everything that moves in Stew Factory plays on Stew Engine: the editor, share pages, video export and every animated download.
The whole engine is about 23 KB compressed. A clip with no pointer actions or rules needs about 17 KB of it.
There is no public package to install yet. These docs show how it works, and every demo on them runs on it.