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.

Was this guide helpful?