Skip to content
animorio
IT
All components

The mechanical key button

Buttons, 3D, Physics, SVGGSAP, CanvasAdvancedCompressed weight: Demo 15 KBGSAP 28 KBFreeDownload the zip

A big mechanical keyboard key in 3D, on a small aluminium block with a band of smoked acrylic: the sculpted keycap takes the light of a lamp that follows the pointer and has its own contact shadow. Pressed, it goes down the travel of a simulated switch, with the tactile bump halfway; when it clicks, a wave of RGB light runs out from the middle, through the well, the band and out round the block. The Enter key of the real keyboard presses it too, and it starts a deploy.

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 mechanical key button</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/space-grotesk@5.3.0/index.css">
  <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 mechanical key: one big keycap on a little aluminium pad, seen from above the desk. Pressed, it travels
         down on a switch with a tactile bump, clicks halfway, and the lights under the smoked acrylic ripple out from
         it. The Enter key of the real keyboard presses it too -->
    <div class="deploy" data-deploy>
      <div class="pad" data-pad>
        <canvas class="pad__desk" aria-hidden="true" data-leds></canvas>
        <svg class="pad__case" aria-hidden="true" data-case></svg>
        <span class="pad__shadow" aria-hidden="true" data-shadow></span>
        <svg class="pad__cap" aria-hidden="true" data-cap></svg>
        <span class="key__legend" aria-hidden="true" data-legend>Deploy</span>
        <span class="key__front" aria-hidden="true" data-front><svg viewBox="0 0 24 24"><path d="M19 5v7.5H6M10 8.5l-4 4 4 4"/></svg>Enter</span>
        <!-- the real button: a transparent area over the keycap -->
        <button class="key" type="button" aria-label="Deploy to production" aria-describedby="deploy-status" data-key data-autoclic></button>
      </div>

      <!-- what the key is doing, and how to press it -->
      <div class="status" id="deploy-status" data-rise>
        <span class="status__text" data-status>Ready to deploy</span>
      </div>
      <p class="hint" data-rise><span data-hint>Press the key, or hit <kbd>Enter</kbd> on your keyboard</span></p>
      <p class="sr" aria-live="polite" data-live></p>
    </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.

26 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 mechanical key button” from Animorio and fit it into my site

What it does

On a black background a macropad seen three quarters from above: a grey aluminium block with a polished edge, a band of smoked acrylic at the bottom and one big cream keycap, sculpted (narrower at the top, with a dish), with Deploy on top and a small arrow with ENTER on the front; below, the line Ready to deploy and the hint Press the key, or hit Enter on your keyboard. In the well and in the band a faint rainbow slowly turns, spilling a little round the block. Moving the mouse, the lamp's light follows it: the reflections on the keycap and on the edge move, the camera turns a little and the key's shadow moves the other way. Pressed, the key goes down: it hangs for an instant on the tactile bump, then snaps all the way down and the block jolts by a pixel. As it snaps the well flashes white and a wave of colour sets off from the middle: it lights the keycap from below, runs along the band and spreads round the block as a ring of light. Below, the line turns orange and says Building, Uploading and Going live with the percentage, while a blue and violet light fills the band going round the block and the hint says Press again to cancel. At the end a green wave, the band and the well turn green, the key shows a tick with Live and the green line Live on production; after a few seconds Deploy comes back. Pressing during the deploy, the wave is red and the red line says Deploy cancelled. With the Enter key of the keyboard the key goes down and stays down while Enter is held.

How it works

A 3D model in SVG

