
The water button
Buttons, SVG, Physics, Hover
NewFree
The Do not disturb switch in a phone’s settings, and the knob is a pill bug seen from the side, standing on its fourteen legs in a little window of daylight. Turned on, it does what a disturbed pill bug does: it folds its legs, lowers its antennae, arches its back and closes its armour into a ball, which rolls to the far end, knocks it and bounces back, while dusk falls in the window with a moon. Turned off, the ball rolls home rocking, opens out and the legs take a few steps.
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 pill bug switch</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/onest@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the Do not disturb switch of a phone's settings, and the knob is a pill bug seen from the side in a little
window of daylight. Off, it stands on its fourteen legs with its antennae out. Turned on, it curls up into an
armoured ball, rolls to the far end of the switch and the window goes dusk; off again, the ball rolls back,
rocks to a stop and opens out, and the legs walk for a moment -->
<div class="tile" data-dnd>
<span class="tile__text">
<label class="tile__name" for="dnd-switch">Do not disturb</label>
<span class="tile__state" id="dnd-state" data-state>Alerts come through</span>
</span>
<button class="bug" id="dnd-switch" type="button" role="switch" aria-checked="false" aria-describedby="dnd-state" data-switch data-autoclic>
<svg class="bug__art" viewBox="0 0 184 56" aria-hidden="true" focusable="false" data-art></svg>
<svg class="bug__art bug__art--alt" viewBox="0 0 184 56" aria-hidden="true" focusable="false" data-art-alt></svg>
<span class="bug__glass" aria-hidden="true"></span>
</button>
<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.
29 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 pill bug switch” from Animorio and fit it into my siteThe little window is a button with role switch and aria-checked, a label for with the name and aria-describedby on the line under it, which changes with the state. Enter and Space turn it on and off, the right arrow turns it on and the left one off, and so does a click on the name; an aria-live line says the new state. The focus ring only shows when the keyboard is in use.
The back is an arc of one curvature, always LEN long: curling only means turning a bigger angle, from 1.15 radians (the dome at rest) to 98.5 per cent of a full turn, when the radius becomes the ball’s, 21 pixels. Every point comes from that arc: its centre, the radius LEN/angle, the normal coming out of the back. The lowest point is set on the floor (or the belly above it, on the legs), so the body sits down by itself as the legs fold in.
Each plate is a band of the arc between the back and a depth that at rest follows the dome (the belly stays nearly flat) and in the ball reaches the middle, where the head closes over the tail. The plates are drawn from the tail to the head, each one a little over the one behind, and take their colour from the way they face the light (the normal in their middle against a light from the top left); over them, the bright thread of the back, the shadow of the edge, the scalloped side and a light that goes from overhead to round, as on a sphere, while it closes.
Seven pairs of legs start from the belly of each big plate and reach the floor, with the knee bent forward at the front and backward at the back. Walking, each foot goes round a small ellipse a little behind the one before, a wave running from the tail to the head, and the far side is half a step behind. The antennae are three segments that bend more and more; the mouse lifts or lowers them, and two springy twitches come as it opens out.
The ball is a mass worked out four times a frame on gsap.ticker, with the time step held to 1/30 of a second, and its turn is tied to the way it has gone (angle = distance / radius). Towards the far end it rolls down a slight slope (ROLL) and bounces keeping BOUNCE of its speed; towards home the same slope ends in a damped dip (SETTLE), where it rocks: only once it is still, and so upright with the head over the tail, does it open.
Closing, opening, the dusk and the steps are GSAP tweens and timelines; the flinch under the mouse and the ball’s nudge towards the pointer are two small springs. A click halfway picks up from where things are: a ball on its way home rolls forward again, a body closing opens back up. Every frame a key of rounded values is compared: when nothing moves, nothing is drawn.
| Name | File | Default | What it changes |
|---|---|---|---|
CURL | script.js | 0.5 | The seconds the bug takes to close into a ball. |
UNCURL | script.js | 0.65 | The seconds it takes to open out again. |
ROLL | script.js | 950 | How steep the slope the ball rolls down to the far end, in pixels a second squared. |
BOUNCE | script.js | 0.34 | How much of its speed the ball keeps when it knocks the far end (0, it stops dead). |
SETTLE | script.js | 9 | How tight the dip the ball rolls home into: higher, it stops sooner. |
FLINCH | script.js | 0.14 | How much the bug starts curling under the mouse or a finger (0, not at all). |
PEEK | script.js | 5 | How many pixels the ball rolls towards the mouse when it is curled up. |
SCURRY | script.js | 1.4 | The seconds the legs keep walking on the spot after it opens out. |
PLATES | script.js | 7 | The big plates on its back, each with its pair of legs. |
For a switch that has to say closed to the world: Do not disturb, a focus mode, pausing notifications, a private mode or an app’s silent mode, or in an app about nature, gardening or children. The ball and the dusk say on even without reading. It is a piece to set on its own, where it is noticed, not in a long list of settings next to ten others.
Same size as on a computer: the switch is 184 by 56 pixels and at 390 pixels the name and the window sit on one line; under 360 pixels the window shrinks a little, the drawing with it. A tap turns it on and off; as soon as the finger rests on it the bug flinches as with the mouse, and as a ball it rolls a few pixels. No antennae following the pointer, which a finger does not have.
No movement: the bug standing in daylight and the ball in the dusk are two still drawings, and turning it on or off fades one into the other in under half a second, with the colour of the name. No flinch and no steps; clicks, taps and keys work as always.
GSAP 3.15.0, Onest (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 11 KB; the libraries: GSAP 28 KB.
Tested on 13 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.