
The slide-to-confirm button
Buttons, Physics, Transitions
NewFree
The preparing of an order in a bakery app, made as a ball of dough proofing in a stoneware bowl: it is a real soft body, a ring of points on springs, a pressure inside that grows with the progress, gravity and the bowl’s wall. As it rises its skin goes tight, bubbles swell and pop and the flour on top cracks into flakes; tapped, it gives and springs back with a soft bounce. At the end it has risen, takes the colour of the crust and is ready for pickup.
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, viewport-fit=cover">
<title>The rising dough</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/full.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/instrument-sans@5.3.0/wdth.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the order tracker of a bakery app: the order is a ball of dough in a stoneware bowl that proofs as the order
gets ready. The dough is a soft body (a ring of points on springs, with a pressure inside that grows with the
progress, gravity and the bowl to lean on), drawn by script.js on the canvas; tap it and it gives under the
finger and springs back. At the end it has risen and baked to a crust: ready for pickup -->
<section class="proof" aria-labelledby="proof-title" data-proof>
<div class="proof__head">
<div class="proof__words">
<h2 class="proof__title" id="proof-title"><span class="proof__swap" data-title>Your order</span></h2>
<p class="proof__meta"><span class="proof__swap" data-meta>Ready in about 18 min</span></p>
</div>
<p class="proof__figure" aria-hidden="true">
<span class="proof__pct is-quiet" data-pct>$21.40</span>
<svg class="proof__tick" viewBox="0 0 24 24" data-tick><path d="M5.5 12.6l4.1 4.1L18.6 7.4" pathLength="1"/></svg>
</p>
</div>
<div class="proof__bowl" role="progressbar" aria-labelledby="proof-title" aria-valuemin="0" aria-valuemax="100"
aria-valuenow="0" aria-valuetext="Not started" data-bowl>
<canvas class="proof__paint" aria-hidden="true" data-paint></canvas>
</div>
<div class="proof__foot">
<p class="proof__items">2 sourdough loaves <span class="sep">·</span> 1 focaccia</p>
<button class="proof__btn" type="button" data-action data-autoclic><span class="proof__label" data-label>Place order</span></button>
</div>
<p class="sr" role="status" aria-live="polite" data-live></p>
</section>
</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.
32 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 rising dough” from Animorio and fit it into my siteThe dough is a ring of 48 points. At every step of 1/240 of a second (a frame’s time is capped at 1/30) each point moves by as much as it moved the step before, a little damped, plus gravity: that is Verlet integration, where the speed is the difference between the position now and the one before. Then three rounds of constraints put things right: springs between neighbours, softer springs between a point and the one after next (so the skin does not crease), the pressure and the bowl.
The pressure is a constraint on the area: the ring’s area comes from the shoelace formula, and its gradient for every point is ½ (y of the next − y of the previous, x of the previous − x of the next); every point moves along its gradient as far as it takes to get back to the area wanted. The area wanted grows with the progress (with RISE 1 it doubles) and the springs’ rest length grows with its square root, a little less: the skin goes tight and the dome rounds up instead of spreading. The progress arrives in jumps, and the dough follows it on a critically damped spring that never goes back.
Under the rim the inside wall is half an ellipse: a point that gets out is put back on the ellipse and loses 30% of its speed along the wall, so the dough slides with some friction. The fingertip is a disc 26 units across that comes down from the top of the dough above the finger by POKE units: the points cannot get into it, so the dough gives and spreads to the sides; meanwhile the area wanted drops by 6%, because pressed dough lets out a little air and does not all bulge round the finger. Once the finger lifts, the pressure pushes it back up and Verlet’s inertia makes it bounce.
Everything on the skin is tied to the ring by two numbers: a place along the ring (between two points) and a depth under the skin, along the normal. The flour is a sheet of eight sided flakes that all touch, with a wandering point in the middle of each side that is the same for the two flakes next to it; each flake remembers its first area and, when the dough under it spreads beyond its strength, it shrinks towards its centre and rounds its corners: so the cracks open here and there, not all at once. Each row of flakes is a single path, and where they still touch there is no seam. The bubbles grow, then pop: a ring that widens, a crater that fades and a push inwards on the points nearby, which give a start.
The bowl is painted only once, in two layers: behind the dough its shadow on the card, the inside and the back of the rim; over it, the glazed outside with the light of a window, the specks of the stoneware, the clay foot under the edge of the glaze and the front of the rim. The dough is drawn every frame as a closed Catmull-Rom curve, with a gradient from top to bottom, a glow at the top left that grows as the skin goes tight, a shade on the far side, a darker edge and a texture of grain. In the oven the colour goes golden first and then brown, because straight from cream to brown it would pass through grey, and darker patches make the crust uneven. When nothing moves, nothing is drawn.
The bowl is a role=progressbar with aria-valuenow and an aria-valuetext that says the step; the card has aria-busy while the order is made and an aria-live line says when it starts, when it is cancelled and when it is ready, with the code. The button changes its word (Place order, Cancel, Order again) and the pill takes the new width with a little bounce; the library preview’s click, which comes from a script, never cancels.
| Name | File | Default | What it changes |
|---|---|---|---|
SECONDS | script.js | 8 | How long the order takes in the demo, in seconds (a real one follows its own steps). |
MINUTES | script.js | 18 | The minutes the app says the order takes. |
RISE | script.js | 0.85 | How much the dough grows by the end: 1 means it doubles. |
GRAVITY | script.js | 900 | How hard gravity pulls the dough into the bowl, in pixels per second squared. |
SKIN | script.js | 0.3 | How firmly the skin holds its shape: low sags, high stays round. |
DAMP | script.js | 1.8 | How quickly a wobble dies away: the share of its speed it loses each second. |
POKE | script.js | 16 | How deep a tap pushes the dough in, in pixels. |
BUBBLES | script.js | 3.2 | How many bubbles come up each second while the dough proofs. |
FLOUR | script.js | 0.9 | How much flour is dusted on top: 0 none, 1 a thick coat. |
CRUST | script.js | 1 | How dark the crust bakes: 0 pale, 1 deep brown. |
For a wait of a few minutes in a food app: an order at a bakery, a pizzeria, a cake made to order, bread to pick up. The rising dough says «we are on it» better than a bar, and it can be poked while you wait; for a wait of a few seconds or a file upload something plainer is better.
The card takes the screen’s width less 32 pixels (358 on a 390 screen) and the bowl shrinks with it, always in the same shape: the physics works in units of the drawing, and the canvas paints at the screen’s real density, up to twice. A finger pokes the dough just as the mouse does, and a tap is a click at once.
The dough still rises, because it is what says how far along the order is, but without any wobble: the damping is so strong that it rises and settles slowly. The finger does not dent it, the bubbles fade in and out without popping, no last puff and no glint: the crust fades in, like the tick and the new words.
GSAP 3.15.0, Fraunces (font variabile) 5.3.0, Instrument Sans (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 17 KB; the libraries: GSAP 28 KB.
Tested on 8 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.