React AnimeJS
Components/On Scroll8 / 25

On Scroll

Code

1const {
2 ref, containerRef, controls, state,
3 isReady, isInView, progress,
4} = useAnimeOnScroll({
5 enter: 'bottom top',
6 leave: 'top bottom',
7})
8
9const p = Math.max(0, Math.min(1, progress))
10const t = p * TOTAL // TOTAL = (slides.length - 1) * STEP + DELAY
11
12// Each slide rotates in/out as a rolodex card. First & last slides have
13// special-cased branches (no preceding/following card).
14function getRotationX(i: number): number {
15 const outStart = i * STEP + DELAY
16 const outEnd = outStart + DUR
17 const inStart = (i - 1) * STEP + DELAY
18 const inEnd = inStart + DUR
19
20 if (i === 0) {
21 if (t <= outStart) return 0
22 if (t >= outEnd) return 90
23 return ((t - outStart) / DUR) * 90
24 }
25 if (t <= inStart) return -90
26 if (t <= inEnd) return -90 + ((t - inStart) / DUR) * 90
27 if (t <= outStart) return 0
28 if (t >= outEnd) return 90
29 return ((t - outStart) / DUR) * 90
30}
31
32// ref → observed trigger element
33// containerRef → inner scroll container
34<div ref={containerRef} style={{ overflowY: 'auto' }}>
35 <div ref={ref} style={{
36 perspective: '800px',
37 position: 'sticky', top: 0,
38 }}>
39 {slides.map((slide, i) => (
40 <div key={i} style={{
41 transform: `rotateX(${getRotationX(i)}deg)`,
42 backfaceVisibility: 'hidden',
43 }}>
44 {slide.content}
45 </div>
46 ))}
47 </div>
48</div>

Scroll-linked animation with progress-derived transforms, dual ref pattern (observer + scroll container), and a scrubbed vertical rolodex demo.

Live previewOpen Playground
On ScrollInner scroller · Scrubbed vertical rolodex
Init…
Scroll inside the panel to scrub the rolodex
slide 1Anim
slide 2Timer
slide 3SVG
slide 4Scope
slide 5Drag
slide 6Text
Progress
0%
Scroll
0
Velocity
0.0
Dir
Fwd →
Props
NameTypeDefaultDescription
refRefObject<T>-Observed element ref (trigger)
containerRefRefObject<T>-Scroll container ref
controlsobject-Imperative animation controls
stateobject-Observer state: progress, scroll, velocity, backward, inView
isReadyboolean-True when observer is attached
isInViewboolean-True when trigger is inside viewport
progressnumber-0-1 scroll progress value
enterstring-Enter boundary (e.g. 'bottom top', 'min 80%')
leavestring-Leave boundary (e.g. 'top bottom', 'max 20%')
axis'x' | 'y''y'Scroll axis
linkedScrollLinkedTarget-Animation/timer/timeline to link
syncboolean-Sync animation to scroll
repeatboolean-Repeat on re-enter
debugbooleanfalseShow debug overlay
enabledbooleantrueEnable/disable observer
onEnter(observer) => void-Enter callback (both directions)
onLeave(observer) => void-Leave callback (both directions)
onEnterForward(observer) => void-Enter callback (forward only)
onLeaveForward(observer) => void-Leave callback (forward only)
onEnterBackward(observer) => void-Enter callback (backward only)
onLeaveBackward(observer) => void-Leave callback (backward only)
onUpdate(observer) => void-Progress update callback
onSyncComplete(observer) => void-Sync complete callback
onResize(observer) => void-Resize callback

Related components