Skip to content

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

PortTypeDirectionDescription
text_intextinputSource TextData from a Text node
path_inshapeinputThe path the text follows (first path of input)
progressOffset_inscalarinputOverrides progressOffset via expose channel
outshapeoutputTransformed glyph outlines, rasterizable via DrawShape

Parameters

ParamTypeDefaultDescription
progressOffsetscalar0Slides all text along the path. Keyframe 0→1 for marquee-style scrolling text. Wraps modulo 1.0.
alignToPathbooleantrueRotate each glyph to match the local tangent direction. Turn off for text that "rides" the path position without curving (rare).
alignOffsetscalar (degrees)0Additional 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:

  1. 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.
  2. 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.
  3. The glyph's outline is rotated around its layout origin by the local path tangent (when alignToPath is 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:

TextOnPathPointsAlongPath + Clone
SpacingNatural (kerning preserved)Evenly spaced
Best forText traveling along a curve (labels, titles)Dial markers, clock faces, discrete letter placement
OutputSingle shape with all glyphsOne 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) → DrawShape

Use 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) → DrawShape

Letters 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) → DrawShape

Each 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).
  • progressOffset keyframes 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.
  • 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