# ASCII Globe

> A rotating planet with lit continents, drawn in characters.

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

## Installation

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

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

## Usage

```tsx
import { AsciiGlobe } from "@/components/ascii/ascii-globe"

<AsciiGlobe className="aspect-square w-80 text-primary" />
```

## Examples

### Braille

Braille packs 2×4 dots into each cell, so coastlines come out far finer. Each dot is on or off, so add `dither="bayer"` to keep the faint ocean and the shading across the terminator.

```tsx
<AsciiGlobe charset="braille" dither="bayer" graticule={false} className="aspect-square w-72 text-primary" />
```

### Water world

`land` sets the share of the surface above sea level and `seed` picks another map. Moving the `light` to the side sweeps the terminator across the disc.

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

<AsciiGlobe
  land={0.2}
  seed={4}
  light={[0.9, 0.3, 0.5]}
  color={palettes.cyanotype}
  className="aspect-square w-72"
/>
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `speed` | `number` | `1` | Rotation speed multiplier. 1 is one turn every 25 seconds. |
| `tilt` | `number` | `23.5` | Axial tilt in degrees. |
| `graticule` | `boolean` | `true` | Draw latitude and longitude lines every 30°. |
| `land` | `number` | `0.35` | Share of the surface that is land, 0 to 1. |
| `seed` | `number` | `0` | Picks a different set of continents. |
| `light` | `[x, y, z]` | `[-0.5, 0.45, 0.75]` | Light direction in view space: x right, y up, z towards the viewer. |

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

- **Continents.** Value-noise fbm is sampled at each point's 3D position on the sphere, so there is no seam at the date line and no pinching at the poles. Lighting stays fixed to the viewer while the planet turns under it.
- **Accessibility.** Labelled "Rotating ASCII globe" with `role="img"`. Pass `aria-label` to describe what it stands for, or `aria-hidden` when it is decoration.
- **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()`.
