Help guide

inputs node reference

Updated June 21, 2026

inputs node reference

Product media placeholder

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

Nodes that read external signals into the graph: DOM events, mouse position, scroll progress, keyboard input, time, and other browser/device inputs.

Category key inputsGenerated public nodes 51Registry source faster-motion-docs/node-registry.json

Nodes

NodeTypeContextDescription
Accumulate PulseaccumulatePulsesharedIntegrates `value` per frame and emits a `pulse` each time the running total reaches `threshold`, then subtracts threshold from the accumulator (overshoot carries forward). `maxBacklog` clamps post-fire overshoot so a one-frame burst cannot queue an unbounded backlog.
Bidirectional CounterbidirectionalCountersharedClamped integer counter with separate `increment` and `decrement` inputs. Counter never grows past `max` or below `min` — out-of-range pulses are silently absorbed inside the node, so the visible `value` always reflects bounds. Sister of `pulseCounter`, but bidirectional and clamped. Avoids the `cDn − cUp` two-counter-subtract hack and its over-scroll drift bug at boundaries.
Bidirectional SnapbidirectionalSnapsharedSelf-contained wheel-driven discrete-step navigator. Bundles observer + threshold pulses + counter + direction latch + initial-load pulse + indexed dispatcher into one author-facing node. Outputs an integer `activeIdx` that wraps in [0, count), forward / backward latches for direction-aware reveals, and per-section enter / exit pulse pairs (`enter_out{i}`, `exit_out{i}`) fired on every `activeIdx` edge. Compound — expands at load to ~8 primitives.
Canvas PointercanvasPointersharedCanvas-level pointer event source — outputs normalized pointer position, down/up flags, and hold state.
Click PulseclickPulsesharedDOM pointer-event listener that emits a single-frame `pulse` per fire on `selector`, with click metadata fan-out — `value` (param-or-wired), `x` / `y` (clientX/Y), and `matchIndex` (which selector match fired). `pulse` is the only pulse-coupled signal; all metadata holds at the last-fire value between pulses, so consumers gate on the rising edge to read fresh data. `eventType` selects between `click` / `dblclick` / `pointerdown` / `contextmenu` / `auxclick` etc.
Click State DispatcherclickStateDispatchersharedClick N targets to set a state to one of N values, written to a single attribute on a write target. Compound: expanded into N eventListener + chained-ternary expression + pulseOr + latch + 1 domPropertyWrite. The latch holds the dispatched value, the write puts it on the writeTo target as a `data-*` attribute that CSS can match against. Also exposes `value` (latched float, for downstream graph computation) and `pulse` (rising-edge merged click pulse, for downstream triggers).
Direction LatchdirectionLatchsharedMaintains a ±1 direction value, flipped to +1 on rising-edge `forward` or -1 on rising-edge `backward`. Outputs `direction` (signed) plus `forwardActive` / `backwardActive` (binary 0/1) for use as multipliers in direction-aware animation expressions. Replaces the pulseTween-of-duration-0.001s + sign-extracting expressions hack.
DistancedistancesharedMouse-to-element-rect proximity. Outputs 0 (far) to 1 (touching) with falloff.
Distance InputdistanceInputdomMouse distance to target (0 = at target, 1 = beyond radius)
DOM Query SizedomQuerySizesharedCounts DOM elements matching a CSS selector at bind time. Pairs with forEach-driven cluster math: feed `count` into a singleton expression that needs to know N (e.g. dock cluster bounds) so the graph-side N stays in lockstep with the DOM-side icon count — author no longer has to keep a hardcoded `N` in sync with the HTML.
Drag InputdragInputdomDEPRECATED for new authoring — prefer `dragVelocity` (passive sensor) wired into a `scrollPosition` or a translateX expression. `dragInput` wraps the internal Draggable utility, which physically translates the bound element via inline `transform` writes to drive its own progress reading. That hijacks the element: it can't coexist with a pinned section, an existing transform, or another node that needs the same DOM space. Kept as a stable boundary input for legacy `.fmtion` files; new graphs should not introduce it. Boundary input: binds pointer events to a DOM element and maps drag offset to 0-1 progress on the configured axis. Supports parent-bounded range and inertia throw.
Drag VelocitydragVelocitysharedPassive pointer-drag sensor: cumulative per-axis offset, per-frame raw delta, continuous velocity, optional post-release inertia. Emits px-cumulative offset (`offsetX`/`offsetY`), per-frame raw pointer delta (`frameDeltaX`/`frameDeltaY`), px/sec velocity (`dx`/`dy`), magnitude, and an `isDragging` gate. Never moves the bound element — pure pointer-event integration so the data can be composed into arbitrary downstream graph expressions (carousel pan, parallax pull, scrub-forever timelines, swipe-to-scroll via `scrollPosition`) without hijacking the listen target. After release, velocity decays exponentially over `releaseDecay`; with `inertia: true` that decaying velocity also integrates back into offset (and into `frameDelta*` so an inertia tail can flow into a downstream `scrollPosition`), respecting the optional clamp bounds.
Element CountelementCountsharedEmits `document.querySelectorAll(selector).length` as a first-class graph value. Use to eliminate hard-coded `N` literals scattered across `propertyAnimation` channel maxes, `expression` `* (N-1)` math, and `clickStateDispatcher.values[]` arrays — wire `count`/`countMinusOne` into them so adding a matched element auto-rescales the graph. Re-queries each evaluate; cost is one querySelectorAll per Scheduler tick (negligible). Throws on empty selector or absent DOM (faster-motion-runtime/SSR).
Event ListenereventListenerdomBoundary node — binds a DOM event listener on the target element and emits a graph pulse every frame an event fired. `fired` is 1/0 per frame; `count` is the number of events seen this frame (for click-counting / rapid-fire aggregation). The event queue captures every event between graph ticks, so nothing is dropped on busy frames.
Gated PulsegatedPulsesharedAND-gate for pulses. Outputs `pulse=1` ONLY on a frame where the input `pulse` is rising AND `gate` is > 0.5. Replaces the `expression: pulse * gate` + `pulseOr` chain authors use to filter a pulse by a boolean state. Pure combinatorial logic with one frame of edge-detector memory.
Hoverhoversharedmouseenter/mouseleave with smooth 0→1 transition over duration.
Indexed DispatchindexedDispatchsharedEdge dispatcher for an externally-owned integer index. Whenever `index` rises or falls to a different integer, fires a single-frame pulse pair: `exit_out{prev}` for the slot we leave and `enter_out{curr}` for the slot we enter. First evaluate fires only the initial enter (no prior slot exists). Sink-agnostic — routes pulses, not values.
Keyboard ListenerkeyboardListenerdomKeyboard key press/release to graph signal
Keyframe ProgresskeyframeProgresssharedReads a parameter value and outputs it as progress. Wire from ParameterStoreNode or SM output for timeline-driven animations.
LatchlatchsharedSample-and-hold on rising-edge `pulse`. Captures the live `value` at the pulse moment and freezes it on `held`.
Latch (2D)latch2DsharedAtomic sample-and-hold for a scalar X+Y pair. On rising-edge `pulse`, captures both axes from the SAME frame.
Latch (Vec2)latchVec2sharedVec2 sample-and-hold. Both components captured atomically on the rising-edge `pulse`. See `latch` for the float variant.
Load PulseloadPulsesharedFires a single-frame `pulse` on the first graph evaluation, then stays at 0 forever. The graph-native equivalent of "do this once at startup". Replaces the common hack of `(time > 0.05 ? 1 : 0)` expression + thresholdPulse rising-edge detector — that pattern silently failed because of thresholdPulse's cold-start rule (first-frame-above-threshold is NOT a rising edge).
Modal TogglemodalTogglesharedOpen-on-click / close-on-click toggle that latches a 0/1 state and writes it to one or more `data-*` attributes. Compound: expanded into eventListener + pulseOr + latch + domPropertyWrite per open target. Each `openTarget` receives the same attribute write so popup / trigger / backdrop / overlay all flip in sync.
Mouse InputmouseInputdomPointer position (0-1) on selected axis
Mouse ProgressmouseProgresssharedOutputs normalized mouse position [0, 1] relative to a target element or viewport.
Mouse VelocitymouseVelocitydomPer-frame pointer velocity. One node emits five outputs in parallel — wire whichever fits.
ObserverobserverdomGesture detector — listens for wheel / touch / pointer / scroll events on a target and outputs accumulated deltas. Events accumulate internally until the magnitude crosses `tolerance`, at which point the per-frame `deltaX` / `deltaY` outputs spike to the gesture amount for one frame, then reset to 0 next frame. Pair with `thresholdPulse` to convert deltas into discrete pulses, then `pulseCounter` for snap navigation.
PinpinsharedF330/F340 pin engagement state machine. Reads engine handle (from sibling PinAnchorNode) + progress; runs the 3-state lifecycle: BEFORE (progress ≤ 0) = element natural inside spacer; PINNED (0 < progress < 1) = element position:fixed at viewport top; AFTER (progress ≥ 1) = element at bottom of spacer via padding-top. Spacer + handle ownership lives on PinAnchorNode (loader-emitted). Subsumes scrollPin.
PointerpointerdomTracks pointer position over an element. One node emits all coordinate spaces in parallel — wire whichever output the consumer needs.
Pulse CounterpulseCountersharedPulse-driven integer counter with optional wrap-around. Each rising edge of `pulse` advances `index` by `step`; rising edge of `reset` returns `index` to `start`. With `wrap` enabled, output is folded into `[start, start + max)` via positive modulo (negative steps wrap correctly too). The current `index` is published every frame; downstream consumers (`pulseRouter`, expressions, `parameterReadFloat`) read it like any other numeric source.
Pulse DelaypulseDelaysharedFires `pulse` exactly `delay` seconds after a rising-edge `trigger`. Graph-native equivalent of `setTimeout(..., delay)`. Single-slot — additional triggers while a pulse is pending are absorbed (matches debounce / one-shot semantics). For per-trigger queuing, compose with `pulseCounter`.
Pulse DispatchpulseDispatchsharedOne pulse in, one of N channels out per pulse. `strategy` picks the dispatch rule. Replaces the accumulator + counter + router triplet.
Pulse ORpulseOrsharedFires `pulse=1` for a single frame whenever ANY input pulse has a rising edge. Replaces the boilerplate `Math.max(node('a'), node('b'), …)` expression + thresholdPulse pair authors use to combine multiple trigger sources.
Pulse RouterpulseRoutersharedDemultiplex one pulse to one of `count` output channels by integer `index`. Rising edge on `pulse` produces a single-frame spike on `out{Math.round(index)}`; out-of-range follows `defaultRoute` (set to -1 to drop).
Random FloatrandomFloatsharedPicks a uniform random float in [`min`, `max`) on each rising-edge `pulse` and holds it until the next pulse. Wire into a tween's `to` for per-spawn variety (random rotation, scale variance, fall distance).
Random IndexrandomIndexsharedSister of `pulseCounter`: picks a random integer in [0, count) on each rising-edge `pulse`. Pair with `pulseRouter` for non-rhythmic dispatch where round-robin reads as too mechanical. Deterministic — uses a seeded mulberry32 PRNG so seek + replay produce identical sequences.
Scroll EventscrollEventsharedF349 — edge-pulse detector on a 0..1 progress signal. Emits 1-frame pulses on threshold crossings: `entered` (forward across startThreshold), `left` (forward across endThreshold), `enteredBack` (backward across endThreshold), `leftBack` (backward across startThreshold). Pair with `pulseTween` and/or `parameterAction(set/toggle)` to recover trigger-mode toggleActions semantics, or with `parameterAction(set, amount=1)` on `entered` only to recover an observe-once latch.
Scroll InputscrollInputdomScroll progress (0-1) from page scroll position
Scroll PositionscrollPositionsharedOwns 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.
Scroll ProgressscrollProgressdomOutputs normalized scroll position [0, 1]. Drive text/instance animations from scroll.
Scroll TriggerscrollTriggerdomTrack an element's position relative to the scroll viewport — outputs progress (0..1), direction (±1), velocity (px/s), isInView (0/1), and pin geometry. Edges control when progress starts and ends, expressed as `<elementEdge> <viewportEdge>` pairs ("top bottom" = element top reaches viewport bottom; "bottom top" = element bottom reaches viewport top). When `pin: true` is authored, the loader emits a PinAnchor sibling and wires `flowTop` automatically so progress measures through the spacer rather than the pinned rect.
Scroll Trigger EachscrollTriggerEachsharedPer-element scroll progress fan-out. Same edge math as `scrollTrigger`, but resolves N matched elements at bind time and emits `progress`/`isInView` as arrays — each element's progress is computed against ITS OWN viewport position. Pairs with `staggerAnimate.progressArray` for "fire each row when its row enters viewport" patterns where one shared scrolltrigger range can't represent the per-element timing. Use when DOM-order interleaves columns (CSS grid) or rows scroll past at distinctly different viewport positions, and where same-row vs different-row stagger ordering would otherwise force per-tile triggers.
Slide DeckslideDecksharedFull-screen slide-deck navigation in one node. Bundles wheel input, optional next/prev arrow clicks, optional nav-link clicks (matchIndex → seekTo), and the eased slideRouter. Compound: at load time it expands to `slideRouter` + `wheelGesture` + up to 3 `clickPulse` nodes + `pulseOr` (when 2+ advance sources). Outputs re-export the slideRouter outputs verbatim. Author can still bypass and wire the primitives by hand for one-off cases — slideDeck is purely additive.
Slide RouterslideRoutersharedGestural N-stage routing with eased transitions. Owns its own discrete-index state and runs an internal eased clock between consecutive indices. 3 input triggers (`advance`, `retreat`, `seekTo`) replace the upstream `pulseCounter` chain — wire wheel / click / key gestures directly. Slide count auto-derives from `slidesSelector` (preferred) or is configured manually via `slideCount`. Emits a continuous `currentIndex` (lerped during transition), the latched `discreteIndex`, eased `transitionProgress`, and a `slideActivations` Float[N] channel.
Text InputtextInputcanvasInteractive text field with cursor and selection
Threshold PulsethresholdPulsesharedEdge-detector / pulse generator. Watches `value` and fires a single-frame `pulse` when it crosses `threshold`. `mode: edge` (default) fires once per crossing then suppresses until value drops below `threshold − hysteresis` and re-crosses (debounce). `mode: auto` fires periodically paced by `cooldownMs` for as long as value stays past threshold (metronome). `direction` selects rising-only / falling-only / both. Continuous comparator output `isAbove` is raw (1 while past threshold, 0 otherwise) — useful as a gate when you do not want pulse semantics. First-frame past-threshold does NOT fire (cold-start state-snap, prevents spurious init pulses).
Time InputtimeInputsharedElapsed time to normalized progress (0-1)
Viewport ObserverviewportObserversharedIntersectionObserver-backed visibility detector. Watches a single element (typically per-clone in a forEach template via `{ "fromScope": "selector" }`) and emits an `enterPulse` (single frame) when it becomes visible, an `exitPulse` when it leaves, plus a continuous `isVisible` gate and the raw `intersectionRatio` (0..1). Crucially this fires on transform-induced visibility changes too — a translateX-driven carousel (no document scroll) still triggers the pulses, which is what differentiates it from `scrollTrigger`'s scroll-event-driven progress. Use as the trigger for per-card pluck animations: each card's pluck fires the moment IT enters view, with parameters captured from a velocity signal at that exact moment via a `latch`.
Virtual ScrollvirtualScrollsharedContinuous 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.
Wheel GesturewheelGesturesharedDOM wheel listener that fires one pulse per noticeable scroll burst with a lockout window — the gesture model used by full-screen scrolljack / slide-deck navigation. Accumulates `deltaY`, fires a single-frame `pulse` once accumulated travel crosses `threshold`, then ignores further wheel events for `lockoutMs` (typically the slide transition duration). Resets the accumulator after `restMs` of idle so a slow scroll doesn't drift toward the threshold.

Related guides

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