
Il pulsante a strati
Pulsanti, Hover, Fisica
Gratis
L'Add to cart di un negozio di caramelle, con un piccolo distributore di palline di gomma in piedi nella punta tonda della pillola: la cupola di vetro piena di palline colorate, il corpo smaltato rosso, la manopola cromata e uno scivolo che scende in una tasca scavata nella pillola. Le palline sono corpi rigidi in una simulazione vera su canvas: cadono, si urtano fra loro e contro il vetro. Passando sopra il pulsante la cupola si scuote appena e le palline si assestano. Al clic la manopola fa mezzo giro, la pallina più in basso scende nel corpo, esce sullo scivolo, rotola, salta dal piccolo bordo in fondo e cade nella tasca: il contatore gira su Added · 1 in cart. Ogni clic ne fa scendere un'altra; al limite compare Clear, che rilancia le palline nella cupola dal coperchio aperto.
Una cartella che funziona da sola: index.html, style.css, script.js e le librerie da CDN. Nelle schede React e Vue la stessa demo è già un componente, che spegne le sue animazioni quando esce dalla pagina.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>The gumball machine 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 gumball machine button: the Add to cart of a candy shop, with a small gumball machine standing in the round
left end of the pill. The gumballs are round rigid bodies in a real simulation on a canvas: gravity, knocks
against each other and against the glass. Over the button the globe shakes a little and they settle again. A
click turns the knob: one gumball drops out of the globe, rolls down the chrome chute, hops into the cup in the
pill, and the counter rolls up. At the limit, Clear sends them back into the globe -->
<div class="gum" data-gum>
<canvas class="gum__art" aria-hidden="true" data-art></canvas>
<button class="gum__btn" type="button" data-btn data-autoclic>
<span class="gum__fill" aria-hidden="true"></span>
<span class="gum__faces">
<span class="gum__face" data-face="rest">
<span class="gum__word" data-label-text>Add to cart</span>
<span class="gum__price" data-price-text>€6.90</span>
</span>
<span class="gum__face gum__face--busy" data-face="busy" aria-hidden="true">
<span class="gum__shine" data-busy-text>Adding…</span>
</span>
<span class="gum__face gum__face--done" data-face="done" aria-hidden="true">
<span class="gum__done">
<span data-done-text>Added</span>
<span class="gum__dot">·</span>
<span class="gum__roll" aria-hidden="true"><span class="gum__digits" data-digits><span>0</span><span>1</span><span>2</span><span>3</span><span>4</span><span>5</span><span>6</span><span>7</span><span>8</span><span>9</span></span></span>
<span data-cart-text>in cart</span>
</span>
<span class="gum__chip" data-chip data-clear-text>Clear</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>Cambia valori, colori e testi con le manopole e guarda l’animazione rispondere dal vivo. Oppure scrivi tu nel codice. Poi scarica la cartella con le tue modifiche.
32 valori da cambiare
Col connettore di Animorio, Claude Code la prende da qui con tutta la sua guida e la adatta al tuo progetto. Incolla questa richiesta:
Prendi «Il pulsante del distributore di palline» da Animorio e adattala al mio sitoOgni pallina è un cerchio di raggio 5 con posizione e velocità. A ogni fotogramma (limitato a 1/30 di secondo) si fanno passi di 1/240: gravità GRAVITY, un filo d'aria che frena, poi tre giri di vincoli. Due palline che si toccano si separano a metà ciascuna e, se si stanno avvicinando, si scambiano un impulso lungo la linea dei centri con rimbalzo BOUNCE, più un poco d'attrito di traverso. Sotto i 40 pixel al secondo il rimbalzo è zero: così un mucchio sta fermo invece di tremare.
Le palline nella cupola stanno dentro un cerchio: se ne escono vengono rimesse sul bordo e la loro velocità relativa al vetro perde la parte verso fuori. La velocità del vetro conta, perché la cupola si scuote (una timeline GSAP di sei fotogrammi chiave sullo spostamento): il vetro che arriva spinge le palline vicine, e con un piccolo sollevamento casuale si vedono assestarsi. Lo stesso colpo, più piccolo e verticale, arriva quando gira la manopola.
Al clic si sceglie la pallina più in basso e più vicina al centro. Diventa cinematica: GSAP la porta al foro e giù nel corpo, e nelle collisioni ha massa infinita, così spinge le vicine invece di esserne fermata. Dentro il corpo è nascosta dal disegno (le palline della cupola si disegnano prima del collare e del corpo); poi rinasce sullo scivolo con una velocità, e da lì è di nuovo un corpo libero, disegnata solo a destra della porticina.
Fuori dalla cupola le palline urtano segmenti: lo scivolo (con un piccolo bordo all'insù in fondo, che la fa saltare) e la tasca, una U fatta di due pareti e quattordici segmenti d'arco. Il contatto con un segmento cerca il punto più vicino, rimette la pallina a distanza di raggio e toglie la velocità verso il muro. Quando la pallina supera il bordo della tasca è arrivata: il tamburo del numero gira e la pillola cambia scritta. Se dopo 2,4 secondi non è ancora arrivata, viene posata nella tasca.
A Clear il coperchio si apre girando sulla sua cerniera di sinistra e ogni pallina della tasca segue una curva quadratica dal suo posto al foro in alto: una curva di Bézier quadratica percorsa a passo costante è proprio la traiettoria di un lancio. Arrivata, ridiventa un corpo della cupola con la velocità d'arrivo e rimbalza sulle altre. Le palline sono sprite dipinti una volta per colore alla densità dello schermo; il ciclo si ferma quando nessuna si muove più.
Tre facce sovrapposte, larghe quanto le parole e misurate al pixel frazionario: a riposo, in corso, il conteggio con il tamburo (una colonna di cifre spostata in yPercent con back.out). Il distributore non si sposta mai: il componente tiene la larghezza del riposo e la pillola cresce o si stringe verso destra. Il pulsante è un button vero, aria-disabled mentre la pallina scende, con una zona aria-live che dice Added. 2 in cart. e un aria-label che dice il conteggio; anche un clic sul distributore aggiunge.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
LABEL | script.js | Add to cart | La scritta a riposo; si allarga sotto il puntatore. |
PRICE | script.js | €6.90 | Il prezzo accanto alla scritta. |
BUSY | script.js | Adding… | La scritta mentre la prima pallina scende. |
DONE | script.js | Added | La parola prima del conteggio. |
CART | script.js | in cart | Le parole dopo il conteggio. |
CLEAR | script.js | Clear | La piccola pillola che compare al limite: il suo clic svuota il carrello. |
LIMIT | script.js | 4 | Quante palline vanno nel carrello prima di Clear (da 1 a 5: la tasca ne tiene cinque). |
GUMBALLS | script.js | 12 | Quante palline ci sono nella cupola. |
GRAVITY | script.js | 1800 | Quanto cadono svelte, in pixel al secondo al quadrato: più bassa, una caduta lenta come sulla luna. |
BOUNCE | script.js | 0.35 | Quanto rimbalzano: 0 atterrano morte, 0,7 saltano a lungo. |
SHAKE | script.js | 1.6 | Quanto si scuote la cupola sotto il puntatore, in pixel: 0 resta ferma. |
Per l'Add to cart di un negozio di dolci, di caramelle sfuse, di giocattoli o di gadget, o di un sito che ha un tono giocoso: il distributore dice «ne prendo un'altra» meglio di un'icona. Va bene anche per i contatori di quantità di un catalogo per bambini o di una pasticceria. L'aggiunta qui è simulata: in un sito vero il conteggio arriva dal carrello del tuo server.
Il componente è largo circa 300 pixel a riposo e circa 340 con Clear: a 390 pixel ci sta. Il tocco scuote la cupola e aggiunge una pallina; il distributore resta delle stesse misure.
Le palline sono già ferme nella cupola, senza pioggia d'arrivo e senza scuotersi; la pillola non si gonfia e la scritta non si allarga. Al clic una pallina della cupola svanisce e una appare già ferma nella tasca, e il conteggio arriva in dissolvenza. Clear fa svanire quelle della tasca e riapparire quelle della cupola.
GSAP 3.15.0, Mona Sans (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 15 KB; le librerie: GSAP 28 KB.
Provata il 12 ottobre 2026
Puoi usarla nei tuoi progetti e in quelli dei tuoi clienti. Non puoi rivenderla né ridistribuirla così com’è. GSAP resta sotto la sua licenza Standard. Licenza completa.
Con l’email e la password del tuo account.
oppure con l’email
Hai fatto l’accesso come .
Con l’account scarichi lo zip di ogni animazione e di ogni pacchetto, gratis.