Basic Scroll Animation
Sync a timeline with scroll position:import { createTimeline, onScroll } from 'animejs';
const tl = createTimeline({
defaults: {
duration: 1000,
ease: 'linear'
},
autoplay: onScroll({
target: '.scroll-container',
enter: 'top top', // When element top hits viewport top
leave: 'bottom bottom', // When element bottom hits viewport bottom
})
});
tl.add('.element', {
y: [100, 0],
opacity: [0, 1]
});
Scroll Configuration
Control scroll behavior with various options:import { createTimeline, onScroll } from 'animejs';
createTi meline({ autoplay: onScroll({
// Target element to track
target: '.sticky-container',
// Start trigger: when element enters viewport
enter: 'top top', // element_position viewport_position
// End trigger: when element leaves viewport
leave: 'bottom bottom',
// Sync point (0 to 1) - when timeline is at 50%
sync: 0.5,
// Smooth scrolling
smooth: 0.1, // 0 (instant) to 1 (very smooth)
// Debug mode - shows scroll markers
debug: true
}) })
.add('.element', { rotate: 360 });
Sticky Scroll Effect
Create a sticky element with scroll-driven animations:import { createTimeline, onScroll, stagger, utils } from 'animejs';
// Set initial positions
utils.set('.card', {
rotate: () => utils.random(-1, 1, 2),
rotateZ: () => utils.random(-1, 1, 2),
y: stagger(-0.5, { from: 'last' }),
z: stagger(1)
});
const tl = createTimeline({
defaults: {
ease: 'linear',
duration: 500,
composition: 'blend'
},
autoplay: onScroll({
target: '.sticky-container',
enter: 'top top',
leave: 'bottom bottom',
sync: 0.5
})
});
// Stack rotation
tl.add('.stack', {
rotateY: [-180, 0],
ease: 'in(2)'
}, 0);
// Card animations
tl.add('.card', {
rotate: 0,
rotateZ: {
to: stagger([0, -360], { from: 'last' }),
ease: 'inOut(2)'
},
y: { to: '-60%', duration: 400 },
transformOrigin: ['50% 100%', '50% 50%'],
delay: stagger(1, { from: 'first' })
}, 0);
Enter/Leave Positions
Understanding scroll triggers:// Format: 'element_position viewport_position'
// Element position:
// - 'top': top edge of element
// - 'center': center of element
// - 'bottom': bottom edge of element
// - '75%': 75% down the element
// Viewport position:
// - 'top': top edge of viewport
// - 'center': center of viewport
// - 'bottom': bottom edge of viewport
// - '25%': 25% down the viewport
onScroll({
enter: 'top bottom', // Start when top of element hits bottom of viewport
leave: 'bottom top', // End when bottom of element hits top of viewport
})
onScroll({
enter: 'center center', // Start when element center hits viewport center
leave: 'center center', // End at same point (short animation range)
})
onScroll({
enter: '25% 75%', // Custom percentages
leave: '75% 25%',
})
Scroll with Sync Point
Control when the timeline reaches a specific progress:import { createTimeline, onScroll } from 'animejs';
const tl = createTimeline({
autoplay: onScroll({
target: '.section',
enter: 'top bottom',
leave: 'bottom top',
sync: 0.5 // Timeline will be at 50% when element is centered
})
});
tl.add('.title', {
scale: [0.5, 1],
opacity: [0, 1],
duration: 1000
});
Multiple Scroll Sections
Create multiple independent scroll-linked timelines:import { createTimeline, onScroll } from 'animejs';
// Section 1
createTi meline({
autoplay: onScroll({
target: '.section-1',
enter: 'top bottom',
leave: 'center top'
})
})
.add('.section-1 .content', {
x: [-100, 0],
opacity: [0, 1]
});
// Section 2
createTi meline({
autoplay: onScroll({
target: '.section-2',
enter: 'top bottom',
leave: 'center top'
})
})
.add('.section-2 .content', {
y: [100, 0],
opacity: [0, 1]
});
// Section 3
createTi meline({
autoplay: onScroll({
target: '.section-3',
enter: 'top bottom',
leave: 'center top'
})
})
.add('.section-3 .content', {
scale: [0, 1],
rotate: [90, 0]
});
Scroll Scope
Control scroll animations within a specific container:import { onScroll, createTimeline } from 'animejs';
// Scroll within a container element
const tl = createTimeline({
autoplay: onScroll({
target: '.card',
container: '.scroll-container', // Custom scroll container
enter: 'top top',
leave: 'bottom bottom'
})
});
tl.add('.card-content', {
y: [50, -50],
opacity: [0, 1, 0]
});
Smooth Scrolling
Add smoothness to scroll-driven animations:import { createTimeline, onScroll } from 'animejs';
const tl = createTimeline({
autoplay: onScroll({
target: '.section',
enter: 'top bottom',
leave: 'bottom top',
smooth: 0.15 // Adds lag for smoother feel (0-1)
})
});
tl.add('.element', {
rotate: [0, 360],
scale: [1, 2, 1]
});
Parallax Effect
Create parallax scrolling:import { createTimeline, onScroll } from 'animejs';
const tl = createTimeline({
autoplay: onScroll({
target: '.parallax-section',
enter: 'top bottom',
leave: 'bottom top'
})
});
// Background moves slower
tl.add('.background', {
y: [0, -100],
duration: 1000
}, 0);
// Foreground moves faster
tl.add('.foreground', {
y: [0, -300],
duration: 1000
}, 0);
// Content at normal speed
tl.add('.content', {
y: [0, -200],
duration: 1000
}, 0);
Debug Mode
Visualize scroll triggers:import { createTimeline, onScroll } from 'animejs';
createTi meline({
autoplay: onScroll({
target: '.section',
enter: 'top bottom',
leave: 'bottom top',
debug: true // Shows visual markers for enter/leave points
})
})
.add('.element', { x: [0, 100] });
Enable debug mode during development to see exactly when your scroll triggers activate!
Responsive Scroll Scope
Adjust scroll behavior based on viewport:import { createTimeline, onScroll } from 'animejs';
function createScrollAnimation() {
const isMobile = window.innerWidth < 768;
return createTimeline({
autoplay: onScroll({
target: '.section',
enter: isMobile ? 'top bottom' : 'top center',
leave: isMobile ? 'bottom top' : 'bottom center',
sync: isMobile ? 0.3 : 0.5
})
})
.add('.content', {
scale: [0.8, 1],
opacity: [0, 1]
});
}
let scrollAnim = createScrollAnimation();
window.addEventListener('resize', () => {
scrollAnim = createScrollAnimation();
});
Performance Tips
- Use
composition: 'replace'for better scroll performance - Limit the number of animated elements
- Use
will-change: transformon animated elements - Avoid animating properties that trigger layout (width, height, etc.)
- Keep
smoothvalue low (0.05-0.15) for responsive feel
Next Steps
Timelines
Master timeline sequencing
Text Animations
Add scroll-triggered text effects