a1ui
6 new components shipped

ASCII Terrain

A landscape made of characters, with rolling hills, pointer sculpting, and click ripples.

Read agent guide

Demo

Move the pointer or use arrow keys to raise hills. Click, press Enter, or press Space to send a ripple. Home centers the hill. Escape releases it. Interactions stop while paused or when reduced motion is enabled.

Installation

pnpm dlx shadcn@latest add https://ui.arjayby1.xyz/r/ascii-terrain.json

Code

"use client";

import { useState } from "react";
import { AsciiTerrain } from "@/components/ui/ascii-terrain";

export function AsciiTerrainExample() {
  const [paused, setPaused] = useState(false);

  return (
    <div>
      <AsciiTerrain paused={paused} cellSize={10} amplitude={1} seed={7} />
      <button type="button" onClick={() => setPaused((value) => !value)} aria-pressed={paused}>
        {paused ? "Resume terrain" : "Pause terrain"}
      </button>
    </div>
  );
}

API reference

PropTypeDefaultPurpose
cellSizenumber10Character spacing in pixels, clamped to 6–24. Smaller values add detail.
amplitudenumber1Base hill height, clamped to 0–2. Pointer hills and ripples are independent.
speednumber1Terrain drift speed, clamped to 0–3. Zero stops drift while keeping interactions active.
seednumber7Reproducible starting landscape. Change it to create a different terrain.
charactersstring".:-=+*#%@"Up to 32 printable, non-space ASCII characters ordered from low to high elevation. Invalid or empty input uses the default ramp.
pausedbooleanfalseFreeze the current frame and disable interactions. Resume continues from the same animation time.
interactivebooleantrueEnable pointer, touch, and keyboard interaction. False removes the focusable control.
ariaLabelstring"ASCII terrain with rolling hills"Accessible description of the terrain.
classNamestringNoneOuter layout classes. The default height is 24rem.
styleCSSPropertiesNoneSet height, text color, or a loaded monospace font.

Move the pointer across the landscape to raise a hill. Click or tap to send a wave across it. Focus the terrain and use arrow keys to move the hill, Enter or Space to create a ripple, Home to return to the center, and Escape to release the hill. Touch scrolling stays available.

Include a pause control for automatically moving terrain, as in the example. Reduced motion shows a static landscape and disables sculpting and ripples. The animation also stops while offscreen, inside an inert catalog preview, or in a hidden browser tab. Use interactive={false} for decorative backgrounds and keep page content outside the canvas.

The component uses Canvas 2D and inherits text color and the monospace font. It needs ResizeObserver, IntersectionObserver, and JavaScript to draw; its accessible description is present in server-rendered HTML. It draws on each display frame with bounded character counts and canvas resolution. Hover hills ease toward the pointer, and click ripples build gradually before fading. It has no WebGL, image assets, or graphics library dependency. This is a procedural illustration, not a geographic map or terrain editor.