Line Boil
A hand-drawn outline draws itself, boils on threes like a cel animation, and fills with color while it keeps boiling
$ pnpm dlx shadcn@latest add @remocn/line-boilUsage
LineBoil is a full-frame scene. It draws a closed outline with a pen that
tapers in and out and varies its pressure along the stroke, then fills the
shape with color. The line never sits still. Like a cel animation shot "on
threes", the whole drawing is retraced every few frames with a slightly
different wobble, cycling through a small set of drawings.
import { LineBoil } from "@/components/remocn/line-boil";
export const Star = () => <LineBoil />;Pass path to draw your own shape. It takes SVG path data in any coordinate
space. The outline is sampled at 160 points along its length, scaled so its
longer side is size of the frame's short side, and centered. Use one closed
outline: separate subpaths and holes are joined into one continuous stroke.
import { LineBoil } from "@/components/remocn/line-boil";
const heart =
"M 50 88 C 20 66 4 48 4 30 C 4 14 16 4 30 4 C 40 4 47 10 50 18 C 53 10 60 4 70 4 C 84 4 96 14 96 30 C 96 48 80 66 50 88 Z";
export const Heart = () => (
<LineBoil
path={heart}
line="#1C1A17"
fill="#FF8FB1"
background="#FFF6E9"
boilEvery={2}
/>
);The fill boils with its own seed and a stronger wobble than the line, so the color slips a little past the outline the way a cel fill does.
Timing
At 30 fps and speed={1}:
| Frames | Motion |
|---|---|
| 0–22 | The pen draws the outline along the path on an ease-in-out, with tapered ends |
| 28–40 | The fill grows from the shape's center with a small overshoot |
| 40+ | The finished drawing keeps boiling |
lineBoilLength is 40, the frame the fill lands. The boil runs from frame 0
and never stops: a new drawing every boilEvery frames, cycling through
drawings variations. speed scales the draw, the fill and the boil rate
together.
| Prop | Type | Default | Description |
|---|---|---|---|
path | string | 5-point star | Closed outline as SVG path data in any coordinate space, fitted to the frame |
boilEvery | number | 3 | Frames each drawing holds before the next one |
drawings | number | 3 | Number of distinct drawings the boil cycles through |
amplitude | number | 1 | Wobble strength; 1 is a gentle hand-drawn boil, 0 is a steady line |
strokeWidth | number | 9 | Base line weight in px at 720p; pen pressure varies it along the stroke |
size | number | 0.66 | Size of the shape's longer side as a fraction of the frame's short side |
line | string | "#111111" | Outline color. Overrides colors.line when set |
fill | string | "#E5322D" | Shape fill. Overrides colors.fill when set |
background | string | "#FFFFFF" | Background color. Overrides colors.background when set |
colors | { line?: string; fill?: string; background?: string } | { line: "#111111", fill: "#E5322D", background: "#FFFFFF" } | The same colors as one object; the flat props above take precedence, missing keys keep their defaults |
speed | number | 1 | Playback multiplier |