Installation
pnpm dlx shadcn@latest add https://asciicn.dev/r/new-york.jsonUsage
import { NewYork } from "@/components/asciicn/new-york";
export function Hero() {
return (
<section className="relative isolate min-h-[480px]">
<NewYork intensity={0.6} className="absolute inset-0 -z-10" />
<h1>Your headline</h1>
</section>
);
}The view looks west at Manhattan from Brooklyn just after sunset. The sky runs from amber on the horizon through coral and violet to a deep blue that is almost the paper, with the afterglow low on the west side, behind the rooftops. The landmarks stand clear of the middle, where a headline goes: One World Trade Center to the west, its glass catching the afterglow on one side, and the Empire State Building to the east, its top floors floodlit gold under a lit crown, mast and antenna, with the Chrysler Building's arched crown outlined in white beside it. Between them the low Village and three rows of towers behind fade into the dusk haze, each row paler, flatter and smaller in its dots than the one in front. On a tall phone the landmarks shrink a little so all three stay beside the headline.
Windows light the skyline in warm lamp light, amber and a few cool office tubes, varied per tower and per floor. The river mirrors the city in long, broken streaks, the landmarks' lights run down it in columns to the bottom of the frame, and a glitter path lies under the afterglow.
The buildings never move. A few windows fade on or off at a time, each on its own clock of one to two minutes. The reflections shimmer, the spire lights breathe, a few stars twinkle, thin clouds drift and a ferry crosses in about three minutes. Nothing follows the pointer.
It draws in dots on square 7px cells by default, about 200 columns across a wide screen, so the dots lay an even halftone lattice and dot size carries tone: the deep sky and the dark facades are the smallest dots in a colour close to the paper, mid tones are small and medium dots, and only the lit crowns, windows and the afterglow get the large ones. In truecolor, the default, every dot takes its own colour on the scene's dusk navy, so it looks the same on light and dark pages. braille and quadrants want square={false}, and draw only the brighter parts, as outlines and lights. mono with a phosphor and duotone with a ramp read the same scene by tone alone.
Examples
Hero
intensity={0.6} dims the city so a centred headline and buttons read first, and the skyline still shows around them.
On a green monitor
colorMode="mono" with phosphor="p1" draws every dot in one green, and fx scanlines, bloom and vignette finish the look.
Props
| Prop | Type | Default |
|---|---|---|
| intensity How strongly the city draws, from 0 to 1. Lower it to keep text on top readable. | Type: number | Default 1 |
| windows Share of windows lit across the skyline, from 0 (dark) to 1. A few windows change at a time, each on its own slow clock. | Type: number | Default 0.55 |
| ferry The ferry crossing the river, once every three minutes or so. | Type: boolean | Default true |
| square Cells as wide as they are tall, so the dots lay an even halftone lattice. false uses the font's narrow cells. | Type: boolean | Default true |
| paper The surface behind the glyphs. Without it, truecolor, ansi16 and duotone sit on the scene's dusk navy; mono and palette use the theme's paper or the phosphor's. | Type: AsciiColor | Default – |
| fallback Shown without WebGL and until the first frame. | Type: ReactNode | Default a gradient |
| charset Which glyphs draw the tones. 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 paints the scene's own colours; mono uses one ink or a phosphor; duotone runs tone through a ramp. | Type: "mono" | "truecolor" | "ansi16" | "duotone" | "palette" | Default "truecolor" |
| phosphor A CRT ink and glass. Setting one switches the default colour mode to mono. | 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 – |
| cell Height of one glyph cell in CSS pixels. | Type: number | Default 7 |
| 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 30 |
| 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.
- The buildings never move and nothing reacts to the pointer. Only window lights, the spire lights, stars, clouds, the reflections and the ferry change.
- With reduced motion turned on, it draws one still frame at
stillTime, with the ferry on the river, and 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 gradient in the same colours.
- The whole city is one shader pass on the GPU. The river reads the skyline three times to mirror it and stretch its lights, so a water cell costs about three sky cells.
braillesamples eight times per cell, so it costs the most. See Performance.