
The send button
Buttons, Transitions, SVG
NewFree
A mug with six colours under it: choosing one, the new paint rises inside the mug from the bottom with a rolling wave, the handle takes it when the wave gets there, the mug sways and a ring slides onto the swatch chosen; all the while steam rises from the cup.
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 colour picker</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/outfit@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the picker: a mug and six colours under it, over six real radio buttons. Choosing a colour, the new paint
rises inside the mug from the bottom with a rolling wave, the handle takes it when the wave gets there, the
mug sways, and a ring slides to the swatch chosen. Steam keeps rising from the cup -->
<form class="pick" data-pick onsubmit="return false">
<svg class="pick__mug" viewBox="0 0 260 240" aria-hidden="true" data-mug>
<defs>
<clipPath id="mug-body"><path d="M60 62 L68 188 Q70 205 87 205 L163 205 Q180 205 182 188 L190 62 Z"/></clipPath>
<linearGradient id="mug-gloss" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" stop-color="#fff" stop-opacity="0"/>
<stop offset="0.5" stop-color="#fff" stop-opacity="0.34"/>
<stop offset="1" stop-color="#fff" stop-opacity="0"/>
</linearGradient>
<linearGradient id="mug-shade" x1="0" y1="0" x2="1" y2="0">
<stop offset="0.55" stop-color="#000" stop-opacity="0"/>
<stop offset="1" stop-color="#000" stop-opacity="0.18"/>
</linearGradient>
<filter id="mug-soft" x="-20%" y="-50%" width="140%" height="200%"><feGaussianBlur stdDeviation="4"/></filter>
</defs>
<ellipse class="pick__shadow" cx="126" cy="214" rx="80" ry="9" filter="url(#mug-soft)"/>
<g class="pick__steam" data-steam>
<path d="M108 50c-7-9 7-15 0-24s7-15 0-22"/>
<path d="M126 46c-7-9 7-15 0-24s7-15 0-22"/>
<path d="M144 50c-7-9 7-15 0-24s7-15 0-22"/>
</g>
<path class="pick__handle" d="M186 88 C238 84 244 172 184 168 L182 148 C218 152 218 102 186 108 Z" data-handle/>
<g clip-path="url(#mug-body)">
<rect x="50" y="50" width="150" height="170" data-body/>
<path data-paint/>
<rect x="50" y="50" width="150" height="170" fill="url(#mug-shade)"/>
<rect x="74" y="66" width="18" height="128" rx="9" fill="url(#mug-gloss)"/>
</g>
<ellipse cx="125" cy="62" rx="65" ry="13" data-rim/>
<ellipse cx="125" cy="64" rx="56" ry="9.5" class="pick__coffee"/>
<ellipse cx="125" cy="62" rx="64" ry="12.4" class="pick__lip"/>
</svg>
<fieldset class="pick__swatches" data-swatches data-autoclic>
<legend class="pick__legend">Colour</legend>
<span class="pick__ring" aria-hidden="true" data-ring></span>
</fieldset>
<p class="pick__name" aria-hidden="true"><span data-name></span></p>
<p class="pick__note" data-note></p>
</form>
</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.
28 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 colour picker” from Animorio and fit it into my siteThe mug is hand-drawn in SVG: the body, cut by a clipPath of its own shape, the handle, the rim, the coffee and a pale light on one side. The body’s colour is a plain rectangle inside the cut; over it, inside the same cut, the new paint rises.
The paint is a path from the bottom up to a wavy edge: the script redraws it on every frame with height = level + WAVE[0] · sin(x · WAVE[1] + phase). The level rises in FILL seconds with power2.inOut, the phase runs and the wave’s height follows sin(π · progress), so it is still at the start and flat at the end; then the body takes the colour and the paint goes.
In the same timeline the handle changes colour when the wave reaches its height (42 per cent of the way up), the rim at the end in the shaded colour, and the mug sways by SWAY degrees round its foot and settles with elastic.out.
Under the swatches there are six real radio buttons: arrows, screen readers and forms work by themselves. A single ring slides onto the swatch chosen with back.out, and the swatch shrinks to 0.74 inside it with a bounce; the name rolls over and the line underneath changes with a fade.
Three wisps of steam have a dash half as long as their line that runs along with stroke-dashoffset while they rise and fade, in an endless loop staggered between them. A click from a script on the swatches (the library’s preview) chooses the next colour.
| Name | File | Default | What it changes |
|---|---|---|---|
COLOURS | script.js | [['Sage', '#9bb38f', 'A soft green, like olive leaves.'], …] | The colours: name, colour and a line about it. |
START | script.js | 0 | The colour chosen when the page opens. |
FILL | script.js | 1.1 | The seconds the new colour takes to rise. |
WAVE | script.js | [7, 0.075] | The wave on top of the paint: how high, in pixels, and how close its crests are. |
SWAY | script.js | 3 | How far the mug sways as it fills, in degrees. |
For a product page with several colours (mugs, bags, shoes, chairs), for picking the colour of a theme or a label: wherever the colour chosen must show on the object straight away.
The mug shrinks with the screen and the swatches stay big enough for a finger; two quick taps on a swatch do not zoom the page.
The mug changes colour at once, without the wave or the sway, the steam stands still, the ring and the name change without sliding.
GSAP 3.15.0, Outfit (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 4.9 KB; the libraries: GSAP 28 KB.
Tested on 3 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.