Product media placeholder
Replace this area with a screenshot or short walkthrough video during the media sweep.
Owns a scroller's scroll position behind typed graph ports. Reads the target's scrollTop / scrollLeft each frame and publishes them on `scrollX` / `scrollY`. When `addX` / `addY` ports carry non-zero deltas, integrates them (with sub-pixel residue carry across frames so cumulative scroll matches cumulative input) into the scroller — one DOM write per evaluate(), so high-frequency upstream sources don't trigger a synchronous reflow on every input sample. Pair with `dragVelocity.frameDeltaX/Y` for swipe-to-scroll: drag → port → scrollPosition → DOM, fully graph-native, no element side-channels. Other writers (button "scroll to top", parallax-driven scroll) compose into the same node.
Inputs
| Port | Type | Description |
|---|---|---|
addX | float | Per-frame delta to apply to scrollLeft. Sub-pixel values are accumulated across frames so a stream of fractional deltas (e.g. 0.7, 0.6, 0.4) integrates to exactly 1.7 px of scroll, not 3 quantized 0/1 px steps. Wire from a delta source (drag frameDeltaX, expression integrating velocity, etc). |
addY | float | Per-frame delta to apply to scrollTop. Same semantics as addX. |
Outputs
| Port | Type | Description |
|---|---|---|
scrollX | float | Integer scrollLeft — what the browser actually has after this frame's write. Wire here when consumers need exact browser-truth (e.g. comparing to other scroll-event sources). |
scrollY | float | Integer scrollTop. |
positionX | float | SUB-PIXEL logical X position — the cumulative addX inputs without integer rounding. Use as a smooth pan source: drag-driven sub-pixel deltas reflect here same-frame, before scroll-event-driven readers (which see only integer scrollLeft) catch up. External scroll (wheel, keyboard) is reconciled into the accumulator at start of each frame so the logical position never drifts from browser truth. |
positionY | float | SUB-PIXEL logical Y position. Same semantics as positionX. |
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
selector | elementSelector | "document" | Element whose scroll position this node owns. `window` or `document` resolves to `document.scrollingElement` (page scroll). Any other value is a CSS selector for an inner scroller. Required. |
axis | string | "both" | `both` (default) reads + writes both scrollLeft and scrollTop. `x` / `y` restricts to one axis — useful when only one direction is graph-driven and the other should remain available for organic native scroll without being clobbered each frame. |
Use cases
- Swipe-to-scroll carousel — wire `dragVelocity.frameDeltaX` (negated, so cursor-left → page-down) into `addY` for horizontal swipe → vertical page scroll.
- Native horizontal scroller — wire `dragVelocity.frameDeltaX` directly into `addX` and set `axis: "x"` to leave the Y axis to organic native scroll.
- Programmatic scroll-to — wire a `pulseTween` or `scrollTo` value into the addY input via a delta-from-current expression for a graph-driven "scroll to next section" button.
Related nodes
Envelope
Use scrollPosition 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/