Animation primitives, live
A first-pass design system for motion. Each block is a primitive we can reuse: animate, sequence, stagger, spring, drag, split text, draw SVG, and sync to scroll.
Built against the v4 modules API from thevanilla JS quick startand thefull documentation. Import only what you need.
import { animate, utils, createDraggable, spring } from 'animejs';The official vanilla example: a looping scale bounce, a springy drag, and a click that accumulates rotation.
Pass an array of tween objects to sequence values on one target. Each step can own its own duration and ease.
animate('#kf-token', {
x: [
{ to: 80, duration: 400, ease: 'out(3)' },
{ to: -40, duration: 500, ease: 'inOut(2)' },
{ to: 0, duration: 450, ease: 'out(4)' },
],
rotate: [
{ to: 20, duration: 400 },
{ to: -12, duration: 500 },
{ to: 0, duration: 450 },
],
});stagger() offsets delay (or values) across a set of targets. Grid + from: 'center' is the classic ripple.
animate('.anime-dot', {
scale: [
{ to: 1.35, ease: 'inOut(3)', duration: 180 },
{ to: 1, ease: spring({ bounce: 0.45 }) },
],
delay: stagger(28, {
grid: [8, 5],
from: 'center',
}),
});Orchestrate several animations as one clock.'-=180' overlaps the next add by 180ms.
createTimeline({ defaults: { ease: 'out(3)' } })
.add('#tl-a', { width: '100%', duration: 450 })
.add('#tl-b', { width: '100%', duration: 450 }, '-=180')
.add('#tl-c', { width: '100%', duration: 450 }, '-=180');Built-in eases use the inOut(3) style intensity helpers. Springs are objects fromspring(), not CSS strings.
linearout(4)inOut(3)spring bounce .65animate() returns an instance.play, pause, restart, and reverse are the controls we will reuse for UI motion.
createDraggable adds pointer tracking and a spring release. The token is constrained to its stage. Flick it.
splitText wraps characters so they can be staggered. scrambleText is a function-based tween value, usually applied to innerHTML.
motion as a system
animate anything
createDrawable exposes a drawproperty: '0 0' hidden, '0 1'fully stroked. Pair with stagger for sequential line reveal.
animate(createDrawable('#svg-stage path'), {
draw: ['0 0', '0 1'],
ease: 'inOut(3)',
duration: 1600,
delay: stagger(180),
});Pass onScroll() as autoplay.sync: true ties progress to scroll position. The card below fades in when it enters the viewport.
Scroll the page — this bar maps to this block
This card uses enter/leave thresholds instead of synced progress. Useful for one-shot reveals.