anime-js
Anime.js animation patterns for web interfaces including timelines, staggering, and motion design.
Installation
Follow the repository instructions for this skill and your agent. Review the files and dependencies before adding it to your workflow.
View source ↗GuidesSkill instructions
Anime.js Animation Patterns
High-performance animations for web interfaces using Anime.js.
Core Concepts
| Concept | Description |
|---|---|
| Targets | CSS selectors, DOM elements, or JS objects |
| Properties | CSS, SVG, DOM, or object properties to animate |
| Timeline | Sequence and coordinate multiple animations |
| Staggering | Cascade animations across multiple targets |
| Easing | Control animation timing curves |
Basic Animation
import anime from 'animejs'
// Simple animation
anime({
targets: '.element',
translateX: 250,
opacity: [0, 1],
duration: 1000,
easing: 'easeOutExpo'
})
CSS Properties
anime({
targets: '.box',
translateX: 250,
translateY: 50,
rotate: '1turn',
scale: 1.5,
opacity: 0.5,
backgroundColor: '#FFF',
borderRadius: ['0%', '50%'],
duration: 2000
})
SVG Animations
// Line drawing
anime({
targets: 'path',
strokeDashoffset: [anime.setDashoffset, 0],
easing: 'easeInOutSine',
duration: 1500,
delay: (el, i) => i * 250
})
// Morph path
anime({
targets: 'path',
d: [
{ value: 'M0 0 L100 0 L100 100 L0 100 Z' },
{ value: 'M50 0 L100 50 L50 100 L0 50 Z' }
],
easing: 'easeInOutQuad',
duration: 2000
})
Timeline
const tl = anime.timeline({
easing: 'easeOutExpo',
duration: 750
})
tl
.add({ targets: '.header', translateY: [-100, 0], opacity: [0, 1] })
.add({ targets: '.content', translateX: [-100, 0], opacity: [0, 1] }, '-=500')
.add({ targets: '.footer', translateY: [100, 0], opacity: [0, 1] }, '-=500')
Staggering
// Basic stagger
anime({
targets: '.grid-item',
translateY: [100, 0],
opacity: [0, 1],
delay: anime.stagger(100)
})
// Grid stagger
anime({
targets: '.grid-item',
scale: [0, 1],
delay: anime.stagger(50, { grid: [7, 5], from: 'center' })
})
// Stagger with easing
anime({
targets: '.item',
translateX: 350,
delay: anime.stagger(100, { easing: 'easeOutQuad' })
})
Easing Functions
| Category | Functions |
|---|---|
| Built-in | linear, easeInQuad, easeOutExpo, etc. |
| Spring | spring(mass, stiffness, damping, velocity) |
| Steps | steps(5) |
| Custom | cubicBezier(0.5, 0, 0.5, 1) |
anime({
targets: '.element',
translateX: 250,
easing: 'spring(1, 80, 10, 0)'
})
Keyframes
anime({
targets: '.element',
keyframes: [
{ translateY: -40 },
{ translateX: 250 },
{ translateY: 40 },
{ translateX: 0 },
{ translateY: 0 }
],
duration: 4000,
easing: 'easeOutElastic(1, .8)'
})
Callbacks
anime({
targets: '.element',
translateX: 250,
begin: (anim) => console.log('Started'),
update: (anim) => console.log(`Progress: ${anim.progress}%`),
complete: (anim) => console.log('Completed'),
loopBegin: (anim) => console.log('Loop started'),
loopComplete: (anim) => console.log('Loop completed'),
changeBegin: (anim) => console.log('Change began'),
changeComplete: (anim) => console.log('Change completed')
})
Controls
const animation = anime({
targets: '.element',
translateX: 250,
autoplay: false
})
animation.play()
animation.pause()
animation.restart()
animation.reverse()
animation.seek(1000) // Seek to 1000ms
React Integration
import { useEffect, useRef } from 'react'
import anime from 'animejs'
function AnimatedComponent() {
const elementRef = useRef<HTMLDivElement>(null)
useEffect(() => {
if (elementRef.current) {
anime({
targets: elementRef.current,
translateX: 250,
opacity: [0, 1],
duration: 1000
})
}
}, [])
return <div ref={elementRef}>Animated</div>
}
Common Patterns
Page Load Animation
anime.timeline()
.add({ targets: '.logo', scale: [0, 1], duration: 600 })
.add({ targets: '.nav-item', translateY: [-20, 0], opacity: [0, 1], delay: anime.stagger(100) }, '-=400')
.add({ targets: '.hero', translateY: [50, 0], opacity: [0, 1] }, '-=200')
Hover Effect
element.addEventListener('mouseenter', () => {
anime({ targets: element, scale: 1.1, duration: 300 })
})
element.addEventListener('mouseleave', () => {
anime({ targets: element, scale: 1, duration: 300 })
})
Scroll Reveal
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
anime({
targets: entry.target,
translateY: [50, 0],
opacity: [0, 1],
duration: 800
})
observer.unobserve(entry.target)
}
})
})
document.querySelectorAll('.reveal').forEach(el => observer.observe(el))
Performance Tips
- Prefer transform and opacity (GPU accelerated)
- Avoid animating layout properties (width, height, top, left)
- Use
will-changesparingly for complex animations - Batch animations with timeline
- Clean up animations on component unmount
Examples
Read the usage examples in the source repository.
View source ↗Source history
- Indexed on
- 2026-01-20
- Index updated
- 2026-03-03
- Branch
- main
Index and sync dates describe this directory. View the source repository for code history.
GitHub ↗chat Comments (0)
Sign in to join the discussion and leave a comment.
No comments yet. Be the first to share your thoughts!