Text on Path
Lay out text glyphs along a path, preserving natural letter spacing (kerning). Classic "text follows a curve" typography effect.
Category: Text Menu path: Text > Text on Path
Ports
| Port | Type | Direction | Description |
|---|---|---|---|
text_in | text | input | Source TextData from a Text node |
path_in | shape | input | The path the text follows (first path of input) |
progressOffset_in | scalar | input | Overrides progressOffset via expose channel |
out | shape | output | Transformed glyph outlines, rasterizable via DrawShape |
Parameters
| Param | Type | Default | Description |
|---|---|---|---|
progressOffset | scalar | 0 | Slides all text along the path. Keyframe 0→1 for marquee-style scrolling text. Wraps modulo 1.0. |
alignToPath | boolean | true | Rotate each glyph to match the local tangent direction. Turn off for text that "rides" the path position without curving (rare). |
alignOffset | scalar (degrees) | 0 | Additional rotation added to the tangent angle. Use 180 for text on the underside of a curve, 90 for vertical orientation. |
How It Works
TextOnPath is positioned between Text and DrawShape in the pipeline — it outputs Shape, not TextData, so the result is filled/strokable glyph geometry rather than text that can still be re-laid-out.
For each glyph in the text layout:
- The glyph's original layout position
glyph.position[0](its x-coordinate in the flat text) is converted to a progress along the path:progress = (x - text.bounds.left) / text.width + progressOffset. - The path is sampled at that progress using Gauss-Legendre arc-length parameterization — so progress=0.5 is exactly half the path's physical length in, not half the parametric t.
- The glyph's outline is rotated around its layout origin by the local path tangent (when
alignToPathis on), then translated to land on the sampled path position.
Result: letters maintain their natural kerning (wide letters like "M" take more path length, narrow ones like "i" take less), and each glyph is correctly oriented to the path tangent at its position.
This differs from the PointsAlongPath + CloneToPoints pattern for text:
| TextOnPath | PointsAlongPath + Clone | |
|---|---|---|
| Spacing | Natural (kerning preserved) | Evenly spaced |
| Best for | Text traveling along a curve (labels, titles) | Dial markers, clock faces, discrete letter placement |
| Output | Single shape with all glyphs | One clone instance per point |
Both are valid; pick the one that matches your intent.
Usage Examples
Label on a curved ribbon
Text ("Hello, world!") ──┐
├─► TextOnPath (alignToPath: true, progressOffset: 0) ─► DrawShape ─► Output
EditableShape (ribbon) ──┘Classic typography-on-curve — letters travel along the ribbon, each oriented to the ribbon's direction at its position.
Animated scrolling marquee
Text ("BREAKING NEWS • ") → TextOnPath (path: Circle, progressOffset: keyframed 0→1) → DrawShapeUse a closed circle path + keyframed offset for a ticker that loops forever. The offset wraps modulo 1 so the text re-enters where it exits.
Upside-down text on a hanging banner
Text → TextOnPath (path: arch curve, alignToPath: true, alignOffset: 180) → DrawShapeLetters face downward (useful for the underside of an arch or a hanging sign).
Vertical tower of characters
Text → TextOnPath (path: vertical line, alignToPath: true, alignOffset: 90)Text reads top-to-bottom with characters rotated sideways.
Combine with per-glyph effects
Since TextOnPath outputs a Shape with paths tagged by glyphIndex, downstream tools still work:
TextOnPath → ShapeAttributes (source: Index, target: Color, groupAttribute: "glyphIndex", ramp: red→blue) → DrawShapeEach letter colored by its index along the curve.
Tips
- Use a long enough path. If the path's arc length is less than the text's natural width, letters will overlap (progress values outside
[0, 1]wrap and start layering from the beginning of the path). progressOffsetkeyframes should usually be Linear interp for constant-speed scrolling. Smooth interp gives eased acceleration, which looks more "organic" but also more artificial for marquee effects.- Closed paths (circles, loops) scroll seamlessly via wrapping. Open paths visibly wrap back to the start.
- Path fidelity matters. For crisp text on a curve, the path should be smooth (avoid jagged polylines — use
ResampleShape(type=bezier)upstream to smooth). - Align offset of 180 flips text upside-down; good for text running along the bottom edge of a shape.
- For evenly-spaced glyphs (ignoring kerning), use
Text → TextToShape → CloneToPoints(distribution=CycleByAttribute, attribute=glyphIndex) ← PointsAlongPath(count=glyph_count)instead.
Related Nodes
- Text — source TextData node
- TextToShape — flat glyph outlines without path following. Used internally by TextOnPath.
- TextToPoints — glyph origin positions as Points
- ShapeAlongPath — single shape animating along a path (not text-specific)
- PointsAlongPath — evenly-spaced points along a path, useful for clock-face text layouts
- ShapeAttributes — per-glyph styling via
groupAttribute=glyphIndex - DrawShape — renders the output glyph outlines