Skip to content
WANCRAFT

C.164Typography & Text

Stroke Draw Text

Display text drawn as a self-tracing outline, letter by letter, that then fills in.

NewReactSVGTailwindintermediate

Overview

Stroke Draw Text renders a headline as SVG text and traces each letter's outline with an animated stroke-dasharray / dashoffset, staggered across the word, before the fill fades in. Every glyph is its own <tspan> with its own Web Animation. SVG has no getTotalLength for text, so the contour length is estimated from each letter's advance (getComputedTextLength) and the dash is removed as each letter finishes, so long contours are never left clipped. The viewBox is fitted to the measured text after webfonts load, so the word scales with its container like an image while keeping the page's font. It can draw when scrolled into view, on mount, or stay drawn and redraw on hover. The text is exposed once to assistive tech; reduced motion shows it filled immediately.

01Installation

Method 01 · Registry

CLI verified

Uses the shadcn CLI in a project initialised with shadcn init. Installs the file to components/ui/stroke-draw-text.tsx and adds its dependencies.

npx shadcn@latest add https://wancraft.my/r/stroke-draw-text.json

Method 02 · Copy and paste

  1. 1. No extra dependencies — React and Tailwind CSS only.
  2. 2. Copy the source from the Code tab into components/ui/stroke-draw-text.tsx.
  3. 3. Import it and adjust props.
Dependencies
None
Peer
react ≥ 18, tailwindcss ≥ 4
Added
13 Oct 2026
Updated
—

02Usage

The default configuration. Change properties above to generate a tailored example in the Usage tab.

example.tsx
import { StrokeDrawText } from "@/components/ui/stroke-draw-text";

export function StrokeDrawTextExample() {
  return (
    <StrokeDrawText as="h2" className="max-w-xl font-bold">
      Draftsman
    </StrokeDrawText>
  );
}

03Props

PropTypeDefaultDescription
childrenstring—Required. The display text (one line).
as"h1" | "h2" | "h3" | "p" | "div" | "span""div"Element to render.
trigger"view" | "hover" | "mount""view"Draw once in view, immediately, or show drawn and redraw on hover.
durationnumber1400Time for one letter's outline to draw, in ms.
staggernumber80Delay between consecutive letters, in ms.
strokeWidthnumber1.5Outline width relative to the glyphs (1 = 1% of the font size).
fillbooleantrueFade the fill in after the outlines are drawn.
accentstring"#FF7448"Outline colour. The fill uses the current text colour.
trackingnumber-0.02Letter spacing in em inside the SVG.

04Features

  • 01Per-letter <tspan> outlines animated with stroke-dashoffset via the Web Animations API, staggered
  • 02Contour length estimated from getComputedTextLength; the dash is cleared when each letter finishes
  • 03Optional fill that fades in as the last letters complete
  • 04Triggers: in view (IntersectionObserver, once), on mount, or drawn-with-hover-redraw
  • 05viewBox fitted to the measured text after fonts load, so it scales like an image in any container
  • 06Uses the page's font family, weight and colour; server markup starts undrawn so nothing flashes
motion · staggermotion · tweeninput · viewportinput · hover

05Accessibility

  • The text is rendered once in a visually hidden span; the SVG drawing is aria-hidden and not focusable.
  • The `as` prop keeps document structure (e.g. an h2 headline).
  • Hover mode starts fully drawn, so nothing depends on hovering; the redraw is decorative.
  • prefers-reduced-motion shows the finished, filled text immediately.

06Limitations

  • Single line only; the word scales to the container width rather than wrapping.
  • Contour lengths are estimated, so the drawing pace varies slightly between glyphs.