Text Animate
Applies per-glyph geometric animation to text, with independent In and Out states. Outputs animated TextData and a reveal mask texture.
Category: Text Menu path: Text > Text Animate
Ports
| Port | Type | Direction | Description |
|---|---|---|---|
text_in | text | input | Source TextData (from Text or another TextAnimate) |
offsetField_in | vectorField / scalarField | input | Per-glyph position offset field. Sampled at each glyph's visual center, scaled per-axis by fieldOffsetAmp. A vectorField is directional — eval_bipolar ([-1, 1]), v.x→X, v.y→Y independently. A scalarField is a magnitude — eval ([0, 1]), where black (0) = no offset and white (1) = full — applied to both axes, with the fieldOffsetAmp sign/axis setting direction (zero one axis to confine motion to the other; scalar-field-driven single-axis offset is the most common case). The unipolar "black = none" reading matches the Scale / Rotation / Opacity fields. |
scaleField_in | scalarField | input | Per-glyph scale field. Unipolar strength: field 0 = no change (scale 1), 1 = fieldScaleTarget. A true resize of the glyph outline around the baseline-anchored pivot (not a reposition). Same none→full convention as the Rotation field, so a black→white gradient drives both coherently. |
rotationField_in | scalarField | input | Per-glyph rotation field. Unipolar: field 0 → no rotation, 1 → fieldRotationAmplitude degrees (a black→white gradient reads as none→full, same convention as the Scale field). Rotation is around the baseline-anchored pivot. This is the C4D Plain-Effector–style "rotate each letter by the field" input. |
opacityField_in | scalarField | input | Per-glyph opacity multiplier field. Multiplies on top of the reveal opacity. |
out | text | output | TextData with per-glyph animation transforms applied |
reveal_mask | imageRgba16f | output | Grayscale texture showing per-glyph reveal state |
Parameters
Glyph
| Param | Type | Default | Description |
|---|---|---|---|
glyphAnchor | enum | Baseline | Per-glyph pivot for all per-glyph rotation/scale (In/Out and fields). Baseline = each letter rotates/scales with its feet on the baseline (default). Center = pivots on the letter's vertical ink centre (e.g. scale each letter from its middle). Horizontal pivot is always the glyph centre. |
When the Text Animate node is selected, the viewport shows a dashed box around each glyph with a dot at its pivot — so you can see (and choose) where each letter transforms from. The pivot dot moves between baseline and centre as you switch glyphAnchor.
Timing
These only affect the staggered In/Out reveal — they don't apply to field-driven effects. The whole group is hidden when both In and Out animation are off (pure field-driven mode); it reappears when you enable either.
| Param | Type | Default | Description |
|---|---|---|---|
target | enum | Character | Granularity: Character, Word, Line, or All |
staggerMode | enum | Time | How elements are staggered. Time (default): every element plays the full progress keyframe curve, delayed staggerFrames per element — whatever you draw on the progress curve in the graph editor (overshoots, bounces) plays per element, each at its own landing. Progress: elements divide the 0→1 progress range into slices (stagger % + easing apply). Nodes saved before this param existed keep the Progress behavior. |
stagger | scalar | 50 | (Progress mode) Delay between elements in the animation sequence |
staggerFrames | scalar | 2 | (Time mode) Frames of delay between consecutive elements |
order | enum | Forward | Stagger order: Forward / Reverse / Random / Center / Edges |
seed | scalar | 1 | Seed for order: Random (deterministic permutation) |
easing | enum | Smooth | (Progress mode) Linear or Smooth (smoothstep). Hidden in Time mode — there the curve itself is the motion. |
Progress is open-range. Values below 0 and above 1 pass through to the geometric channels (position / scale / rotation), so overshoot lives on the progress curve itself — keyframe past 1 and settle back to land with a bounce. Opacity and blur clamp, so nothing flashes. In Progress mode, out-of-range progress moves the whole line together; in Time mode each element plays the full curve — including every bounce — on its own delayed clock.
Order modes:
- Forward / Reverse — sequential, first-to-last or last-to-first.
- Random — Fisher-Yates permutation seeded by
seed. Same seed = same shuffle, so you can animate or keyframe the seed to reshuffle. - Center — middle glyphs animate first, edges last. Expands outward.
- Edges — edges first, middle last. Collapses inward.
In (Entry Animation)
Gated by the In Animation toggle (inEnabled), which defaults to off — a freshly-added Text Animate is a clean pass-through so field-driven work isn't perturbed by a default reveal. Turn it on for the classic entry animation; the rows below appear only when it's enabled. (Existing projects keep their In animation running.)
| Param | Type | Default | Description |
|---|---|---|---|
inEnabled | boolean | false | Master toggle for the In (entry) animation. Off = no entry transform (pass-through). |
progress | scalar | 0.5 | In animation progress (0 = all hidden, 1 = all revealed) |
offsetX | scalar | 0 | Horizontal offset of the From state |
offsetY | scalar | 50 | Vertical offset of the From state (positive = below) |
fromScale | scalar | 1 | Scale of the From state |
fromRotation | scalar | 0 | Rotation of the From state (degrees, around each glyph's baseline-anchored pivot — the baseline stays put) |
fromOpacity | scalar | 0 | Opacity of the From state (0 = invisible) |
fromBlur | scalar | 0 | Blur radius of the From state |
Out (Exit Animation)
| Param | Type | Default | Description |
|---|---|---|---|
outProgress | scalar | 0 | Out animation progress (0 = no exit, 1 = all exited) |
outOffsetX | scalar | 0 | Horizontal offset of the Out state |
outOffsetY | scalar | -50 | Vertical offset of the Out state (negative = above) |
outFromScale | scalar | 1 | Scale of the Out state |
outFromRotation | scalar | 0 | Rotation of the Out state (degrees, around each glyph's baseline-anchored pivot) |
outFromOpacity | scalar | 0 | Opacity of the Out state |
outFromBlur | scalar | 0 | Blur radius of the Out state |
Per-glyph field effects
After the In/Out animation transforms settle each glyph into its current position, optional field inputs drive additional per-glyph offset, scale, and opacity. Fields are sampled at each glyph's current visual center (AABB midpoint), in origin-centered comp-pixel coords — the same convention as every other field consumer.
| Param | Type | Default | Description |
|---|---|---|---|
fieldOffsetAmp | vec2 | (100, 100) | Per-axis pixel scale applied to offsetField_in output. The default gives glyph-scale motion (a vector field's ±1 → ±100 px; a scalar field's 0→1 → 0→100 px). Set one axis to 0 to confine a connected field's motion to the other axis (e.g. a scalarField driving X-only offset); use a negative value to flip direction. Link toggle in Properties scrubs both together. (Pre-split projects fall back to the legacy scalar fieldOffsetAmplitude for both axes.) |
fieldRotationAmplitude | scalar | 180 | Degrees of rotation a full (1.0) rotationField_in sample produces. Unipolar: field 0 → none, 1 → this many degrees. Use a negative value for the opposite spin, or a Remap upstream for a custom range. |
fieldScaleTarget | scalar | 0 | Scale a full (1.0) scaleField_in sample reaches. field 0 = no change (scale 1), 1 = this. Default 0 = shrink away; set 2 to grow to double, etc. (scale = lerp(1, target, field)). |
The field inputs are optional — disconnected fields no-op. Pair with Vortex / RadialForce / DistanceField / Noise / Gradient / any other field source to drive per-letter motion, scale, rotation, or visibility from spatial primitives. This is the per-character "effector" workflow.
Signal interpretation:
offsetField_in(vectorField or scalarField): a vectorField is sampled viaeval_bipolar([-1, 1]) and maps its two components to X/Y independently. A scalarField is sampled viaeval([0, 1]) — black (0) = no offset, white (1) = full — and applied to both axes, matching the unipolar "black = none" convention of the Scale / Rotation / Opacity fields. Either is multiplied byfieldOffsetAmpper axis to get pixel displacement, added directly to glyph position; the amplitude's sign/magnitude sets direction + distance (sofieldOffsetAmp.x = 0⇒ Y-only motion). Only one field connects at a time (single edge per port).scaleField_in(scalarField): sampled viaeval([0, 1]), thenscale = lerp(1, fieldScaleTarget, field)— field 0 → scale 1 (no change), field 1 →fieldScaleTarget. A real resize of the glyph outline around the baseline-anchored pivot. This "0 = no effect" strength convention matches the Rotation field.rotationField_in(scalarField): sampled viaeval([0, 1]), multiplied byfieldRotationAmplitude(degrees) → per-glyph rotation around the baseline-anchored pivot (field 0 → none, 1 → full). Composes additively with the In/OutfromRotation.opacityField_in(scalarField): sampled viaeval, clamped to[0, 1]. Multiplies the existing reveal opacity (from In/Out progress + from-state).
Per-glyph pivot: rotation and scale pivot on a baseline-anchored point — each glyph's horizontal centre at the text baseline. Letters tumble and grow in place without the baseline drifting per character (a descender like "p" and an x-height letter like "o" share the same baseline pivot line).
Expose Channels
When enabled (E button on node header), adds input ports that override params via edge connections:
| Port | Type | Overrides |
|---|---|---|
progress_in | scalar | progress |
stagger_in | scalar | stagger |
offset_in | vec2 | offsetX and offsetY |
fromScale_in | scalar | fromScale |
fromRotation_in | scalar | fromRotation (degrees) |
fromOpacity_in | scalar | fromOpacity |
fromBlur_in | scalar | fromBlur |
outProgress_in | scalar | outProgress |
outOffset_in | vec2 | outOffsetX and outOffsetY |
outFromScale_in | scalar | outFromScale |
outFromRotation_in | scalar | outFromRotation (degrees) |
outFromOpacity_in | scalar | outFromOpacity |
outFromBlur_in | scalar | outFromBlur |
How It Works
TextAnimate is a geometric modifier, not a render effect. It modifies per-glyph position, scale, opacity, and blur values in the TextData before it reaches a DrawText node.
Each glyph (or word/line/all, depending on target) gets an individual animation progress based on its index in the sequence, the stagger delay, and the global progress value. The element interpolates between its From state and its resting (fully revealed) state.
The In animation brings elements from the From state to their natural position. The Out animation moves elements from their natural position to the Out state. Both can be active simultaneously for a typewriter-style "rolling window" effect.
The reveal_mask output is a grayscale texture where each glyph's area is white (revealed) or black (hidden), useful for masking other effects.
When connected to DrawText with applyReveal enabled, per-glyph blur and opacity from TextAnimate are applied during rasterization.
Usage Examples
Basic: Fade-up character reveal
Text -> TextAnimate (progress: keyframed 0 to 1, offsetY: 50, fromOpacity: 0) -> DrawText -> Transform2D -> Output. Characters fade in from below, one at a time.
Word-by-word with blur
Set target to Word. Set fromBlur to 20 and fromOpacity to 0. Keyframe progress from 0 to 1. Words sharpen and appear sequentially.
In and Out (rolling window)
Keyframe both progress (0 to 1) and outProgress (0 to 1, starting slightly later). Characters enter from below and exit upward, creating a scrolling reveal.
Scale pop
Set fromScale to 0.5, fromOpacity to 0, offsetY to 0. Characters pop in from half-size to full-size.
Tumble in
Set fromRotation to -90 (or +90), offsetY to 50, fromOpacity to 0. Characters spin into place as they fall. Try order: Random for a scatter effect.
Scramble
Set order: Random and keyframe seed over time — the stagger permutation shuffles, so characters animate in a different order each time. Pair with target: Character and short stagger for a quick scramble.
Expand from middle
Set order: Center, keyframe progress from 0 to 1. Characters nearest the middle animate first, edges last — good for emphasis reveals.
Per-character overshoot / bounce
With staggerMode: Time (the default) set offset to (0, 80). Keyframe progress as the actual landing motion in the graph editor — e.g. 0 → 1.15 → 0.96 → 1 — and each character rises, overshoots past its resting position, and settles, one after another (staggerFrames apart). Add more decaying wiggles to the curve for a bouncing-ball landing; the curve is each character's motion, so anything you can draw, every character performs.
Tips
- TextAnimate modifies TextData, not pixels -- always follow with DrawText for rendering
- You can chain multiple TextAnimate nodes for layered animation effects
- The
reveal_maskoutput is useful for driving other effects (e.g., connect to a Mix node's mask input) staggercontrols the overlap between elements -- higher values mean more sequential, lower values mean more simultaneous- Set
targetto All for a uniform fade/scale of the entire text block
Related Nodes
- Text -- creates the source TextData
- DrawText -- rasterizes the animated TextData (
applyRevealapplies per-glyph blur/opacity) - TextToShape -- alternative path: convert text to shape outlines