Docs
Text Along Path

Text Along Path

A text component that animates along an SVG path.

JOIN THE WAITLIST ✉ JOIN THE WAITLIST ✉ JOIN THE WAITLIST ✉ JOIN THE WAITLIST ✉ JOIN THE WAITLIST ✉ JOIN THE WAITLIST ✉ JOIN THE WAITLIST ✉ JOIN THE WAITLIST ✉ JOIN THE WAITLIST ✉ JOIN THE WAITLIST ✉

Installation


npx shadcn@latest add "https://fancycomponents.dev/r/text-along-path.json"

Usage


There are two types of animations available for this component, which you can control with the animationType prop:

  1. auto — plays the animation automatically when the text is initially rendered. This is the default setting.
  2. scroll — drives the animation with the scroll position of the container. To use this component, you'll need to provide an SVG path via the path prop. You can create this path using:
  • Design tools like Figma, Illustrator, or any online SVG editor
  • Code, by constructing the path programmatically

The component only requires the d attribute from your SVG path and the viewBox attribute from the SVG container.

Path ID

Each path needs a unique id to properly reference it in the text elements. While the component includes a basic ID generator, it's recommended to provide your own via the pathId prop, especially when using multiple instances of the component. This ensures animations remain distinct and don't interfere with each other.

Sizing and ViewBox

The SVG container can be sized flexibly - by default it will expand to fill its parent container. The viewBox attribute can be any dimensions, but it's recommended to:

  1. Match the aspect ratio you want the final component to have
  2. Use dimensions that make sense for your path coordinates

For example, if your path coordinates span 0-500 on x and 0-100 on y, a viewBox of "0 0 500 100" would be appropriate.

Understanding the component


The component consist an svg container with a path element, and two text elements with textPath elements inside. The textPath elements are used to animate the text along the path. When it is used with the auto animation type, we use an animate element to animate the text along the path. When it is used with the scroll animation type, we animate the startOffset attribute of the textPath elements to scroll the text along the path.

Auto animation


The auto animation type is the default setting, and it plays the animation automatically when the text is initially rendered. We start at 0% offset and animate to 100% offset, which means the text will start at the beginning of the path and end at the end of the path.

The relevant props for the auto animation type are:

  • duration — the duration of the animation in milliseconds
  • repeatCount — the number of times the animation should repeat. You can also set this to indefinite to make the animation repeat indefinitely (default setting)
PARIS • LONDON • BERLIN • ROME • BARCELONA • MADRID • VIENNA • PRAGUE • AMSTERDAM • STOCKHOLMPARIS • LONDON • BERLIN • ROME • BARCELONA • MADRID • VIENNA • PRAGUE • AMSTERDAM • STOCKHOLMBUDAPEST • COPENHAGEN • OSLO • HELSINKI • MILAN • MUNICH • VENICE • MADRID • VIENNA • PRAGUEBUDAPEST • COPENHAGEN • OSLO • HELSINKI • MILAN • MUNICH • VENICE • MADRID • VIENNA • PRAGUEPARIS • BERLIN • ROME • BARCELONA • MADRID • VIENNA • PRAGUE • AMSTERDAMPARIS • BERLIN • ROME • BARCELONA • MADRID • VIENNA • PRAGUE • AMSTERDAM

Animation on closed paths


You might notice the component uses two identical text elements with textPath elements when you use the auto animation type. The reason for this to achieve the illusion of continuous movement on a closed path. Here is how it works:

  1. The first text element starts at the beginning of the path and animates forward
  2. The second text element follows behind the first one at an offset
  3. When the first text reaches the end of the path, the second text has moved into position to continue the animation
  4. This creates the illusion of continuous movement without any visible jumps or gaps

This dual-text approach is necessary because animating a single text element would result in a noticeable "jump" when the animation resets back to the start position.

See an example of this in the first, and the following demo above:

loadingloadingloadingloadingloadingloadingloadingloading

This example above also demonstrates how to use the easingFunction prop to create more interesting animations. Please refer to the (mdn docs)[https://developer.mozilla.org/en-US/docs/Web/CSS/easing-function] on what values you can use.

Another important note here is that you have to experiment with the text length and size, to ensure the text doesn't overlap with each other, since it's not calculated automatically.

Preserve aspect ratio


The preserveAspectRatio attribute controls how the SVG content scales to fit its container when their aspect ratios differ. This is determined by comparing the viewBox dimensions to the actual SVG container size. For example, with preserveAspectRatio="xMidYMid meet", the path and text will be centered both horizontally and vertically while maintaining proportions.

Please refer to the MDN docs for the poossible values. In short, the default value xMidYMid meet will work for most cases. If you set it to none, the SVG container will be stretched to the container size, but will also result in a distortion of the text. Check out this behaviour on the first demo. Resize your viewport to see the difference.

Scroll


By setting the animationType prop to scroll, you can control the animation with the scroll position of the container. For tracking the scroll position, we use the useScroll hook from motion/react.

The relevant props are:

  • scrollContainer — a ref to the container element that the scroll animation will be driven by
  • scrollOffset — the scroll offset range for the animation
  • scrollTransformValues — The scrollYProgress value returned by useScroll hook ranges between 0 and 1, and this prop defines how we should map these values to the startOffset attribute of the text elements. It will be converted to percentage values.

Please refer to the motion docs for more details.

SCROLL DOWN

Information is expanding daily. How to get it out visually is important.The details are not the details. They make the design.There's no other product that changes function like the computer.Innovation is the outcome of a habit, not a random act.The only important thing about design is how it relates to people.Good design is obvious. Great design is transparent.

Notes


The performance impact of the animation increases with the length and complexity of the path, especially if you're using multiple instances, so keep an eye on it :).

Props


PropTypeDefaultDescription
path*string-The path to be animated
text*string-The text to be animated
pathIdstring-The ID for the path
pathClassNamestring-Additional CSS classes for the path
preserveAspectRatioPerserveAspectRatio"xMidYMid meet"The aspect ratio to preserve when scaling the SVG
showPathbooleanfalseWhether to show the path
widthstring | number100%The width of the SVG container
heightstring | number100%The height of the SVG container
viewBoxstring"0 0 100 100"The viewBox of the SVG container
svgClassNamestring-Additional CSS classes for the SVG container
textClassNamestring-Additional CSS classes for the text
textAnchor"start" | "middle" | "end""start"The text anchor of the text
animationType"auto" | "scroll""auto"The animation type
durationnumber4The duration of the animation in milliseconds
repeatCountnumber | "indefinite""indefinite"The number of times the animation should repeat
easingFunction{ calcMode?: string; keyTimes?: string; keySplines?: string }-The easing function for the animation
scrollContainerRefObject<HTMLElement>-The ref to the container element that the scroll animation will be driven by
scrollOffsetUseScrollOptions["offset"]["start end", "end end"]The scroll offset range for the animation
scrollTransformValues[number, number][0, 100]The scrollYProgress value returned by useScroll hook ranges between 0 and 1, and this prop defines how we should map these values to the startOffset attribute of the text elements. It will be converted to percentage values.