Documentation Index Fetch the complete documentation index at: https://mintlify.com/juliangarnier/anime/llms.txt
Use this file to discover all available pages before exploring further.
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 ]
});
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 });
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%' ,
})
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
});
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 ]
});
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 ]
});
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!
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 ();
});
Use composition: 'replace' for better scroll performance
Limit the number of animated elements
Use will-change: transform on animated elements
Avoid animating properties that trigger layout (width, height, etc.)
Keep smooth value low (0.05-0.15) for responsive feel
Next Steps
Timelines Master timeline sequencing
Text Animations Add scroll-triggered text effects