Skip to content

ScrollSync

The ScrollSync plugin links your animations and code to the page's scroll position.

Instead of just triggering when something comes into view, ScrollSync tracks the exact pixel position. This lets you smoothly tie an animation to the scrollbar ("scrubbing") or stick elements to the screen ("pinning").


1. Basic Triggers

You can make standard animations play when they scroll into view simply by adding a scrollSync object to your AnimX.animate() settings.

Scroll down in the box below to see an animation trigger when it comes into view.

Scroll down
Animate me on scroll
End of content
60 FPS

Setting markers: true adds helpful visual lines to the screen so you can see exactly when the animation will start and end.

js
AnimX.animate('.box', {
  x: 200,
  duration: 1.5,
  scrollSync: {
    trigger: '.box',
    start: 'top 80%' // When the top of the box hits 80% down the viewport
  }
})

2. Scrubbing

Setting scrub: true links the animation directly to your scrollbar. It will play forward as you scroll down, and backward as you scroll up.

If you give it a number (like scrub: 1), it adds a 1-second smoothing delay so the animation feels incredibly smooth.

Scroll to scrub
This box scrubs with scroll — drag the scrollbar to control the animation precisely.
Keep scrolling
60 FPS
js
AnimX.animate('.box', {
  x: 300,
  scrollSync: {
    trigger: '.box',
    bounds: scrollContainer, // Element or window (default)
    start: 'top 80%',
    end: 'bottom 20%',       // Defines where the animation hits 100%
    scrub: 1                 // 1 second of smooth catch-up
  }
})

3. Pinning

Setting pin: true locks an element in place on the screen while you continue scrolling. This is great for full-screen sections or horizontal scrolling effects.

Scroll to pin
Pinned Section

I stay pinned while you scroll

Keep scrolling to unpin
60 FPS
js
AnimX.animate('.text', {
  scale: 2,
  opacity: 0,
  scrollSync: {
    trigger: '.container',
    bounds: scrollContainer, // Element or window (default)
    start: 'top center',
    end: '+=300',            // Pin lasts for exactly 300px of scrolling
    pin: true,
    scrub: true
  }
})

API Reference

Standalone Creation

If you just want to run some code when scrolling without tying it to an animation, you can create a standalone ScrollSync.

js
import { ScrollSync } from 'animx/scrollsync'

const sync = ScrollSync.create({
  trigger: '.section',
  onEnter: () => console.log('Entered!'),
  onLeaveBack: () => console.log('Scrolled backwards out of view')
})

Auto ToggleActions (Play & Reverse)

When you trigger a normal animation (without scrub), AnimX handles the playback for you:

  1. Scrolling down past the start plays the animation forward.
  2. Scrolling back up past the start plays the animation backward.

If you only want it to play once and never reverse, add once: true.

Compound Math Offsets

The start and end options use a "element-point viewport-point" format. You can also add math (+=, -=) to be even more precise.

  • Keywords: top, center, bottom, left, right
  • Percentages: 0%, 50%, 100%
  • Offsets: top+=100, bottom-=50, center+=10%

For example: 'top center+=50px' means "Start when the top of the element passes 50px below the center of the screen".

Configuration Options

OptionTypeDefaultDescription
triggerstring|ElementnullThe element that triggers the animation when it enters the screen.
boundsstring|ElementwindowThe scrolling container (defaults to the browser window).
startstring'top bottom'When the animation should start. Syntax: "triggerEdge viewportEdge". E.g. "top center".
endstring'bottom top'When the animation should end (100% progress).
scrubboolean|numberfalseLinks the animation directly to the scrollbar. Pass a number (e.g., 1) to add smooth lag.
pinboolean|stringfalseIf true, locks the element in place while you scroll past it.
oncebooleanfalseIf true, runs the animation only once.
toggleClassstringnullA CSS class to instantly add to the trigger when active, and remove when inactive.
markersbooleanfalseAdds helpful debug lines to the screen.
animationTween|Timelinenull(Used when calling ScrollSync.create()). The animation instance to link to.

Event Callbacks

All callbacks receive the ScrollSync instance as their first argument.

CallbackDescription
onEnterFires when scrolling down past start.
onLeaveFires when scrolling down past end.
onEnterBackFires when scrolling up past end.
onLeaveBackFires when scrolling up past start.
onToggleFires whenever the active state flips (receives { isActive, progress }).
onUpdateFires on every pixel of scroll change while active.

Instance Methods

MethodDescription
refresh()Force-recalculates all pixel bounds based on current DOM layout. (Fires automatically on window resize).
kill()Cleans up the animation, removes pins/markers, and deletes event listeners.
progress(Getter) Returns the current scrolled progression 0-1.
isActive(Getter) Returns true if the scroll position is between start and end.