
The card field
Forms, SVG, 3D, Physics, Text
NewFree
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.
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>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
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 siteThe 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.
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 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 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.
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.
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.
| Name | File | Default | What it changes |
|---|---|---|---|
TRAVEL | script.js | 24 | How far the key goes down, in pixels (4 mm on a real keyboard). |
STIFF | script.js | 2000 | How hard the switch's spring pushes back. |
BUMP | script.js | 0.9 | How strong the tactile bump halfway down is (0 = a smooth, linear switch). |
WAVE | script.js | 2.4 | How fast the light wave runs out from the key, in key widths per second. |
HUE | script.js | 18 | The colour the wave starts from, as a hue: 0 red, 120 green, 240 blue. |
DEPLOY | script.js | 3.4 | The seconds of the pretend deploy. |
DONE | script.js | 2.8 | The seconds the key says Live before it is ready again. |
LIGHT | script.js | 1 | How much the lamp follows the pointer (0 = it stays where it is). |
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.
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.
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.
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.
Tested on 4 October 2026
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.
With your account’s email and password.
or with your email
You’re signed in as .
With your account, you can download the zip of every animation and every pack, for free.