For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to any URL or sending an Accept: text/markdown header. The asciicn agent skill, for building any ASCII effect on the engine, is at /.well-known/agent-skills/asciicn/SKILL.md.

Glyph rain

Falling glyphs gather into a message, then fade and form again.

Controls
Message
Charset
Colour mode
Density0.5
Speed1×
Hold5s
Loop
Cell12px

Installation

pnpm dlx shadcn@latest add https://asciicn.dev/r/glyph-rain.json

Usage

import { GlyphRain } from "@/components/asciicn/glyph-rain";
 
export function Hero() {
  return (
    <section className="relative h-[480px]">
      <GlyphRain message="asciicn" className="absolute inset-0" />
      <h1 className="sr-only">asciicn</h1>
    </section>
  );
}

Each stream is one column of glyphs with a head and a trail. The head is drawn in accent, the cell or two behind it shade from the accent into color, and the rest of the trail fades out. Glyphs come from the charset in order of ink: dense ones near the head, faint ones at the tail. Every cell keeps its own glyph, and now and then one changes, so a trail flickers a little as it passes.

Without message the rain is ambient: streams start at random columns, fall at different speeds and start again at the top.

With message, the text is set in a built-in pixel font and scaled to fill most of the box. Each font pixel covers a whole number of quadrants, so every edge lands on a cell boundary and the letters stay crisp. When a stream's head crosses a cell of the message, that cell fills in behind it: first a dense glyph in the accent, then â–‘ â–’ â–“, then a solid block. While the message forms, most new streams fall through its columns, so you watch the letters being written. Cells no stream reaches fill in on their own after a few seconds.

The message holds for hold seconds, then wears away cell by cell, faster where a stream passes, and forms again after a short rest. With loop={false} it forms once and stays. Trails behind the message are dimmed so the letters read.

The font covers A to Z in both cases, the digits and ! " # & ' ( ) * + , - . / : < = > ? @ [ ] _ |. Other characters draw as ?.

Examples

Headline over a hero

The message is the headline. Keep it short: four to eight characters fill a hero at any width. Put the same words in a real heading for screen readers.

Ambient background

No message, a lower density and speed, and charset="braille", so each trail thins from full cells to single dots. The content sits on its own panel above the rain.

Props

PropTypeDefault
message

Text the rain settles into, in block letters. Line breaks start new lines. Without it the rain is ambient.

Type: stringDefault –
density

Share of columns with a stream falling at once, from 0 to 1.

Type: numberDefault 0.5
speed

Fall speed multiplier.

Type: numberDefault 1
hold

Seconds the finished message holds before it wears away.

Type: numberDefault 5
loop

Wear the message away and form it again, forever. false forms it once and keeps it.

Type: booleanDefault true
charset

Glyphs the rain falls in. latin is digits, letters and a few symbols. Any engine charset works, such as katakana or braille.

Type: "latin" | CharsetNameDefault "latin"
chars

Your own glyphs, faint to dense, such as ".:+*#". Wins over charset.

Type: stringDefault –
colorMode

truecolor: trails in color, heads and message in accent. mono: everything in color or the phosphor. duotone: by brightness along ramp.

Type: "truecolor" | "mono" | "duotone"Default "truecolor"
color

Trail colour, and every glyph in mono.

Type: AsciiColorDefault "--ascii-ink"
accent

Heads and the message in truecolor. The palette's amber.

Type: AsciiColorDefault "orange"
phosphor

mono: a CRT phosphor for the ink and the glass behind it.

Type: PhosphorNameDefault –
ramp

duotone: a ramp name or stops as #rrggbb.

Type: RampName | string[]Default "sodium"
background

transparent shows the page between glyphs. A phosphor or duotone paints its own glass unless this is transparent.

Type: "paper" | "transparent"Default "transparent"
fx

CRT effects, drawn as a CSS overlay.

Type: PostFxDefault –
cell

Glyph cell height in CSS pixels.

Type: numberDefault 12
fps

Frame rate cap.

Type: numberDefault 30
animate

false holds one still frame with the message complete.

Type: booleanDefault true
handle

Filled with a handle for export.

Type: RefObject<AsciiHandle | null>Default –

Notes

  • Each column falls at its own speed, with an amber head and a trail that fades through the charset. A column that crosses a cell of the message leaves that cell lit, so the words assemble out of the rain, hold, wear away and form again.
  • The canvas is decorative and hidden from assistive technology. Put the message in a real heading too, visible or sr-only.
  • The first frame already shows the message part written, so it never opens on a blank box.
  • Under reduced motion it draws one still frame: the finished message with rain around it. It pauses offscreen and in hidden tabs.
  • After a resize the message comes back whole at its new size.
  • A message too wide for the box at the smallest size runs off both sides. Use shorter words or a line break on narrow screens.