Animation, computed in columns.
A data-oriented animation engine for the web. Springs, tweens, keyframes and inertia, written to the DOM once per frame.
- Springs solved in closed form
- Velocity kept when you retarget
- One transform write per element per frame
- Under 128 bytes allocated per frame
- Compositor path for transforms and opacity
One engine. Every driver.
Every animated value is a row in a set of Float64Array columns. Springs, tweens, keyframes and inertia step in one loop over the rows that move.
01Write one call
Pass elements or a selector, the values to reach and how to get there. Transforms combine into one transform string per element.
import { animate, stagger } from "@animaly/dom"; animate(".card", { x: 120, opacity: 1 }, { type: "spring", stiffness: 300, damping: 20, }); animate(".dot", { scale: [1, 1.4, 1] }, { duration: 0.6, delay: stagger(0.05, { from: "center" }), });02Retarget mid-flight
Call animate again before the first spring settles. The new spring starts from the current position and keeps the current velocity.
animate(".box", { x: 400 }, { type: "spring" }); // Later, while it is still moving: // the new spring starts from the current // position and keeps the current velocity. animate(".box", { x: 0 }, { type: "spring" });Click the track, then click again before the ball settles.Velocity 0 px/s
See it in motion.
Every demo on this page runs on animaly, live in your browser.
Measured against motion.
motion 13.4.6's time divided by animaly's, headless Chromium, engines interleaved over 5 repetitions. Higher is better for animaly.
| Scenario | 1,000 elements | 10,000 elements |
|---|---|---|
| Main-thread time per frame, tween | 1.30x | 1.31x |
| Main-thread time per frame, spring | 1.41x | 1.35x |
| Script time per frame, tween | 2.3x | 2.7x |
| Script time per frame, spring | 2.5x | 3.2x |
| Starting all animations | 1.75x | 1.23x |
| Retargeting all animations | 3.0x | 3.3x |
One call in your code.
One write per frame.
Version 0.1 is on npm. The API can still change before 1.0.
pnpm add @animaly/dom