Anime.js v4
Stand 2026-10: animejs 4.5.
npm i animejs
import { animate, createTimeline, stagger, svg, utils, createScope } from 'animejs'
v3 → v4 (alte Tutorials verwenden v3)
| v3 | v4 |
|---|---|
anime({ targets, ... }) | animate(targets, { ... }) |
easing: 'easeOutQuad' | ease: 'outQuad' ('inOutExpo', 'inOut(3)', ...) |
anime.timeline() | createTimeline() |
direction: 'alternate' | alternate: true |
update, complete, begin | onUpdate, onComplete, onBegin |
Dauern und Verzögerungen sind in Millisekunden (GSAP verwendet Sekunden).
animate
animate('.square', {
x: 320, // Kurzform für translateX
rotate: { from: -180 },
opacity: [0, 1], // [von, bis]
duration: 1250,
delay: stagger(65, { from: 'center' }),
ease: 'inOutQuint',
loop: true,
alternate: true,
})
Ziele: CSS-Selektor, Element(e) oder ein einfaches Objekt (animate(obj, { value: 100, onUpdate: () => draw(obj.value) })).
Timeline
const tl = createTimeline({ defaults: { duration: 600, ease: 'outExpo' } })
tl.add('.title', { opacity: [0, 1], y: [40, 0] })
.add('.sub', { opacity: [0, 1] }, '-=300') // 300 ms vor vorherigem Ende
.add('.dot', { scale: [0, 1], delay: stagger(80) }, '<<') // gleichzeitig mit vorherigem Start
Positionen: 100 absolute ms · '+=100' / '-=100' relativ zum vorherigen Ende · '<' vorheriges Ende · '<<' vorheriger Start · '<<+=250' · 'Label' (gesetzt mit tl.label('Label')) · stagger(10).
SVG
animate(svg.createDrawable('.line'), { draw: ['0 0', '0 1'], duration: 2000 }) // Strich-Zeichnen, Werte 0–1 "Start Ende"
animate('#shapeA', { d: svg.morphTo('#shapeB'), duration: 800 }) // Pfad A in B morphen
animate('.car', { ...svg.createMotionPath('#road'), duration: 4000 }) // einem Pfad folgen (x, y, rotate)
Wiedergabe / Scrubbing
autoplay: false, dann .play(), .pause(), .restart(), .reverse(), .seek(ms), .complete(), .cancel(), .revert() (macht alle Inline-Stile rückgängig).
React
const root = useRef(null)
useEffect(() => {
const scope = createScope({ root }).add(() => {
animate('.box', { x: 200 }) // Selektoren sind auf root beschränkt
})
return () => scope.revert()
}, [])
Für Video
Anime.js läuft mit eigener Uhr. Innerhalb von Remotion baue es pausiert und suche pro Frame — lasse es niemals automatisch abspielen:
const frame = useCurrentFrame()
const { fps } = useVideoConfig()
const tl = useRef(null)
useLayoutEffect(() => {
tl.current = createTimeline({ autoplay: false }).add('.title', { y: [40, 0], opacity: [0, 1] })
return () => tl.current.revert()
}, [])
useLayoutEffect(() => { tl.current.seek((frame / fps) * 1000) }, [frame, fps])
Bevorzuge Remotions eigene interpolate / spring für einfache Bewegungen; greife zu Anime.js, wenn seine SVG-Helfer (draw, morph, motion path) oder Stagger echte Arbeit sparen.