
Il pulsante che copia
Pulsanti, Testo, SVG, Fisica
NuovaGratis
Nello stile minimal: quanti ospiti per un tavolo, da 1 a 12, con un meno, un più e una cifra grande che a ogni ospite in più prende peso e un po’ di larghezza. La cifra nuova cade al suo posto, atterra un pixel troppo in basso e torna su, e la riga sottile sotto sente il colpo: vibra come una corda e si assesta. Dalla riga pendono dodici tacche, rosse fino al numero.
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 stepper that gains weight</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/archivo@5.3.0/wdth.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- how many guests for a table: minus, the number, plus. Every guest more makes the number heavier and a little
wider; the new number falls into its place, lands a pixel too low and the thin line under it feels the knock.
Under the line, one thin tick per seat. The numbers, the line and the ticks are made by the script -->
<div class="party" data-party>
<p class="party__label" id="party-label">Guests</p>
<div class="party__row">
<button class="party__btn" type="button" aria-label="Remove a guest" data-less>
<span class="party__btn-in" aria-hidden="true">
<svg viewBox="0 0 48 48">
<circle class="party__ring" cx="24" cy="24" r="23"/>
<circle class="party__draw" cx="24" cy="24" r="23" pathLength="1"/>
<path class="party__icon" d="M17 24h14"/>
</svg>
</span>
</button>
<div class="party__value" role="spinbutton" tabindex="0" aria-labelledby="party-label" aria-describedby="party-note" aria-valuemin="1" aria-valuemax="12" aria-valuenow="2" aria-valuetext="2 guests" data-value>
<span class="party__window" aria-hidden="true" data-window></span>
</div>
<button class="party__btn" type="button" aria-label="Add a guest" data-more data-autoclic>
<span class="party__btn-in" aria-hidden="true">
<svg viewBox="0 0 48 48">
<circle class="party__ring" cx="24" cy="24" r="23"/>
<circle class="party__draw" cx="24" cy="24" r="23" pathLength="1"/>
<path class="party__icon" d="M17 24h14M24 17v14"/>
</svg>
</span>
</button>
</div>
<svg class="party__ruler" aria-hidden="true" data-ruler>
<path class="party__rule" data-rule d=""/>
<g data-ticks></g>
</svg>
<p class="party__note" id="party-note" data-note></p>
<p class="sr" aria-live="polite" data-said></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.
27 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 contatore che prende peso» da Animorio e adattala al mio sitoLe cifre sono in Archivo, un carattere variabile con due assi, peso (wght) e larghezza (wdth). Il conto non cambia gli assi direttamente: guida una molla smorzata (OMEGA 17, smorzamento 0,62 / SPRING) che va verso il conto nuovo, e il peso e la larghezza si leggono dalla posizione della molla, fra LIGHT e HEAVY. Così il peso cresce in un attimo, va un filo oltre e si assesta, e saltando da 3 a 12 con Fine si vede il numero gonfiarsi tutto in un colpo. Gli assi stanno su tutta la finestra, quindi il numero che arriva e quello che se ne va hanno sempre lo stesso peso.
Ogni numero è una riga di cifre (inline-block) in una finestra che sfuma in alto e taglia netto in basso, appena sopra la riga: quella è la fessura. Col più il numero vecchio sprofonda nella fessura in 0,12 secondi (power2.in) e il nuovo parte 0,09 secondi dopo da un terzo di cifra più in alto, così i due non si toccano mai; cade con power2.in, come una cosa lasciata andare, fino a 1,2 pixel sotto il suo posto, e torna su con elastic.out mentre tutto il numero si schiaccia del 2,5% sul fondo. Due cifre cadono una dopo l’altra, a 35 millesimi.
La riga è una corda di 56 pezzi con i capi fermi: a ogni passo (al massimo un millesimo di secondo, e un fotogramma lento conta per 1/30) ogni punto prende un’accelerazione dalla curvatura fra i due vicini, con un’onda che corre a 2600 pixel al secondo, e perde velocità per l’attrito. Una cifra che atterra dà alla corda una spinta a forma di campana proprio sotto il suo centro, misurato con getBoundingClientRect, e la spinta cresce col peso del numero: a 3 la riga si piega di un pixel e mezzo, saltando da 3 a 12 di più di quattro. Le tacche sono appese alla corda e si disegnano dove la corda passa. Quando corda e molla sono ferme il ciclo si toglie dal ticker di GSAP e non ridisegna.
Al limite il numero non cambia: si sposta di 6 pixel verso il pulsante e torna con un elastic.out stretto, che fa due piccoli no; il segno del pulsante fa lo stesso di 3 pixel. La molla del peso riceve una spinta oltre il limite e ritorna, la corda un colpetto, e la nota sotto le tacche sale con la sua frase rossa e torna quella di sempre dopo 1,8 secondi.
Il numero è uno spinbutton con aria-valuenow e aria-valuetext, e una regione aria-live dice il conto mezzo secondo dopo l’ultimo cambio. Un pulsante conta alla pressione (pointerdown) e ripete tenendolo, con intervalli che si accorciano dell’80% fino a HOLD[2]; il clic che segue viene ignorato, mentre Invio e Spazio contano nel clic. La riga prende i tocchi e i trascinamenti (touch-action: pan-y, così la pagina scorre ancora). Il clic che arriva da uno script, quello dell’anteprima della libreria, fa invece un giro intero in una timeline GSAP: su fino a 12, un più di troppo, e giù fino al numero di partenza.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
MIN | script.js | 1 | Il numero più piccolo di ospiti. |
MAX | script.js | 12 | Il numero più grande di ospiti, che è anche il numero di tacche sulla riga (da 2 a 24). |
START | script.js | 2 | Gli ospiti quando si apre la pagina. |
LIGHT | script.js | [140, 80] | Il peso (da 100 a 900) e la larghezza (da 62 a 125) del numero col minimo degli ospiti. |
HEAVY | script.js | [860, 116] | Il peso e la larghezza del numero col massimo degli ospiti. |
DROP | script.js | 0.24 | Quanto ci mette un numero nuovo a cadere al suo posto, in secondi. |
KNOCK | script.js | 1 | Quanto forte la riga sente un numero che atterra (0 = non si muove). |
SPRING | script.js | 1 | Quanto è elastico il peso: a 0,5 si posa senza oscillare, a 2 va oltre e ondeggia. |
HOLD | script.js | [0.42, 0.16, 0.06] | Tenendo premuto un pulsante: dopo quanto comincia a ripetere, il primo intervallo e il più corto, in secondi. |
WORD | script.js | ['guest', 'guests'] | La parola per uno e per più di uno, letta da chi usa un lettore di schermo. |
NOTE | script.js | ['Tables seat up to {max}', 'Our longest table seats {max}', 'At least one guest'] | La nota sotto le tacche: a riposo, al massimo e al minimo; {max} diventa il numero più grande. |
Per scegliere quante persone o quante cose quando il numero è piccolo e conta: gli ospiti di una prenotazione al ristorante, i posti di un tavolo, le persone di una visita guidata, le notti, i biglietti, le porzioni. Sta bene in un sito sobrio e tipografico, dove si vuole un gesto che si sente senza disegni intorno: il numero stesso dice quanto è grande il gruppo.
Il numero si rimpicciolisce con la larghezza dello schermo (al massimo il 30% della sua larghezza), così a 390 pixel 12 nerissimo e largo sta fra i due pulsanti e niente sfora. Il dito fa come il mouse: un tocco su un pulsante conta uno e disegna l’anello, tenuto premuto ripete sempre più in fretta, un tocco su una tacca porta il numero lì e trascinando lungo la riga lo si sceglie, mentre lo scorrimento in verticale della pagina resta libero. Il tocco lungo non apre menu e due tocchi veloci non ingrandiscono la pagina.
Niente cadute, rimbalzi, scossoni o corde che vibrano: il numero nuovo compare in dissolvenza al suo posto mentre il vecchio si dissolve, il peso cambia senza andare oltre, le tacche si accendono subito e la nota cambia con una dissolvenza. Tasti, pulsanti e riga funzionano come sempre.
GSAP 3.15.0, Archivo (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 11 KB; le librerie: GSAP 28 KB.
Provata il 16 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.