Anime.js v4
Anime.js (animejs, v4.x) is a lightweight JavaScript animation engine for CSS properties, transforms, SVG, DOM attributes, and plain JS objects. v4 is a full API rewrite — there is no default anime() function anymore; everything is a named import.
import { animate, createTimeline, createTimer, stagger, onScroll, utils, svg, text } from 'animejs';
Docs: https://animejs.com/documentation — installed API truth lives in node_modules/animejs/dist/.
Core: animate()
animate('.square', {
x: '17rem', // transform shorthand (x, y, rotate, scale, skew…)
rotate: { from: -180, to: 0 }, // per-property from/to
scale: [ { to: 1.25, duration: 200 }, { to: 1, duration: 300 } ], // keyframes
opacity: 0.5,
duration: 800,
delay: stagger(100), // stagger across targets
ease: 'outElastic(1, .5)', // NOTE: 'ease', not 'easing'; no 'ease' prefix in names
loop: 3, alternate: true, // v3 direction:'alternate' → alternate: true
onComplete: (anim) => {}, // callbacks are onBegin/onUpdate/onComplete/onLoop
});
- Targets: CSS selector, element, NodeList, array, or plain object (
animate(obj, { prop: 100, onUpdate: ... })).
- Playback controls on the returned animation:
.play() .pause() .restart() .reverse() .seek(ms) .then() (awaitable).
- Eases are strings:
'out', 'inOutQuad', 'outElastic(amplitude, period)', 'cubicBezier(...)', linear(), steps(n), irregular(), or createSpring({ stiffness, damping }) passed as the ease value (physics-based, ignores duration).
Timelines
const tl = createTimeline({ defaults: { duration: 500 }, loop: true });
tl.add('.a', { x: 100 })
.add('.b', { y: 50 }, '-=200') // position: absolute ms, '-=x'/'+=x', or labels
.label('mid')
.add('.c', { rotate: 360 }, 'mid')
.sync(otherAnimationOrTimeline); // v3 nested anime instances → .sync()
Scroll, draggable, scope
animate('.el', { x: 200, autoplay: onScroll({ container: '.scroll', enter: 'bottom top', leave: 'top bottom', sync: true }) });
createDraggable('.el', { container: '.area', snap: 100 });
For React/Vue/SSR, wrap in a scope tied to a root ref — required for cleanup and media queries:
useEffect(() => {
const scope = createScope({ root }).add(() => { animate('.logo', { rotate: 360 }); });
return () => scope.revert();
}, []);
SVG and text
animate(svg.createDrawable('path'), { draw: '0 1' }); // line drawing
animate('#shape', { points: svg.morphTo('#shape2') }); // morph
animate('.el', svg.createMotionPath('path')); // follow a path
const { chars, words, lines } = text.split('h1', { chars: true });
animate(chars, { y: [16, 0], opacity: [0, 1], delay: stagger(30) });
Performance picks
waapi.animate(...) — same syntax, hardware-accelerated Web Animations API; prefer for simple transform/opacity animations.
createAnimatable('.el', { x: 200 }) — for values driven every frame (cursor followers); far cheaper than re-triggering animate().
createTimer({ duration, onUpdate }) — clock without targets (replaces empty-target anime() hacks).
utils (grab-bag, all importable via utils.)
utils.get(target, prop, unit) reads current values, utils.set(targets, props) sets instantly, utils.remove(targets) stops animations, plus random, randomPick, shuffle, clamp, round, snap, wrap, mapRange, lerp, damp, degToRad/radToDeg, padStart/padEnd, roundPad, sync, keepTime, createSeededRandom. Chainable: utils.clamp(0, 100).round(2) returns a composed function.
v3 → v4 migration (the usual breakages)
| v3 |
v4 |
anime({ targets: '.el', ... }) |
animate('.el', { ... }) |
easing: 'easeOutQuad' |
ease: 'outQuad' |
direction: 'reverse' / 'alternate' |
reversed: true / alternate: true |
loop: true + alternate requires even loops |
loop counts iterations independently |
anime.timeline() |
createTimeline() |
anime.stagger(100) |
stagger(100) (named import) |
complete: fn, update: fn |
onComplete: fn, onUpdate: fn |
anime.random(a, b) |
utils.random(a, b) |
anime.set() / anime.get() |
utils.set() / utils.get() |
anime.remove() |
utils.remove() |
value like '+=100' string only |
{ from: x }, { to: x }, relative '+=100' all supported |
Full API surface (every export, grouped by module): references/api.md.
1---2name: animejs3description: This skill should be used when the user asks to "animate with anime.js", "use animejs", "add an animation" with timelines/staggers/springs, "animate on scroll", "make this draggable", "animate SVG" (draw lines, morph paths, motion paths), "split text and animate it", or when working in a project that imports from "animejs". Covers the v4 API (animate, createTimeline, stagger, onScroll, createScope) and v3→v4 migration.4---56# Anime.js v478Anime.js (`animejs`, v4.x) is a lightweight JavaScript animation engine for CSS properties, transforms, SVG, DOM attributes, and plain JS objects. **v4 is a full API rewrite** — there is no default `anime()` function anymore; everything is a named import.910```js11import { animate, createTimeline, createTimer, stagger, onScroll, utils, svg, text } from 'animejs';12```1314Docs: https://animejs.com/documentation — installed API truth lives in `node_modules/animejs/dist/`.1516## Core: animate()1718```js19animate('.square', {20 x: '17rem', // transform shorthand (x, y, rotate, scale, skew…)21 rotate: { from: -180, to: 0 }, // per-property from/to22 scale: [ { to: 1.25, duration: 200 }, { to: 1, duration: 300 } ], // keyframes23 opacity: 0.5,24 duration: 800,25 delay: stagger(100), // stagger across targets26 ease: 'outElastic(1, .5)', // NOTE: 'ease', not 'easing'; no 'ease' prefix in names27 loop: 3, alternate: true, // v3 direction:'alternate' → alternate: true28 onComplete: (anim) => {}, // callbacks are onBegin/onUpdate/onComplete/onLoop29});30```3132- Targets: CSS selector, element, NodeList, array, or plain object (`animate(obj, { prop: 100, onUpdate: ... })`).33- Playback controls on the returned animation: `.play() .pause() .restart() .reverse() .seek(ms) .then()` (awaitable).34- Eases are strings: `'out'`, `'inOutQuad'`, `'outElastic(amplitude, period)'`, `'cubicBezier(...)'`, `linear()`, `steps(n)`, `irregular()`, or `createSpring({ stiffness, damping })` passed as the `ease` value (physics-based, ignores duration).3536## Timelines3738```js39const tl = createTimeline({ defaults: { duration: 500 }, loop: true });40tl.add('.a', { x: 100 })41 .add('.b', { y: 50 }, '-=200') // position: absolute ms, '-=x'/'+=x', or labels42 .label('mid')43 .add('.c', { rotate: 360 }, 'mid')44 .sync(otherAnimationOrTimeline); // v3 nested anime instances → .sync()45```4647## Scroll, draggable, scope4849```js50animate('.el', { x: 200, autoplay: onScroll({ container: '.scroll', enter: 'bottom top', leave: 'top bottom', sync: true }) });51createDraggable('.el', { container: '.area', snap: 100 });52```5354For React/Vue/SSR, wrap in a scope tied to a root ref — required for cleanup and media queries:5556```jsx57useEffect(() => {58 const scope = createScope({ root }).add(() => { animate('.logo', { rotate: 360 }); });59 return () => scope.revert();60}, []);61```6263## SVG and text6465```js66animate(svg.createDrawable('path'), { draw: '0 1' }); // line drawing67animate('#shape', { points: svg.morphTo('#shape2') }); // morph68animate('.el', svg.createMotionPath('path')); // follow a path69const { chars, words, lines } = text.split('h1', { chars: true });70animate(chars, { y: [16, 0], opacity: [0, 1], delay: stagger(30) });71```7273## Performance picks7475- `waapi.animate(...)` — same syntax, hardware-accelerated Web Animations API; prefer for simple transform/opacity animations.76- `createAnimatable('.el', { x: 200 })` — for values driven every frame (cursor followers); far cheaper than re-triggering `animate()`.77- `createTimer({ duration, onUpdate })` — clock without targets (replaces empty-target `anime()` hacks).7879## utils (grab-bag, all importable via `utils.`)8081`utils.get(target, prop, unit)` reads current values, `utils.set(targets, props)` sets instantly, `utils.remove(targets)` stops animations, plus `random`, `randomPick`, `shuffle`, `clamp`, `round`, `snap`, `wrap`, `mapRange`, `lerp`, `damp`, `degToRad`/`radToDeg`, `padStart`/`padEnd`, `roundPad`, `sync`, `keepTime`, `createSeededRandom`. Chainable: `utils.clamp(0, 100).round(2)` returns a composed function.8283## v3 → v4 migration (the usual breakages)8485| v3 | v4 |86|---|---|87| `anime({ targets: '.el', ... })` | `animate('.el', { ... })` |88| `easing: 'easeOutQuad'` | `ease: 'outQuad'` |89| `direction: 'reverse' / 'alternate'` | `reversed: true` / `alternate: true` |90| `loop: true` + `alternate` requires even loops | `loop` counts iterations independently |91| `anime.timeline()` | `createTimeline()` |92| `anime.stagger(100)` | `stagger(100)` (named import) |93| `complete: fn, update: fn` | `onComplete: fn, onUpdate: fn` |94| `anime.random(a, b)` | `utils.random(a, b)` |95| `anime.set()` / `anime.get()` | `utils.set()` / `utils.get()` |96| `anime.remove()` | `utils.remove()` |97| value like `'+=100'` string only | `{ from: x }`, `{ to: x }`, relative `'+=100'` all supported |9899Full API surface (every export, grouped by module): **`references/api.md`**.