Handwriting Text
Handwriting animation drawn stroke by stroke with SVG pathLength, with a built-in single-line font and support for custom signature paths.
This is a WebberUI Pro component
Free during the launch campaign: sign up or sign in, then hit “Copy install command” in the preview above and it installs straight away — no payment, no credit card. The command below returns 401 while you are signed out.
npx shadcn@latest add "https://webberui.com/r/handwriting-text.json?t=<install token>"Playground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<HandwritingText />
Installation
npx shadcn@latest add "https://webberui.com/r/handwriting-text.json?t=<install token>"Or, once registries are configured in components.json, install it as @webberui/handwriting-text.
Usage
Pass text and it is drawn stroke by stroke in the built-in single-line font (the text is uppercased automatically):
import { HandwritingText } from "@/components/ui/handwriting-text";
<HandwritingText text="Webber" className="text-5xl font-medium" />To draw a signature or a script flourish, pass paths instead (an array of SVG path d strings) together with a viewBox:
<HandwritingText
paths={["M10 66 C 24 20 40 22 42 60 …", "M6 90 C 90 76 200 76 262 88"]}
viewBox="0 0 272 100"
label="Handwritten signature"
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
text | string | — | The text to draw, rendered in the built-in single-line font (uppercased automatically); use either this or paths |
paths | string[] | — | Custom SVG paths (an array of d strings); takes the place of text when provided |
viewBox | string | "0 0 100 100" | The viewBox for paths mode; in text mode it is computed automatically |
label | string | — | Text description exposed to assistive technology in paths mode |
duration | number | 0.7 | Duration of a single stroke (seconds) |
stagger | number | 0.18 | Interval between the starts of adjacent strokes (seconds) |
delay | number | 0 | Delay before the whole drawing starts (seconds) |
strokeWidth | number | 5 | Stroke width (in viewBox units) |
fill | boolean | false | Fade in a fill once drawing finishes, suited to closed paths; ignored when loop is on |
loop | boolean | false | Whether to redraw in a loop |
trigger | "view" | "hover" | "mount" | "view" | When the animation is triggered |
once | boolean | true | With trigger set to view, plays only the first time the element enters the viewport |
className | string | — | The outer container; in text mode size is controlled by font-size, in paths mode by width |
svgClassName | string | — | Applied directly to the <svg>, so the default size classes can be overridden |
How it works
- Size: in
textmode the<svg>is1emtall, so a font-size class liketext-5xlis enough to scale it; inpathsmode the width fills the container, so the outer width controls the size. - Color: the stroke uses
currentColor, so a text color class such astext-neutral-*colors it directly, and light and dark themes can each set their own. - Single-line font: A–Z, 0–9, and common punctuation are built in, with all letters uppercase; each glyph is broken into several strokes drawn in writing order. Glyphs that are not included are treated as blank spacing.
- Looping: with
loopon, all strokes share the same cycle, so a redraw keeps the original offset ordering and does not flicker out of sequence. - Triggering: with
trigger="hover"the container is focusable (tabIndex=0), so both a mouse enter and keyboard focus redraw it.
Accessibility
- When the user has "reduce motion" enabled at the system level, the finished drawing is shown statically with no animation.
- In
textmode the container carriesrole="img"and anaria-label, and keeps ansr-onlycopy of the text for the screen reader. - In
pathsmode, provide a text description throughlabel; when neithertextnorlabelis provided, the whole thing is hidden from assistive technology witharia-hidden.