For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to any URL or sending an Accept: text/markdown header. The asciicn agent skill, for building any ASCII effect on the engine, is at /.well-known/agent-skills/asciicn/SKILL.md.

Torus knot

A lit 3D torus knot tumbling in glyphs, with p and q windings, a breaks-at-crossings outline and drag to turn.

Controls
Charset
Colour
Ramp (duotone)
p (around)2
q (through)5
Thickness0.13
Speed1×
Cell10px
Contours

Installation

pnpm dlx shadcn@latest add https://asciicn.dev/r/torus-knot.json

Usage

import { TorusKnot } from "@/components/asciicn/torus-knot";
 
export function Hero() {
  return (
    <section className="relative h-[520px]">
      <TorusKnot p={3} q={7} className="absolute inset-0" />
    </section>
  );
}

A torus knot is a closed curve drawn on the surface of a ring. It winds p times around the ring's axis and passes q times through its hole. When p and q share no common factor you get one knot, such as the trefoil at p={2} q={3}. When they do, you get a link of several loops.

The tube is a real 3D mesh. It is swept along the curve, projected in perspective and rasterised into a depth buffer at the charset's own sample grid, so Braille gets 2×4 samples per cell and quadrants 2×2. Each sample is lit from its surface normal: a key light sets the tone, a tight highlight reaches the densest glyphs, and a rim brightens the edges. Parts farther from the camera fade, which puts the near strands in front.

In truecolor the colour comes from colors, the site's orange, pink, purple and blue by default. With hue="film" it shifts with the surface angle like oil on water, so the colour slides over the tube as it turns. With hue="tube" it runs along the knot instead.

Where one strand crosses over another, the strand underneath breaks just short of the one on top, the way knots are drawn by hand. That keeps every crossing readable even in a coarse charset. With ramp charsets, contours traces the silhouette with - / | \ glyphs that follow the outline.

It turns slowly on its own axis and sways a little, so you see the knot near face on with its depth showing. It does not react to hover. Press and drag to tilt it. Let go mid-drag and it coasts, then stays where you left it. With keyboard focus, the arrow keys turn it.

Examples

Braille, coloured along the tube

hue="tube" lays the colors stops along the tube and loops back to the first, so you can follow one strand round the whole knot. Braille samples 2×4 dots per cell, which gives a (3, 4) knot a fine outline and an even dot shading.

A trefoil beside text

Mono with a transparent background takes your theme's ink, so the knot sits on the page like an illustration. interactive={false} makes it decoration only.

Props

Every ASCII image look prop also applies, with charset defaulting to "blocks", plus fx for a CRT finish.

PropTypeDefault
p

Times the tube winds around the central axis. Rounded to a whole number.

Type: numberDefault 2
q

Times the tube passes through the hole. Rounded to a whole number.

Type: numberDefault 5
thickness

Tube radius as a share of the knot's radius, 0.04 to 0.3.

Type: numberDefault 0.13
size

How much of the box's shorter side the knot spans, 0.3 to 1.

Type: numberDefault 0.86
spin

Turn around the knot's own axis, in radians per second.

Type: numberDefault 0.25
speed

Multiplies the spin and the slow sway. 0 holds it still.

Type: numberDefault 1
colors

Truecolor stops, looping back to the first.

Type: AsciiColor[]Default ["orange", "pink", "purple", "blue"]
hue

Lay the stops by surface angle, like oil on water, or along the tube.

Type: "film" | "tube"Default "film"
light

Where the key light comes from, in degrees clockwise from the top.

Type: numberDefault 320
contours

Ramp charsets draw - / | \ along the silhouette, following the outline.

Type: booleanDefault true
charset

Which glyphs draw the tones.

Type: CharsetNameDefault "blocks"
colorMode

How glyphs are coloured.

Type: "mono" | "truecolor" | "ansi16" | "duotone" | "palette"Default "truecolor"
interactive

Drag or use the arrow keys to turn it.

Type: booleanDefault true
cell

Glyph cell height in CSS pixels.

Type: numberDefault 10
animate

false draws one still frame.

Type: booleanDefault true
handle

Filled with a handle for export.

Type: RefObject<AsciiHandle | null>Default –

Notes

  • It is announced as an image whose label names the knot. Pass aria-label to describe what it stands for on your page.
  • Under reduced motion it draws one still frame. Dragging and the arrow keys still turn it.
  • It draws at up to 60 fps on the CPU and pauses offscreen and in hidden tabs. The mesh is built once per shape; each frame only transforms it and fills the samples it covers. Large boxes in Braille cost the most, so raise cell for a full-screen hero.