
The slide-to-confirm button
Buttons, Physics, Transitions
NewFree
The Checkout of a grocery shop as the belt at the till: the pill is the counter, along its edge runs the ribbed rubber belt, on it stand four small drawn groceries (a baguette, a jar of honey with a checked lid, an apple, a carton of milk), and over the belt hangs the reader. At a click the belt starts: the groceries ride along and feel the push as real things do, the milk and the honey tip back as it starts and forward as it brakes, the apple rolls back a little and catches up. Passing under the reader a red line crosses each one, the reader flashes and the total rises with every item, its digits turning on drums; at the end Paid · €18.70. Another click lifts the groceries back to the start of the belt, one after the other with a little hop.
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 checkout belt 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 checkout belt button: the Checkout of a grocery shop, as the belt at the till. The pill is the counter, and
along its top runs the rubber belt; on it stand four small groceries (a baguette, a jar of honey, an apple, a
carton of milk) and over it hangs the reader. A click starts the belt: the groceries ride along, tipping with
the belt's push as real things do, and pass under the reader, where a red scan line crosses each one; the total
rolls up on its digits with every item, then Paid. Another click puts the groceries back on the belt -->
<div class="till" data-till>
<canvas class="till__art" aria-hidden="true" data-art></canvas>
<button class="till__btn" type="button" data-btn data-autoclic>
<span class="till__faces">
<span class="till__face" data-face="rest">
<span class="till__word" data-label-text>Checkout</span>
<span class="till__items" data-items-text>4 items</span>
</span>
<span class="till__face till__face--sum" data-face="sum" aria-hidden="true">
<span class="till__state">
<svg class="till__tick" viewBox="0 0 16 16" aria-hidden="true" data-tick><path d="M3.2 8.4l3 3 6.6-6.8"/></svg>
<span class="till__says" data-says>
<span class="till__say" data-scan-text>Scanning</span>
<span class="till__say till__say--paid" data-paid-text>Paid</span>
</span>
</span>
<span class="till__dot">·</span>
<span class="till__sum" aria-hidden="true" data-sum></span>
</span>
</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.
27 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 checkout belt button” from Animorio and fit it into my siteEverything that moves is drawn on a canvas 12 pixels wider than the component on each side, for the swell and the shadow. The pill is a rounded rectangle with its gradient; inside it, clipped to the pill, the band of rubber with a rib every 5.5 pixels, shifted by the belt's travel modulo the step. Near the ends a rib's position goes through a sine, x = end ± r · sin(...), so the ribs crowd together as on the roller. The swell and the squash are two numbers tweened by GSAP, and the groceries always stand on the pill's top edge as it is at that moment: pressing, they sink with it.
The belt's travel is a power2.inOut tween of RUN seconds. Every frame its speed and its acceleration are read (finite differences, filtered), and the acceleration pushes each grocery backwards. The milk and the honey have an angle on a damped spring (φ'' = −ω²φ − 2ζωφ' − k·a), and they turn round their back corner when they tip back and round their front corner when they tip forward; the apple and the baguette have a slip on their spring, and the apple turns by its slip over its radius, that is, it rolls. Steps of 1/240 of a second; the tip goes no further than 0.3 radians.
While the belt runs, a narrowing fan of red light is drawn under the reader in lighter mode, and over it a one pixel line with its glowing shadow. On a grocery crossing it the line is drawn again, brighter, for the grocery's height: it seems to lie on it. When the middle of a grocery passes the line it is read: a tween takes the flash from 1 to 0 (the window and the line light up more) and the total rises by its price.
The total has four drums (tens, units, tenths, hundredths), each a column with the digits 0 to 9 twice. A drum always turns forward: from 7 to 2 it goes to 12, through 8, 9, 0, 1, and at the end it is set back on the 2 of the first round without it showing. The drums on the right turn a little faster. The tens drum is zero wide until it is needed and widens with back.out when the total passes ten euros.
At the second click each grocery moves onto a path of its own: x from where it is to its starting place, height 4 · h · t · (1 − t), a parabola, and a small turn (the apple turns more). Under them the belt is set back to zero at once, because while a grocery is in the air its place does not depend on the belt. Landing, each one squashes and springs back with three keyframes.
Two faces on top of each other: at rest, and Scanning or Paid with the total. The box of Scanning and Paid takes the width of the word showing, so the tick, the word and the total stay close together. The button is a real button, aria-disabled while the belt runs; the aria-live region says the total at every item and then Paid. €18.70., and once paid the aria-label also says Put the items back. The belt runs for 2.6 seconds, a little less than the 2.8 between two clicks of the preview: the second click falls in the wait and Paid stays in view for a whole round.
| Name | File | Default | What it changes |
|---|---|---|---|
LABEL | script.js | Checkout | The word at rest; it widens under the pointer. |
SCANNING | script.js | Scanning | The word while the belt runs. |
PAID | script.js | Paid | The word at the end, with the tick. |
CURRENCY | script.js | € | The sign before the total. |
PRICES | script.js | [3.2, 11.9, 1.2, 2.4] | The prices of the baguette, the honey, the apple and the milk: the total is their sum (under a hundred euros). |
RUN | script.js | 2.6 | The seconds the belt runs. |
TIP | script.js | 1 | How much the groceries tip and roll with the belt's push: 0 they stand still, 2 they sway a lot. |
JOG | script.js | 8 | How many pixels the belt jogs forward under the pointer: 0 it stays still. |
For the button that closes the order of an online supermarket, a grocery delivery, a delicatessen or a local market: the belt and the rising total say adding it up better than a spinner. The groceries can be redrawn as the shop's own. Payment is simulated here: in a real site the total and the confirmation come from your server or the payment service.
The counter is 330 pixels wide and narrows on a narrower screen: the groceries, the reader and the belt's travel are worked out again from the width. A tap squashes the counter, the groceries sink with it, and it pays.
The belt does not run and the groceries do not tip; the counter does not swell and the word does not widen. At a click the groceries fade out at the start of the belt and fade in already past the reader, and Paid · €18.70 fades in, with no red line and no turning digits. Another click fades them out and back in at the start.
GSAP 3.15.0, Mona Sans (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 12 KB; the libraries: GSAP 28 KB.
Tested on 10 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.