Installation
pnpm dlx shadcn@latest add https://asciicn.dev/r/squall.jsonUsage
import { Squall } from "@/components/asciicn/squall";
export function Hero() {
return (
<section className="relative isolate min-h-[480px]">
<Squall seed="gale-9" className="absolute inset-0 -z-10" />
<h1>Your headline</h1>
</section>
);
}Each seed rolls a set of ribbons: how many, how they swing, how much slow noise bends them, how wide they are and how often they twist. A ribbon's width follows its twist, so where it turns edge-on it narrows to a bright line, like a strip of film turning in the light. Its rims are the brightest part, a soft halo surrounds it, and the ribbons further back sit a little dimmer. In truecolor each ribbon takes its own hue along the palette.
Squall runs from a muted teal to slate blue at low chroma. It rolls four or five heavy, deeply folded ribbons that drift steadily, like rain bands crossing a sky. It draws in the standard ramp by default.
Each seed gets its own palette, built in OKLCH: a first hue, then a turn of up to 120 degrees that never runs through the olive and khaki hues that turn muddy at glyph sizes. The palette comes in two versions, deep to bright on dark paper and pale to deep on light paper, and switches with the theme, so the densest glyphs always have the most contrast.
The parts are in lib/ascii/seed.ts (shipped with the ascii-shader item) if you want your own preset: seedParams(seed, kind, options) rolls the parameters, seedField(seed, kind) returns { field, colorField, uniforms } for AsciiShader, and the SeedField component wraps both.
Examples
Glacier duotone
The dense ramp read through the glacier duotone ramp.
Behind a headline
Half intensity drops the bands to the light end of the ramp under the text.
Props
| Prop | Type | Default |
|---|---|---|
| seed Any string. The same seed always draws the same field; each new one rolls a different shape, palette and motion in the same family. | Type: string | Default "squall" |
| intensity Scales the exposure the seed settled on, from 0 to 1.5. Lower it to put text on top. | Type: number | Default 1 |
| ink The glyph colour in mono mode. | Type: AsciiColor | Default "--ascii-ink" |
| paper The surface behind the glyphs. | Type: AsciiColor | Default "--ascii-paper" |
| palette Colours for palette mode, paper first. | Type: [AsciiColor, AsciiColor, ...AsciiColor[]] | Default Paper, then the seed's four colours |
| charset Which glyphs draw the tones. See Charsets. | Type: CharsetName | Default "standard" |
| chars A custom ramp from empty to dense, such as " .oO@". Wins over charset. | Type: string | Default – |
| colorMode How glyphs are coloured. truecolor uses the seed's own OKLCH palette; palette maps tone to it; mono, duotone and ansi16 work as everywhere else. | Type: "mono" | "truecolor" | "ansi16" | "duotone" | "palette" | Default "truecolor" |
| phosphor In mono mode, a CRT ink and glass that replace ink and paper. | Type: "p1" | "p3" | "ibm" | "blueprint" | Default – |
| ramp In duotone mode, the colour ramp from dark to light. | Type: RampName | string[] | Default – |
| ansi In ansi16 mode, which 16-colour table. | Type: "vga" | "xterm" | Default "vga" |
| grade Brightness, contrast, gamma and saturation applied to tones before glyphs are picked. | Type: Grade | Default – |
| invert Dense glyphs for dark tones instead of bright ones. | Type: boolean | Default false |
| threshold Braille and quadrants: the tone that lights a dot. | Type: number | Default 0.5 |
| edgeThreshold Edge charset: how strong a change in tone must be to draw - / | or \. | Type: number | Default 0.22 |
| dither Ordered dithering between neighbouring glyph levels. | Type: "none" | "bayer2" | "bayer4" | "bayer8" | "blue-noise" | Default "none" |
| background "transparent" draws the glyphs only, over your own surface. | Type: "paper" | "transparent" | Default "paper" |
| fx CRT finish: scanlines, bloom, curvature, glitch, flicker and vignette, each 0 to 1. | Type: PostFx | Default – |
| interaction What the pointer does to the glyphs. Off by default, so the field ignores hover; opt in only where a pointer effect suits the page. | Type: "none" | "repel" | "ripple" | "trail" | Default "none" |
| interactive false turns pointer interaction off whatever interaction says. | Type: boolean | Default true |
| cell Height of one glyph cell in CSS pixels. | Type: number | Default 12 |
| speed How fast it moves. | Type: number | Default 1 |
| animate false stops the motion: a still frame if it starts off, the current frame if it was moving. | Type: boolean | Default true |
| fps Frame rate cap. | Type: number | Default 30 |
| stillTime The moment drawn when motion is off or reduced, in seconds. | Type: number | Default 8 |
| handle Filled with a handle that reads back the current frame, for export to text, ANSI, SVG or PNG. | Type: RefObject<AsciiHandle | null> | Default – |
| className Size and position. The background fills this box. | Type: string | Default – |
Notes
- It is decorative and hidden from assistive technology. Put real text on top of it, not inside it.
- With reduced motion turned on, it draws one still frame at
stillTimeand stops. - By default it does not react to the pointer: moving the mouse over it changes nothing.
- It pauses when scrolled out of view or when the tab is hidden, and releases its WebGL context when far offscreen. Without WebGL it shows soft CSS glows in the seed's colours.
- A seed is rolled once, on the CPU, in a few milliseconds: a small exposure check samples the field at 40×22 at three moments and re-rolls (up to eight times) until between a quarter and three fifths of the box carries a glyph, then sets the gain so the brightest glyphs reach the top of the ramp. Changing
seedre-rolls; changing the look props does not. See Performance.