Help guide

Virtual Scroll node

Updated June 21, 2026

Virtual Scroll node

Product media placeholder

Replace this area with a screenshot or short walkthrough video during the media sweep.

Continuous wheel/touch accumulator with eased follow. Replaces document scroll for infinite-loop carousels and forever-scroll virtual scrollers — listens to wheel/touch on `selector` (or window), accumulates raw deltas into an unbounded `targetPos`, and lerps `position` toward it each frame using `smoothing`. `position` is monotonic and unbounded, so consumers can fract-wrap it (`carouselEffectAnimation` does this internally) for true forever-scroll without document-scroll runways. Optionally hides the native scrollbar by setting `overflow:hidden` on html+body during bind, restoring on dispose.

Type virtualScrollCategory inputsContext sharedDynamic ports noCompound no

Inputs

PortTypeDescription
gateInputfloatWhen > 0.5 the node ignores wheel/touch events. Wire from any boolean-shaped graph signal (e.g. a modal-open gate, a transition-busy gate).

Outputs

PortTypeDescription
positionfloatSmoothed accumulated position in raw wheel-delta pixels. Unbounded — keeps growing as user scrolls.
velocityfloatPer-frame delta of `position`. Sign indicates direction; magnitude indicates speed. Useful as a scroll-energy input to mesh distortion / motion blur amounts.
directionfloat+1 forward / -1 backward / 0 idle. Sign of velocity above a small dead-zone.

Parameters

ParameterTypeDefaultDescription
selectorelementSelector""Element to listen on. **Leave empty** for window-scope (the right choice for full-page virtual scroll). Set a specific selector only to scope to a region.
axisaxisChooser"y"Which delta channel(s) feed the accumulator. Vertical (deltaY) is the default for wheel-driven horizontal carousels (counter-intuitive but matches user expectation — vertical scroll wheel drives horizontal travel). Horizontal (deltaX) for trackpad-pan-only. Both lets the dominant-axis component win.
sensitivityfloat1Multiplier on raw wheel delta before accumulation. 1.0 = 1px wheel-delta → 1 unit position. Decrease for slower travel, increase for snappier feel. min 0.01; step 0.1
smoothingfloat0.1Lerp factor toward target each frame (`position += (target - position) * smoothing`). 0 = instant (no smoothing); 0.1 = relaxed; 0.05 = very smooth (long tail). Smoothing values around ~0.08-0.12 give a buttery scroll feel. min 0; max 0.99; step 0.05
hideNativeScrollbooltrueOn bind, set html+body `overflow:hidden` so the native scrollbar never appears (and the page never reaches a "scroll end"). Restored on dispose. Disable only if you want native scroll to coexist (rare).
inertiafloat0Momentum strength. 0 = pulse-mode (each wheel tick is a discrete jump that the smoothing tail eases). > 0 = wheel ticks become target velocity that decays — Lenis/Locomotive feel where the scroll keeps gliding after you stop. Pair with `smoothing` for an additional render tail. 1 is a strong default. min 0; max 1; step 0.05
inertiaFrictionfloat4Velocity decay per second when inertia > 0 (`v *= exp(-friction*dt)`). 4 ≈ "loose mouse-wheel glide" (~0.7s halt), 8 ≈ "snappy" (~0.35s), 16 ≈ "near-immediate". Ignored when inertia = 0. min 0; step 0.5

Use cases

  • Infinite-loop carousel — wire `position` through `expression: node('p') / 800` into `carouselEffectAnimation.playhead`. Each 800px of wheel = one full slide cycle. Page never reaches an end.
  • Marquee / ribbon scroll — wire `position` directly into `domPoseWrite.translateX` (px units) for an endless side-scrolling ticker.
  • Smooth virtual-scroll camera — wire `position` through a smoothing node (extra easing) and a `mathUtil(modulo)` for explicit wrap, plus `velocity` into a `meshAttractor.jump` channel for scroll-velocity-driven distortion.

Related nodes

Envelope

Use virtualScroll as the node type inside a graph node envelope. Add id, optional params, optional connections, and optional activeWhen based on the guide context.

Generated source

Registry faster-motion-docs/node-registry.jsonCategory page /help/faster-motion/faster-motion-node-category-inputs/

Was this guide helpful?

Sunny Arora

Written by

Sunny Arora

Get technical deep dives delivered to your inbox

Join creators and developers who get exclusive insights, tutorials, and behind-the-scenes content every week.

No spam. Unsubscribe anytime.

Continue Exploring

You might also enjoy