KQ-1357 · PEN/OUTLINE

Pen Outline

A small nib travels the contour of every letter — outlines traced from the glyphs the browser actually rendered — while the stroke's dash offset grows under its tip, letter after letter, lifting between loops; when the last stroke closes, ink floods each letter from the bottom up behind a gentle wave on springs.drift, one after another. The pen runs on a linear clock (a hand at constant speed) that pauses off screen, and the flood is the real, selectable text clipped by a per-letter wave. Focused, Enter or Space drains the ink, rewinds the outline on the exit ease and writes it again.

KQ-1357 · PEN/OUTLINE

Fernworks · bottled ink no. 4

Written by hand

Press Enter to draw it again.

waiting · the nib is ready

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/pen-outline

Props

text
string
default —
The words the pen writes.
as
"h1" | "h2" | "h3" | "p" | "span" | "div"
default "p"
The element rendered.
speed
number
default 1
How fast the pen writes and the ink floods, 0.5 to 2.
stroke
number
default 1.25
Outline width, px.
flood
number
default 1
How much ink floods in once the outline closes: 0 leaves a pure outline, 1 is solid ink.
ink
string
default "var(--foreground)"
Outline colour, any CSS colour.
floodColor
string
default the ink colour
The colour the letters flood with.
guide
number
default 0.12
Opacity of the pencil guide shown before the pen arrives, 0 to 1.
wave
number
default 0.5
Height of the flood's wave front, 0 (flat) to 1.
nib
boolean
default true
Show the travelling nib; the box reserves a quarter em above and right for it.
keepOutline
boolean
default true
Keep the inked edge once the flood settles; false dissolves it into the fill.
trigger
"mount" | "inView" | "hover" | "manual"
default "inView"
What starts the drawing.
once
boolean
default true
Draw once; false rewinds when it leaves view or the hover ends.
play
boolean
default —
Manual trigger: true draws, false rewinds.
delay
number
default 0
Wait before the pen starts, ms.
duration
number
default 180
Time the pen spends on an average letter at speed 1, ms (a whole headline is capped at about three seconds).
stagger
number
default 55
Gap between the letters' floods, ms.
interactive
boolean
default true
A press, or Enter or Space while focused, erases and redraws.
onPhaseChange
(phase: "waiting" | "drawing" | "flooding" | "inked") => void
default —
The drawing moved on; reported from the first commit.
onComplete
() => void
default —
The ink has settled.
className
string
default —
Size, weight and tracking live here; the outline follows whatever font renders.