Skip to content
animorio
IT
All components

The ASCII menu

Menus, Text, Transitions, HoverCanvas, GSAPAdvancedCompressed weight: Demo 10 KBGSAP 28 KBFreeDownload the zip

The full-screen menu of a studio that makes tools for developers, written in characters: pressing Menu, a wave of characters runs out of the button across the screen and, where it passes, leaves the links in big letters made of small ones, each chosen for its shape.

The code

A folder that runs on its own: index.html, style.css, script.js and the libraries from a CDN. The React and Vue tabs hold the same demo as a ready component, which switches its animations off when it leaves the page.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>The ASCII menu</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/jetbrains-mono@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the full-screen menu of a small studio that makes tools for developers, set in characters. At rest only a
         Menu button. Pressed, a wave of characters runs out of the button across the screen and, where it has passed,
         the links are left drawn in big letters made of small ones: every character is chosen for its shape, so the
         slashes follow the diagonals and the bars the straight strokes -->
    <div class="term" data-frame>
      <canvas class="term__screen" aria-hidden="true" data-screen></canvas>

      <nav class="term__menu" id="ascii-menu" aria-label="Main" data-menu inert>
        <ul class="term__list">
          <li><a class="word" href="#work" data-word data-note="selected work">Work</a></li>
          <li><a class="word" href="#tools" data-word data-note="open source" aria-current="page">Tools</a></li>
          <li><a class="word" href="#notes" data-word data-note="essays, changelogs">Notes</a></li>
          <li><a class="word" href="#studio" data-word data-note="people and place">Studio</a></li>
          <li><a class="word" href="#contact" data-word data-note="say hello">Contact</a></li>
        </ul>
      </nav>

      <button class="key" type="button" aria-expanded="false" aria-controls="ascii-menu" data-toggle data-autoclic>
        <span class="key__word" aria-hidden="true" data-key-word>Menu</span>
        <svg class="key__icon" viewBox="0 0 16 12" aria-hidden="true">
          <path data-key-line d="M1 2h14"/>
          <path data-key-line d="M1 6h14"/>
          <path data-key-line d="M1 10h14"/>
        </svg>
        <span class="sr" data-toggle-name>Open the menu</span>
      </button>
    </div>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
  <script src="script.js"></script>
</body>
</html>

Playground

Change values, colours and text with the controls and watch the animation respond live. Or write in the code yourself. Then download the folder with your changes.

20 values to change

Or ask Claude Code for it

With the Animorio connector, Claude Code takes it from here, guide included, and fits it into your project. Paste this request:

Take “The ASCII menu” from Animorio and fit it into my site

What it does

On a black page there is only a dark button, «Menu» in a monospaced typeface with three lines. Pressed, the button glides to the top right corner and its word becomes «Close» through random characters, while the three lines shorten into steps. A wave of characters starts from the button and runs across the screen: every place flickers for an instant and settles, and where the wave has passed the links are left, WORK, TOOLS, NOTES, STUDIO and CONTACT, in letters six lines tall made of small characters: the dashes, bars, brackets and hashes follow the shape of the letters. Beside each one there is a grey note, and a few faint crosses mark the grid. The page you are on, TOOLS, is orange. Under the pointer the empty places stir in a small field; the link pointed at flickers in orange from where the pointer came in and the others dim. From the keyboard the link has crop marks round it, drawn in characters. Choosing a link it is inverted on an orange block, then the wave runs back and the characters disappear towards the button, which goes back to the middle. It also closes with Esc or with the button.

How it works

The shape of every character

At the start every character of the set (dots, dashes, bars, brackets, hash…) is drawn on a hidden canvas and its coverage measured in six zones: two across and three down. They are six numbers from 0 to 1 that say where the character has ink: the slash / top right and bottom left, the underscore only at the bottom.

The big letters, place by place

The links are written in capitals, weight 800, on another hidden canvas three times finer than the grid, TALL lines high. For every place of the grid the same six zones are measured and the character most like them is chosen (the distance between the six numbers, with full ink brought to the coverage of the densest character). So the diagonal edges become slashes, the straight strokes brackets and the inside hashes.

The wave

Every place knows how far it is from the button: the wave reaches it after distance / SPEED seconds, plus a touch of chance. For SCRAMBLE seconds the place shows random characters (they change 24 times a second, from a hash of the place and the time), then its final one; empty places flicker only in part (GLITTER). Closing it is the same the other way round, from the farthest place to the button.

The pointer

In the empty places within LENS pixels of the pointer characters from a density scale appear, thicker near it, fading in less than a second when it stops. The link pointed at flickers again from the column where the pointer came in, the farther columns later, and the others turn grey.

Real links over the drawing

The links are real links, transparent, laid over the box of their word. The keyboard focus draws crop marks with the characters + - |; the arrows go from link to link, Tab goes round the button and the links, Esc closes and the focus goes back to the button. The canvas is drawn again only while something moves.

Values to change

NameFileDefaultWhat it changes
SPEEDscript.js950How fast the wave of characters runs, in pixels per second.
SCRAMBLEscript.js0.24The seconds a character flickers before it settles.
TALLscript.js7How many lines tall a big word is at most (it lowers itself when it does not fit).
WEIGHTscript.js800The weight of the letters the big words are cut from (100 to 800).
LENSscript.js64The radius of the field of characters the pointer stirs, in pixels.
GLITTERscript.js0.45How many empty places flicker as the wave goes by (0 none, 1 all).

Try them in the Playground

When to use it

For the site of a development studio, a tool for programmers, a technical app or a portfolio that wants a strong character. It works with a few short links, up to five or six: the big words need room.

On phones

The grid is rebuilt to the width of the screen and the big words lose a line so they fit; the wave still starts from the button in the corner. A tap chooses the link; the field that follows the pointer follows the finger too.

With reduced motion

No wave and no flickering characters: the links fade in already written, and the button goes to its corner without gliding. The links pointed at light up and the others dim as always, without flickering.

Pitfalls

  • With every character of the keyboard (@, $, &, M, W) the big letters filled with different symbols and turned into noise: the set was cut to those with a clean shape, and the densest, the hash, fills the inside.
  • The top of the letters reached a hair into the line above and left a row of dots: now only the lines of the word are read.
  • Words four lines tall could not be read: the grid moved to smaller characters (9.5 pixels on 10 pixel lines), so the words have six or seven lines and the letters are letters again.
  • The characters must be measured after the typeface has arrived (document.fonts.load): before that the canvas uses a fallback typeface, and shapes and widths are wrong.
  • The button went back to the middle while the wave was still running back into its corner: now it leaves only when the last character has gone.

Libraries

GSAP 3.15.0, JetBrains Mono (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 10 KB; the libraries: GSAP 28 KB.

Testing

Tested on 19 October 2026

  • Desktop: Done
  • Phone: Done
  • Reduced motion: Done
  • Safari on iPhone: To do

License

Use it in your own projects and in your clients’ projects. Do not resell it or redistribute it as is. GSAP stays under its own Standard license. Full license.

All components