Installation
pnpm dlx shadcn@latest add https://asciicn.dev/r/dubai.jsonUsage
import { Dubai } from "@/components/asciicn/dubai";
export function Hero() {
return (
<section className="relative isolate min-h-[480px]">
<Dubai intensity={0.85} className="absolute inset-0 -z-10" />
<h1>Your headline</h1>
</section>
);
}The whole frame is painted in halftone dots. Each dot takes its own colour, and its size carries the light: the smallest dots in the deep blue at the top of the sky and in the shadows between the dunes, middle dots through the rose and violet, and the largest dots on the lit spire, the afterglow and the sunlit dune crests.
The sun has just set to the left, behind the desert. The sky runs from a hazy gold horizon through rose to deep blue, with thin clouds lit from below and the first stars overhead.
The Burj Khalifa rises far above everything else. Its wings step back in turn as it climbs, so the setbacks alternate sides, and it narrows to a long spire. The lower floors already stand in the blue of dusk with a few lit windows; above them the faces turned to the sunset are still gold and amber, and the far face takes rose from the sky. A red beacon pulses slowly on the tip. A cluster of towers stands round its foot in blue haze, with lit windows and warm edges on the side facing the light, and further towers fade into the haze along the horizon, where the city's glow lies.
In front, three rows of dunes run to the bottom of the frame. The faces turned to the sunset are rose and amber; behind each crest a violet shadow widens down the slip face. The far dunes are hazier and paler, and fine ripples cross the near one.
Motion is slow: the beacon pulses, a window turns on or off now and then, dust drifts over the dunes, thin clouds move and stars twinkle faintly. The pointer does nothing.
The Burj stands right of centre at every aspect, and the towers in the middle of the box stay low, so a centred headline sits over open sky. On a tall phone screen it stands near the right edge, beside the text rather than behind it.
It draws in dots by default on square 7px cells, so the dots lie in an even lattice, about 200 across a 1440px screen, with bayer4 dithering between dot sizes for smooth gradients. square={false} returns to the usual text cells, twice as tall as wide; braille and quadrants use them by default. Other ramp charsets such as standard or dense read the same tones as typed glyphs. In truecolor, the default, the scene paints its own dusk-blue paper in both themes. mono with a phosphor and duotone with a ramp read the same scene by tone alone.
intensity dims the colours in step and shrinks the dots more gently, so the shapes keep their place behind text.
Examples
Hero
intensity={0.85} quiets the scene a little behind a centred headline and two buttons. The Burj stays right of the text.
Duotone
colorMode="duotone" with a four-colour ramp from indigo to pale gold reads the dusk by tone alone, at cell={6} in a card.
Props
| Prop | Type | Default |
|---|---|---|
| intensity How strongly it draws, from 0 (faint) to 1. Lower it so text on top stays readable. | Type: number | Default 1 |
| charset Which glyphs draw the scene. See Charsets. | Type: CharsetName | Default "dots" |
| 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 scene's own colours, mono uses the theme ink or a phosphor, duotone runs tone through a ramp. "mono" when a phosphor is set. | Type: "mono" | "truecolor" | "ansi16" | "duotone" | "palette" | Default "truecolor" |
| phosphor A CRT ink and glass for mono mode. Setting one switches colorMode to mono. | Type: "p1" | "p3" | "ibm" | "blueprint" | Default – |
| ramp In duotone mode, the colour ramp from dark to light. | Type: RampName | string[] | Default "infrared" |
| 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 dot sizes. The default turns four dots into smooth tone. | Type: "none" | "bayer2" | "bayer4" | "bayer8" | "blue-noise" | Default "bayer4" |
| 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 – |
| cell Height of one glyph cell in CSS pixels. | Type: number | Default 7 |
| square Square cells, so the dots lie on an even lattice. false uses the font's narrower cells, the default for braille and quadrants. | Type: boolean | Default true |
| 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 0 |
| handle Filled with a handle that reads back the current frame, for export to text, ANSI, SVG or PNG. | Type: RefObject<AsciiHandle | null> | Default – |
| paper Paper behind the glyphs. By default the scene's dusk blue in truecolor, ansi16 and duotone, and the theme's paper (or the phosphor's) otherwise. | Type: AsciiColor | Default – |
| fallback Shown without WebGL and until the first frame. By default the dusk as a flat gradient. | Type: ReactNode | 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.
- It ignores the pointer: no parallax and no hover effect. An
interactiveprop passed by a gallery is accepted and ignored. - With reduced motion turned on, it draws one still frame at
stillTimeand stops. - 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 a flat dusk gradient.
- The whole scene is one shader pass on the GPU, with one short loop over the twelve towers round the Burj.
braillesamples eight times per cell andquadrantsfour; a largercellmakes it cheaper. See Performance.