Installation
pnpm dlx shadcn@latest add https://asciicn.dev/r/ascii-text.jsonUsage
import { AsciiText } from "@/components/asciicn/ascii-text";
export function Hero() {
return (
<AsciiText as="h1" charset="braille" reveal="decode" className="font-bold">
Ship it
</AsciiText>
);
}AsciiText draws your text in the element's own font (family, weight and style come from its className) into an offscreen canvas at size pixels. It averages the coverage of every glyph sample, builds a tone field and maps it to glyphs with the engine's mapTones, the same mapping every asciicn renderer uses. The art is a <pre> of real characters, so it stays sharp at any zoom and you can select and copy it.
The charset sets the look. braille packs 2×4 dots into each cell and gives the smoothest large type. blocks and quadrants give chunky banners. standard and dense give classic character art. edge traces the letters' outlines with - / | \.
Examples
Duotone banner
blocks with colorMode="duotone" colours every glyph by its density along a ramp, here outrun. A line break in the text starts a second line.
Outlines
The edge charset runs a Sobel filter over the sampled type and draws a directional glyph wherever the edge is strong. Lower edgeThreshold picks up softer edges.
Reveal on hover
trigger="hover" shows the finished art and replays the reveal each time the pointer enters. Here each link wipes in from the left through quadrant glyphs. fit={false} keeps every label at the same size.
Props
| Prop | Type | Default |
|---|---|---|
| children The text to draw. Line breaks start new lines. | Type: string | Default – |
| as The element that holds the real text. | Type: "h1" | "h2" | "h3" | "h4" | "p" | "div" | "span" | Default "h2" |
| size Font size the type is drawn at, in CSS pixels, before it is sampled into cells. | Type: number | Default 96 |
| cell Glyph cell height in CSS pixels. Smaller cells draw finer type. | Type: number | Default 8 |
| charset Glyphs the type is drawn with: standard, dense, blocks, quadrants, braille, cp437, petscii, katakana, dots or edge. | Type: CharsetName | Default "braille" |
| chars A custom ramp from empty to dense, such as " .oO@". Wins over charset. | Type: string | Default – |
| colorMode mono draws every glyph in color. duotone colours glyphs by density along ramp. | Type: "mono" | "duotone" | Default "mono" |
| ramp The duotone ramp: mainframe, sodium, heliograph, infrared, outrun, orchid, glacier, ember, toxic or vapor. | Type: RampName | Default "mainframe" |
| color Glyph colour in mono mode: a palette name, a CSS variable name or any CSS colour. | Type: AsciiColor | Default "ink" |
| threshold Braille and quadrants: the coverage that lights a dot, 0 to 1. | Type: number | Default 0.5 |
| edgeThreshold Edge charset: gradient strength, 0 to 1, that draws a directional glyph. | Type: number | Default 0.22 |
| dither Ordered dithering between glyph levels. | Type: "none" | "bayer2" | "bayer4" | "bayer8" | "blue-noise" | Default "none" |
| reveal decode cycles inked cells through random glyphs until they settle. scan writes rows from the top. wipe writes columns from the left behind a ragged edge. | Type: "none" | "decode" | "scan" | "wipe" | Default "none" |
| trigger When the reveal plays. hover shows the finished art and replays the reveal on each pointer enter. | Type: "mount" | "view" | "hover" | Default "view" |
| duration Reveal length in seconds. | Type: number | Default 1.2 |
| fit Shrink the type to fit the container's width. | Type: boolean | Default true |
Other props pass through to the element.
Notes
- The real text is always in the element. It shows as plain type during server rendering and until the art is drawn, then becomes visually hidden, so screen readers, search engines and find-in-page read the words while sighted readers see the art. The art itself is
aria-hidden. - The art redraws when the element resizes and when web fonts finish loading, so it always uses the font you set.
- With reduced motion, the reveal is skipped and the finished art shows at once.
- Drawing is one canvas pass when the text, size or charset changes. Nothing runs per frame except during a reveal.