# ASCII Background

> Eleven animated fields for heroes and sections, from plasma and starfield to a synthwave grid.

Category: Backgrounds. Docs: https://asciicn.sumak.dev/docs/ascii-background

## Installation

```bash
npx shadcn@latest add @asciicn/ascii-background
```

Needs the `@asciicn` registry in components.json: `"registries": { "@asciicn": "https://asciicn.sumak.dev/r/{name}.json" }`.

## Usage

```tsx
import { AsciiBackground } from "@/components/ascii/ascii-background"

export function Hero() {
  return (
    <section className="relative isolate">
      <AsciiBackground
        variant="topography"
        className="absolute inset-0 -z-10 text-primary/50"
      />
      <h1>Hello</h1>
    </section>
  )
}
```

## Examples

### Pointer ripple

`variant="ripple"` centres the rings on the pointer while it is over the canvas, and drifts back to the middle when it leaves.

```tsx
<div className="relative h-64 overflow-hidden rounded-xl border">
  <AsciiBackground variant="ripple" className="absolute inset-0 text-primary" />
</div>
```

### Behind a card

A faint `clouds` field behind content. Keep the alpha low (`text-primary/30`) so text stays readable, and mask the edges with a gradient.

```tsx
<div className="relative isolate overflow-hidden rounded-xl border p-6">
  <AsciiBackground
    variant="clouds"
    fontSize={10}
    className="absolute inset-0 -z-10 text-primary/30 [mask-image:linear-gradient(to_bottom,black,transparent)]"
  />
  <h3>Pro</h3>
  <p>$12 / month</p>
</div>
```

### Retro grid

`variant="grid"` scrolls a perspective floor towards the viewer with its horizon at 40% height. Put the heading above the horizon, where only a faint glow sits, and map tone onto `palettes.sunset` so near lines glow hot and far ones fade to violet.

```tsx
import { palettes } from "@/lib/ascii"

<section className="relative isolate h-80 overflow-hidden rounded-xl bg-zinc-950">
  <AsciiBackground variant="grid" color={palettes.sunset} className="absolute inset-0 -z-10" />
  <h2 className="pt-14 text-center font-mono text-2xl font-bold tracking-[0.3em] text-white sm:text-4xl">
    NIGHT DRIVE
  </h2>
</section>
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `variant` | `"plasma" | "topography" | "clouds" | "ripple" | "tunnel" | "rain" | "starfield" | "metaballs" | "grid" | "waves" | "aurora"` | `"plasma"` | Which field to draw. Ripple follows the pointer. |
| `speed` | `number` | `1` | Time multiplier. |
| `opacity` | `boolean` | `true` | Fade glyphs by tone. |

Also accepts every `AsciiCanvas` prop:

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `charset` | `CharsetName | string` | `"standard"` | Named ramp or your own string, empty to dense. "braille" packs 2×4 dots per cell, "quadrants" 2×2 blocks. |
| `fontSize` | `number` | `12` | Cell size in CSS pixels. Smaller means more detail. |
| `dither` | `"none" | "bayer" | "floyd"` | `"none"` | Quantisation. Floyd–Steinberg for photos, Bayer for a retro look. |
| `color` | `"ink" | "source" | string[]` | `"ink"` | Ink uses the CSS colour (theme with text-*). Source keeps pixel colours. An array maps tone onto gradient stops, e.g. palettes.thermal. |
| `edges` | `number` | `0` | Outline contours with | / - \ where the tone gradient beats this strength. Try 0.3. Ramps only. |
| `opacity` | `boolean` | `false` | Fade each glyph by its tone. |
| `brightness` | `number` | `0` | Added after contrast, -1 to 1. |
| `contrast` | `number` | `1` | Multiplier around mid grey. |
| `gamma` | `number` | `1` | Tone curve exponent. |
| `invert` | `boolean` | `false` | Swap ink and blank. |
| `animate` | `boolean` | `auto` | On for fields, frames and video. Off under reduced motion, except video. |
| `fps` | `number` | `30` | Frame cap. |
| `ref` | `Ref<AsciiHandle>` |  | Exposes text(), svg(), png() and the canvas. |

## Notes

- **Accessibility.** Rendered with `aria-hidden` and `pointer-events: none`, so it never steals focus or clicks from what sits on top.
- **Motion.** Animation pauses offscreen and in hidden tabs. Under `prefers-reduced-motion` it freezes on the current frame.
- **Theming.** Glyphs take the CSS `color`, so `text-primary` or `text-foreground/40` themes them. Theme changes repaint at once.
- **Performance.** Glyphs are stamped from a pre-rendered atlas onto one canvas, capped at 30 fps. Export with `ref.current.text()`, `svg()` or `png()`.