The block and the key are a small model: rounded rectangles at several heights (the floor of the well, the top of the block, the keycap's base and top), with six segments per corner. A camera raised 46 degrees and turned 0.3 radians projects the points with a touch of perspective, and every frame the script rewrites the SVG paths: the walls between two rings of points, the block's top with its hole (fill-rule evenodd), the chamfered edge. The faces turned away, told by the way they wind on the screen, are not drawn.

Light and shadows

Each face takes its colour from the CSS and its light from a lamp: an ambient light stronger towards the top, the diffuse light by the angle to the lamp and a highlight towards the camera, with a different material for the keycap, the aluminium, the polished edge and the well. The lamp follows the pointer over the block and the camera follows it a little; the keycap's top is a dish, shaded at nine stops. The contact shadow is a blurred rectangle laid on the block's top with a matrix, sharper and closer the further the key goes down.

The simulated switch

The travel is a number from 0 to 1 moved by a force: the finger pushes with a force that grows quickly, the spring answers from a preload, and a bump (a gaussian, steep after its peak, of strength BUMP) resists a third of the way down. So the key hesitates on the bump and then snaps; halfway the switch actuates and starts the action, at the bottom there is a hard stop with a tiny bounce. The physics takes six steps per frame, with the step capped at 1/30 of a second, and a short press still goes all the way to the click.

The RGB wave

The light at each point is a function of its distance from the middle, measured in key widths: each click adds a ring moving out at WAVE widths per second and leaving a little light behind it. The same function colours the well (a radial gradient and a glow round the keycap), the acrylic band, cut into 14 pixel slices so the colour runs along it, and the desk, a half resolution canvas under the block with blobs of light added together and the ring spreading out.

The words on the keycap

Deploy and ENTER are real HTML text, laid on the faces with a matrix: the script projects one model pixel along the face and one down its slope, and those two vectors are the columns of the CSS matrix(). The words stay sharp, follow the perspective and go down with the key; the real button is a transparent area over the keycap.

Keyboard, finger and the deploy

Enter presses the key from anywhere on the page (Space when the key has the focus), and it stays down while the real key is down; a click with no press (a screen reader, the preview) takes it down and up by itself. The pretend deploy is a timeline in fits and starts of DEPLOY seconds that fills the band going round; a press during the deploy cancels it with a red wave, the library's preview never cancels.

Values to change

NameFileDefaultWhat it changes
TRAVELscript.js24How far the key goes down, in pixels (4 mm on a real keyboard).
STIFFscript.js2000How hard the switch's spring pushes back.
BUMPscript.js0.9How strong the tactile bump halfway down is (0 = a smooth, linear switch).
WAVEscript.js2.4How fast the light wave runs out from the key, in key widths per second.
HUEscript.js18The colour the wave starts from, as a hue: 0 red, 120 green, 240 blue.
DEPLOYscript.js3.4The seconds of the pretend deploy.
DONEscript.js2.8The seconds the key says Live before it is ready again.
LIGHTscript.js1How much the lamp follows the pointer (0 = it stays where it is).

Try them in the Playground

When to use it

For the action that matters in a tool for developers or creatives: Deploy, Run, Publish, Ship, Record. It works on its own, on a dark background, in a control panel or on the launch page of a product for keyboard lovers; the Enter key pressing it makes it natural wherever the action is launched from the keyboard.

On phones

The drawing scales to the width of the screen (at 390 pixels the block is about 350 wide) and nothing spills over. The finger presses the key and holds it down while it rests, the lamp goes where it touches; the line below does not mention the Enter key.

With reduced motion

The key does not travel: it is down while pressed and up as soon as it is released, with no spring and no jolt. The lamp and the camera stay still. Instead of the running wave, the well and the band light up together and fade; the deploy still fills the band, and the words change without a blur.

Pitfalls

  • The faces of a curved wall are thin slices: side by side, a line of the background showed between them. Each slice also has a 0.7 pixel outline in its own colour.
  • The part of the keycap going below the block's top must be drawn only inside the hole (a clipPath with the edge of the well), or the key seems to pass in front of the block instead of sinking into it.
  • With the screen's y pointing down, the winding of the visible faces is the opposite of the textbooks': with the area's sign the wrong way round, only the back walls showed.
  • Seen straight from the front, the model looked like a flat drawing: turning the camera by 0.3 radians shows the side and the thickness, and the 3D reads at once.
  • The acrylic band, with its straight sides made of a single slice, lit up in one colour: it must be cut every 14 pixels so the wave and the progress run along it.
  • A ring of light on the desk, left to run, went out of the canvas and was cut off sharply: it fades before it reaches the edge.
  • A very short tap let go of the key before the click and the deploy did not start: the push carries on until the switch actuates, like a real key pressed in a hurry.
  • Enter on the page pressed the key even while the focus was on another button: it presses it only when the focus is on nothing else, or on the key.

Libraries

GSAP 3.15.0, Space Grotesk (font variabile) 5.3.0, JetBrains Mono (font variabile) 5.3.0.

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

Testing

Tested on 4 October 2026

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

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