
The layered button
Buttons, Hover, Physics
Free
The Add to basket button of a bike shop, in the rich style: on the round end of the blue pill a gravel wheel is mounted as on a workshop stand, with a tan-wall tyre, crossed spokes, a disc brake and a price tag tied to a spoke. On a click the wheel spins up until the spokes blur and the tag flies outwards, then the caliper bites, the rotor heats to gold and blue and the wheel rocks to a stop with its valve at the bottom; the words become In your basket.
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 bike wheel button</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/mona-sans@5.3.0/wdth.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the bike wheel button: the Add to basket pill of a bike shop, with a gravel wheel bolted on its round left end
as on a workstand. A click spins the wheel up until the spokes blur and the price tag tied to a spoke flies
outwards, then the disc brake bites, the rotor glows and the wheel rocks to a stop with its valve at the
bottom; the tag drops and swings, and the words become In your basket. A second click takes it out again -->
<div class="wheel" data-wheel>
<button class="wheel__btn" type="button" data-btn data-autoclic>
<span class="wheel__fill" aria-hidden="true" data-fill><span class="wheel__band" data-band></span></span>
<span class="wheel__words">
<span class="wheel__line" data-line>
<svg class="wheel__tick" viewBox="0 0 20 20" aria-hidden="true"><path d="M4.6 10.4l3.5 3.5 7.4-8" pathLength="1" data-tick/></svg>
<span class="wheel__word" data-word>Add to basket</span>
</span>
<span class="wheel__note" data-note>Gravel wheel · €189</span>
</span>
</button>
<canvas class="wheel__art" aria-hidden="true" data-art></canvas>
<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.
39 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 bike wheel button” from Animorio and fit it into my siteA square canvas centred on the axle, over the left end of the pill. It is drawn from the back: the shadow on the ground, the bracket going into the pill, the far spokes, the rim, the tyre, the near spokes with their nipples, the valve, the reflector, the hub, the rotor, the caliper, the axle and the gloss that does not turn. The spokes are laced two-cross: each leaves the flange shifted forwards or backwards from where it meets the rim.
Each turning part is drawn several times along the arc the wheel covered in the last frame, each copy with its opacity divided by their number, up to ten copies: at rest it is sharp, at speed the spokes become a veil. Above a certain speed the tread is just a band and the sidewall lettering a ring.
The tag is a point with gravity, moved with Verlet integration in four steps a frame and held at the string's length from a point that turns with the wheel: when the wheel runs the centrifugal force takes it outwards by itself, and when it stops it drops and swings.
When nothing drives it the wheel feels the pull of its heavy side, the valve: an acceleration proportional to the sine of the angle between the valve and the bottom, plus friction. After braking the wheel rocks like a pendulum until the valve settles at the bottom.
A GSAP timeline takes the speed to the top, holds it for HOLD seconds, closes the caliper, brakes in BRAKE seconds with power3.out, heats and cools the rotor and changes the words. The drawing sits on the GSAP ticker and stops when nothing moves. It is a real button: Enter and Space, aria-busy, aria-disabled and an aria-live region; a click on the wheel presses it too.
| Name | File | Default | What it changes |
|---|---|---|---|
LABEL | script.js | Add to basket | The words at rest. |
NOTE | script.js | Gravel wheel · €189 | The small words under them. |
BUSY | script.js | Spinning it up… | The words while the wheel spins. |
DONE | script.js | In your basket | The words once it is in the basket. |
PRICE | script.js | €189 | The price on the tag. |
BRAND | script.js | SPOKESMITH | The name on the tyre's sidewall. |
SPIN | script.js | 34 | The wheel's top speed, in radians a second. |
HOLD | script.js | 1 | How many seconds it spins at full speed before the brake. |
BRAKE | script.js | 0.8 | How many seconds the brake takes to stop it. |
HEAT | script.js | 1 | How hot the rotor glows after braking: 0 never. |
SPEED | script.js | 1 | How fast the whole thing runs: 0.6 slow, 1.6 quick. |
For the Add to cart button of a bike or parts shop, a workshop taking bookings, a bike rental or a cycling app; or for a button that starts something that speeds up and stops.
The component is 314 pixels wide and 164 tall, with a 60 pixel pill; on narrower screens everything shrinks together. With no hover the wheel stays still at rest; a tap starts the spin like a click, also on the wheel.
The wheel does not turn and the tag does not swing: on a click the band fills the pill in a fade and the words change by fading, with the tick already drawn.
GSAP 3.15.0, Mona Sans (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 11 KB; the libraries: GSAP 28 KB.
Tested on 23 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.