Product media placeholder
Replace this area with a screenshot or short walkthrough video during the media sweep.
Text animation nodes: split text into characters/words/lines, per-character wave/fade/spring/skew/distort transforms, coverage ranges for reveal effects.
Category key textGenerated public nodes 31Registry source faster-motion-docs/node-registry.json
Nodes
| Node | Type | Context | Description |
|---|---|---|---|
| Counter | counter | shared | Animated number counter — interpolates min→max with formatting (decimals, separator, template). |
| Counter Animation | counterAnimation | shared | Interpolate a number from min to max (formatted via template, decimals, thousand separator) driven by a 0..1 progress input. Authors pick any number of output targets via `channels`: `from: "text"` writes the formatted string to any DOM string target (textContent, aria-valuetext, CSS var, title, data-*, etc.), `from: "value"` routes the raw float to any numeric CSS property (opacity, translateY, scale, rotate, width, …). One compound can show the number AND animate motion simultaneously from the same count. Compound: expands into `counter + one domPoseWrite + N domStringWrites` at load time — no runtime class. |
| Coverage Group | coverageGroup | shared | F356: Per-character transforms scaled by coverage values. Reads x/y/rotation/scaleX/scaleY/opacity from a wired AttributeBundle at slot bundle.objectIds.indexOf(objectId). Outputs Mat4TransformBundle. |
| Coverage Group Bundle | coverageGroupBundle | shared | F356: Author-facing compound for a coverage group + N coverage ranges with self-aligning bundle reads. Expands at load to one `coverageGroup` + N `coverageRange` primitives with a shared `bundle` connection — no `bundleRead` intermediaries. Compound: no runtime class. |
| Coverage Range | coverageRange | shared | F356: Per-character coverage window with falloff ramps. Reads coverageTime from a wired AttributeBundle at slot bundle.objectIds.indexOf(objectId). |
| Scramble Compute | scrambleCompute | dom | Per-character scramble effect — outputs original or random character. Convention: progress=1 fully scrambled, progress=0 fully revealed; per-char threshold derived from index/count so leftmost char reveals first. F336 adds `speed` (cycle-rate multiplier on the 16Hz baseline flicker) and `revealDelay` (hold-on-scramble fraction at the high-progress end before any chars resolve). `charset` accepts preset names (`upperCase`, `lowerCase`, `upperAndLowerCase`, `01`, `symbols`) or any literal string. |
| Split Shape | splitShape | shared | Setup-only DOM shape splitter — fractures the path / polygon source shapes inside an `<svg>` into N polygon fragments at bind time, so per-piece animations (translate, rotate, scale, opacity) can target the pieces individually. Runs once: rejection-samples points inside the source-fill region, tessellates with d3-delaunay's Voronoi, boolean-intersects each cell with the union of source paths via `polygon-clipping` so adjacent pieces share their edges exactly (no gaps or overlap). Each fragment gets the class `ft-shatter-piece`. Mirror to `splitText`, but for SVG geometry — drop in any 2-path logo and shatter it into ~100 deterministic pieces without manually pre-fragmenting in a vector editor. |
| Split Text | splitText | canvas | Setup-only DOM text splitter — wraps every word / character / line of the target element's text content in its own `<span>` so per-piece animations (rotateX, opacity, color, position) can target the pieces individually. Runs once at bind time; the spans persist for the page lifetime. Each span gets a class based on the split mode: `ft-split-word`, `ft-split-char`, or `ft-split-line` — use these in downstream selectors (e.g. `.headline .ft-split-char` for `staggerWrite`). |
| Stagger Animation | staggerAnimation | shared | Fan a single animation template across all DOM elements matching a plain CSS selector, with per-element stagger offsets. Element count is resolved at runtime via `querySelectorAll(selector)` — no template language, no `{i}` placeholder, no per-child graph nodes. Inner `each` is a propertyAnimation-shaped template (float / color / string keyframe channels); the runtime evaluates it per element with translation-stagger (each element's progress is shifted by `stagger * effectiveIndex(i)`). Compound: expands to ONE `staggerAnimate` runtime node. |
| String Array Concat | stringArrayConcat | shared | Pure data transform. Concatenates up to N stringArray inputs (in0..inN-1, default 8) into a single flat stringArray output. Complement to textDecompose for multi-source typewriter-style graphs: each source goes through its own textDecompose; this node stitches the per-source items[] into one indexable stream for textSequence. Unwired ports contribute nothing (default = empty array) so the node is safe to serialize with fewer connections than ports. |
| String Array Pick | stringArrayPick | shared | Pure picker — emits `array[floor(index)]` as a string. Index is clamped to [0, length-1]. The `array` input port wins when wired (non-empty); otherwise falls back to the `values` param. Fallback string returned when the resolved array is empty. |
| Text Apply | textApply | canvas | Pure passthrough: forwards per-character Mat4 transforms to output port for SRN consumption. Follows SkinnedPathDeformNode pattern (F264). |
| Text Color Apply | textColorApply | canvas | Per-character fill color interpolation. Writes `piece.outputs.fill.set(lerpedColor)` via the F260 port-sourced rendering contract. Supports 4 reveal modes (linear, center-out, edges-in, random) + stagger control. |
| Text Decompose | textDecompose | shared | Pure text-data transform. Splits one or more source strings into an array of strings by granularity (char/word/sentence/line) and optionally reshapes into a cumulative pyramid (prefixes/suffixes). Decouples the data-shape problem from animation — feed items[] into textSequence, variantStagger, or any index-driven consumer. Example: granularity=char, shape=prefixes on "Sunny" → ["S","Su","Sun","Sunn","Sunny"] (classic typewriter). Input precedence (highest wins): `sources` stringArray port (multi-source — typically wired from domStringArrayRead for i18n cycles), `sources` string[] param, `text` string port (single-source wire), `text` string param. Multi-source mode decomposes each entry and concatenates — one graph chain types through every word in order. Emits a parallel `itemSources: floatArray` output that tags each item with its source index — lets downstream nodes drive per-source side effects (per-word colors, opacities, etc.) without re-deriving boundaries. |
| Text Distort Compute | textDistortCompute | shared | Per-character random scatter/explosion entrance. Deterministic (seed-based). Geometry modifier — routes through TextApply. |
| Text Draw Layer Index Apply | textDrawLayerIndexApply | canvas | Per-character draw-order layering. Assigns a discrete layer index per character based on reveal order pattern + stride. Writes `piece.outputs.drawLayerIndex.set(layerIdx)` via the F260 port-sourced rendering contract. |
| Text Effect Apply | textEffectApply | canvas | Per-character blur/glow/shadow via the F260 port contract. Writes piece.outputs.blur/glow/shadow.set(v) per character using the perCharProgress stagger + reveal mode. The `effect` param selects which port to write. |
| Text Fade Compute | textFadeCompute | shared | Per-character opacity ramp with stagger. Geometry modifier — routes through TextApply via Mat4Bundle. |
| Text Reveal | textRevealAnimation | shared | Progressively reveals text by character, word, sentence, or line, driven by a progress input. DOM-first: the translatable source lives in the HTML, the .fmtion carries only the animation recipe. `sourceFrom: element` (DEFAULT) reads `selector`.textContent at bind time. `sourceFrom: elements` reads textContent from every element matching `sourcesSelector` and cycles through them in document order (multi-word typewriter). `sourceFrom: param` is an escape hatch for non-translatable copy — prefer element/elements for anything user-facing. Default (char + prefixes + includeEmpty) gives classic typewriter; switch granularity for word/sentence/line reveals under the same node type. `cycleMode: pingPong` (multi-source only) makes each phrase type forward then delete backward before the next phrase begins from empty — native author-level type+delete typewriter cycle, no progress remap needed. OPTIONAL `channels` + `variants` (same shape as variantStaggerAnimation) declare per-source side effects — e.g. a `color` channel with 3 hex values cycles the color at actual word boundaries regardless of word length or language. Compound: expands to `textDecompose` + `textSequence` + `domStringWrite` (+ optional channel writers) at load time — no runtime class. |
| Text Scramble Animation | textScrambleAnimation | shared | Scramble a single character — cycles through a charset and settles on the original, driven by a 0..1 progress input. Authors pick one or more string write targets via `channels` (textContent, attribute like aria-label / title / data-*, CSS style property, CSS custom var). Compound: expands to `scrambleCompute` + one `domStringWrite` per channel at load time — no runtime class. |
| Text Scramble Apply | textScrambleApply | canvas | Per-character glyph swap from a pre-rasterized pool. F272: configurable pool, easing curves, per-char stagger + reveal mode. |
| Text Sequence | textSequence | canvas | Cycles through a string array based on progress — outputs current text and index. The `texts` input port takes priority over the static `texts` param when wired (from textDecompose or any stringArray source), so the node composes with upstream text-data transforms without losing back-compat for .fmtion files that bake in a static array. `mode` selects the index-from-progress convention: `round` (default) = center-snap with flips at midpoints, item i centered at p=i/(N-1) — aligns with counterAnimation's round(min + p*(max-min)) so a sequence + counter scrubbed by the same progress flip in lockstep. `floor` = equal-width buckets, item i occupies [i/N, (i+1)/N) — for streamed timelines (typewriter / video-like). `cycleMode` selects how progress is mapped across multi-source arrays (where `itemSources` tags each item with its source index, typically wired from textDecompose): `forward` (default) walks the concatenated prefixes linearly, `pingPong` splits progress into S equal windows (S = source count) and runs a triangle 0→1→0 within each window — native author-level "type then delete then next phrase" typewriter cycle. With `pingPong` and no `itemSources` wired, falls back to single-source ping-pong over the whole array. |
| Text Sequence Animation | textSequenceAnimation | shared | Cycle through a sequence of strings based on progress. textSequence emits both the current string (`text`) and its position in the array (`index`, float). Authors pick any number of output targets via `channels`: `from: "text"` routes the string to any DOM string target (textContent, aria-label, CSS var, title, data-*, etc.), `from: "index"` routes the position float to any numeric CSS property (opacity gating, slide offset, step-in indicator). Compound: expands into `textSequence + one domPoseWrite + N domStringWrites` at load time — no runtime class. |
| Text Skew Compute | textSkewCompute | shared | Per-character horizontal shear with staggered decay. Geometry modifier — routes through TextApply. |
| Text Split | textSplit | canvas | Split text into chars/words/lines with glyph metrics for per-element animation |
| Text Spring Compute | textSpringCompute | shared | Per-character bouncy scale/offset via closed-form damped spring. Geometry modifier — routes through TextApply. |
| Text Stagger Animation | textStaggerAnimation | shared | Splits a text element into chars / words / lines and animates each piece from a single 0..1 progress signal with staggered start times. One authoring node replaces the splitText + per-piece tween chain. Channels are author-friendly `{from, to, ease, unit}` ranges (numeric) or CSS-fragment ranges (`blur(16px) → blur(0px)`, `inset(0 100% 0 0) → inset(0 0% 0 0)` — the runtime tokenizes numeric tokens and lerps each independently). Compound: expands at load time to `splitText` + 1× `staggerWrite` (continuous mode) — runtime stays at 2 nodes regardless of piece count. Discrete mode (instant flip per piece, typewriter-style) falls back to `splitText` + N× `propertyAnimation` and requires `count` (since N keyframe-shaped children must be emitted up front). `totalStagger` is the fraction of progress consumed by spreading start times across pieces; runtime reads piece count dynamically from splitText, so editing the heading text does not require a graph edit. |
| Text Stroke Apply | textStrokeApply | canvas | Per-character stroke color interpolation. Writes `piece.outputs.stroke.set(lerpedColor)` via the F260 port-sourced rendering contract. |
| Text Stroke Width Apply | textStrokeWidthApply | canvas | Per-character stroke width interpolation. Writes `piece.outputs.strokeWidth.set(lerped)` via the F260 port-sourced rendering contract. |
| Text Wave Compute | textWaveCompute | shared | F256: Pure per-character wave sweep. Takes progress + upstream Mat4 bundle. schedulerPhase=pure, zero this.context access. |
| Variant Stagger Animation | variantStaggerAnimation | shared | Fan a compound across N indexed DOM elements where each child has UNIQUE from/to values on shared channels. Per-child variation sibling of F324 staggerAnimation (which requires uniform values). Use for mouse-driven dispersals, hover-chaos grids, card-spread layouts, per-icon flutter — any "N siblings, same channels, different ranges". Compound: expands into N× propertyAnimation at load time (fixed-point loop then expands each to mk+pw). |