Appearance
ScrollSync
ScrollSync binds animation states and programmatic callbacks to browser scroll progression. The module tracks trigger elements relative to configurable viewport boundaries (start and end), outputting a normalized progress value (0-1) and dispatching discrete directional events.
Integration occurs directly via the scrollSync parameter on any tween configuration, or manually via standalone ScrollSync.create(config) instances.
1. Triggered Sequences
Absent the scrub parameter, ScrollSync executes standard playback controls. The target animation.play() invokes when the scroll position crosses the downward start boundary, and animation.reverse() triggers upon the upward intersection. The once: true configuration terminates the tracker immediately after the initial downward intersection.
The linked animation requires the paused: true configuration property to prevent execution prior to the boundary crossing.
js
animateFrom(items, {
y: 100, z: -200, opacity: 0, rotationX: -45, rotationY: 20, scale: 0.8,
stagger: 0.1, duration: 1.2, ease: 'expo.out',
paused: true,
scrollSync: {
trigger: gridElement,
bounds: scrollContainer,
start: 'top 85%',
once: true
}
});2. Interpolated Scrubbing
The scrub configuration maps scroll progression proportionally to the animation progress property. Assigning a numerical coefficient to scrub (e.g., 1.5) initializes a secondary interpolation loop utilizing requestAnimationFrame, smoothing the interpolation over the specified duration in seconds.
js
// Scrubbed Timeline (Only hands are scrubbed!)
const scrubTl = timeline({ paused: true });
scrubTl.animate(secHand, { rotationZ: 360 * 15, duration: 4, ease: 'cubic.inOut' }, 0);
scrubTl.animate(minHand, { rotationZ: 360 * 3, duration: 4, ease: 'cubic.inOut' }, 0);
scrubTl.animate(hourHand, { rotationZ: 360 * 0.25, duration: 4, ease: 'cubic.inOut' }, 0);
ScrollSync.create({
trigger: sectionElement,
animation: scrubTl,
start: 'top bottom',
end: 'bottom top',
scrub: 1.5
});3. Multiphasic Parallax Geometry
Synchronous playback of distinct tweens operating with independent magnitudes within a parent timeline resolves parallax displacement. Setting scrub: true outputs zero-latency frame correspondence.
js
const tl = timeline({ paused: true });
// 1. Nebula moves slowly down
tl.animate(nebula, { y: 200, scale: 1.5, duration: 1, ease: 'linear' }, 0);
// 2. Stars move down faster
tl.animate(stars, { y: 400, opacity: 0, duration: 1, ease: 'linear' }, 0);
// 3. Text moves UP while rotating
tl.animate(text, { y: -200, scale: 1.2, rotationX: 15, duration: 1, ease: 'linear' }, 0);
// 4. Streaks whip extremely fast past the camera
tl.animate(streaks, { y: -2000, translateZ: 500, duration: 1, ease: 'quad.in' }, 0);
ScrollSync.create({
trigger: sectionElement,
start: 'top bottom',
end: 'bottom top',
animation: tl,
scrub: true
});4. Contextual Element Pinning
The pin: true configuration computes the absolute distance spanning start to end and establishes a spacer element retaining Document flow dimensions. The target element applies position: sticky and anchors to the designated viewport offset across the progression window.
The configuration supports pure-relative coordinate syntax for the end property (e.g., +=1200), computing the scroll distance explicitly independent of intrinsic element height.
js
const tl = timeline({ paused: true });
tl.animate(track, { x: '-66.666%', ease: 'linear', duration: 1 }, 0);
tl.animate(images, { x: '20%', ease: 'linear', duration: 1 }, 0); // Internal background parallax
ScrollSync.create({
trigger: container,
start: 'top 5%',
end: '+=1200',
pin: true,
animation: tl,
scrub: 0.8
});5. System Event Dispatch
Four primary lifecycle observers dispatch execution relative to the active bound crossing. The onUpdate parameter exposes the continuous normalized progress property during the sequence window.
js
ScrollSync.create({
trigger: triggerElement,
bounds: scrollContainer,
start: 'top 60%',
end: 'bottom 40%',
markers: true,
onEnter: (self) => flash(indicators.onEnter),
onLeave: (self) => flash(indicators.onLeave),
onEnterBack: (self) => flash(indicators.onEnterBack),
onLeaveBack: (self) => flash(indicators.onLeaveBack),
onUpdate: (self, { progress }) => {
apply(progressBar, { scaleX: progress });
}
});Configuration Reference
The constructor initializes properties matching the syntax below.
| Property | Type | Default | Description |
|---|---|---|---|
trigger | string | Element | required | Element binding for scroll bounds extraction. |
bounds | string | Element | window | Viewport contextualization container. |
start | string | 'top bottom' | Origin property. Syntax "{triggerPoint} {viewportPoint}". |
end | string | 'bottom top' | Termination property. Supports relative math syntax ('+=800'). |
animation | Tween | Timeline | null | Associated timeline payload. Auto-paused when scrub: true. |
scrub | boolean | number | false | Progression synchronization metric. Numeric assignments supply inertia. |
pin | boolean | string | false | Modifies DOM layout rendering relative offset pinning mechanism. |
once | boolean | false | Terminates tracking node after single forward intersection occurrence. |
toggleClass | string | null | Class application hook during bounded active states. |
markers | boolean | false | Visual bounds projection injection into physical DOM. |
Absolute and Relative Calculation Offsets
Mathematical calculations interpret properties spanning explicit coordinates to percentage distributions.
| Operator | Interpretation |
|---|---|
top | Offset zero matrix. |
center | dimension * 0.5. |
bottom | dimension. |
[number]% | Proportionate mathematical offset relative to containing bounding box. |
[number]px | Absolute dimensional spacing. |
Compound matrix operations chain natively across declaration strings:
js
start: 'center+=50px bottom-=10%'
end: '+=800'Method Registry
The core API provides standardized initialization, destruction, and refresh commands directly through the exported object hierarchy.
| Method | Role |
|---|---|
refresh() | Instructs explicit recalculation across positional vectors based on immediate DOM layout flow. Attached natively to resize hooks. |
kill() | Discards bounds rendering nodes and invalidates attached tracking listeners. |
progress | Read-only matrix parameter returning absolute 0-1 sequence value. |
isActive | Boolean extraction verifying trigger presence within designated matrix sequence bounds. |
Static Execution Properties
| Scope | Role |
|---|---|
ScrollSync.create(config) | Standard registration module. |
ScrollSync.getAll() | Extracts active execution bounds tracker instances. |
ScrollSync.refresh() | Triggers mass recalculation sequentially across attached items. |
ScrollSync.stopAll() | Iterates through and detaches all active bounds monitors. |
Protocol Export Module
Initialization through NPM distributions.
js
import { ScrollSync } from 'animx/plugins/ScrollSync'