
Il pulsante che copia
Pulsanti, Testo, SVG, Fisica
NuovaGratis
Il pulsante Add to bag di un negozio, nello stile minimal: una pillola nera con le lettere composte come caratteri mobili. Al clic la parola si ricompone in quella nuova lettera per lettera: le lettere in comune restano e scivolano al loro posto (la g di bag corre fino in fondo ad Adding), le altre escono e cadono dentro una dopo l’altra, mentre l’asse della larghezza del carattere tiene ogni parola vicina alla stessa misura e la pillola fa il resto su una molla. Poi Added to bag, con la spunta disegnata in vermiglio.
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 button that recomposes the word</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 frame keeps the room of the widest word, so the preview never has to move -->
<div class="frame" data-frame>
<!-- the button: a black pill whose letters are movable type. Pressed, the word recomposes itself into the next
one: the letters the two words share slide to their new place, the others leave and arrive one after the
other, and the width axis of the typeface keeps every word near the same measure. The letters and the
tick are laid out by the script on every frame -->
<button class="bag" type="button" aria-label="Add to bag" data-bag data-autoclic>
<span class="bag__pill" aria-hidden="true" data-pill>
<span class="bag__line" data-line>
<svg class="bag__tick" viewBox="0 0 20 20" data-tick><path d="M4.2 10.6l3.7 3.6 7.9-8.4" pathLength="1" data-tick-path/></svg>
</span>
</span>
</button>
</div>
<p class="sr" role="status" aria-live="polite" data-said></p>
<!-- a hidden copy of the type, to measure every letter at every width and weight -->
<div class="ruler" aria-hidden="true" data-ruler></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.
23 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 che ricompone la parola» da Animorio e adattala al mio sitoPer sapere quali lettere restano, lo script cerca la sottosequenza comune più lunga fra la parola di prima e quella nuova, con la tabella della programmazione dinamica, e la percorre dall’inizio prendendo sempre la coppia più a sinistra. Così fra Add to bag e Adding restano A, d, d e g, fra Added to bag e Add to bag restano tutte tranne la e e la d. Le lettere in comune non si incrociano mai, perché la sottosequenza tiene il loro ordine: fra due lettere che restano si mettono prima quelle che escono, poi quelle che entrano, e la riga è una sola fila di lettere in viaggio.
Mona Sans è un carattere variabile con l’asse della larghezza (da 75 a 125) e del peso. All’avvio un righello nascosto scrive ogni lettera delle tre parole a cinque larghezze e cinque pesi e ne misura l’avanzamento con getBoundingClientRect; l’avanzamento a una larghezza e a un peso qualsiasi si ricava interpolando fra i quattro valori vicini. Le lettere sono elementi separati, che perdono la crenatura: le coppie (Ad, to, ba…) si misurano su un canvas nello stesso carattere, ab meno a meno b, e si rimettono a mano.
Per ogni parola lo script cerca per bisezione la larghezza dell’asse che la fa lunga MEASURE pixel, dentro AXIS: Add to bag sta poco sopra 100, Added to bag scende fino a 78. Adding è troppo corta per arrivarci, e si ferma prima del massimo per lasciare all’onda lo spazio di allargarsi. Ogni lettera che resta passa alla larghezza nuova mentre scivola, e quella che entra arriva già alla sua.
Ogni lettera è un insieme di numeri che GSAP muove: larghezza, peso, altezza, trasparenza e presenza, cioè quanto è aperto il suo posto nella riga. A ogni fotogramma una funzione sul ticker di GSAP somma gli avanzamenti moltiplicati per la presenza, centra la riga e mette ogni lettera al suo posto con un translate3d e la sua font-variation-settings. Una lettera che esce chiude il suo posto e una che entra lo apre spingendo le vicine, senza salti; mentre entra o esce è larga quanto il suo posto (scaleX uguale alla presenza), così non copre mai le vicine. La g che corre in fondo non ha un’animazione sua: si sposta perché la riga si ricompone intorno a lei.
La larghezza della pillola è quella della riga più il margine, ma non la segue di colpo: è una molla smorzata (rigidezza e smorzamento in SPRING) integrata a mezzo passo, col passo di tempo limitato a 1/30 di secondo. Anche l’altezza ha la sua molla: 60 a riposo, un po’ di più sotto il puntatore, un po’ meno sotto il dito, e mentre la larghezza corre la pillola si abbassa di un pelo, al massimo 2,5 pixel. Quando molle e tween sono fermi il ticker si toglie da solo; ogni timeline lo risveglia dal suo onUpdate.
Il clic passa ad Adding e mette il pulsante in aria-busy; dopo WAIT secondi viene Added to bag, dopo HOLD si torna ad Add to bag, e un clic durante il giro non fa niente. Un testo nascosto con role=status dice Adding to bag e Added to bag. L’onda di Adding è una campana che corre lungo la parola, ripetuta senza fine: ogni lettera si allarga di WAVE[0] e prende peso quando la campana le passa sopra; il cambio di parola la spegne in tre decimi di secondo.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
WORDS | script.js | ['Add to bag', 'Adding', 'Added to bag'] | Le tre parole: a riposo, mentre il negozio lavora, a cosa fatta (con la spunta davanti). Più lettere hanno in comune, più la ricomposizione è bella. |
WAIT | script.js | 2.2 | I secondi di Adding; in un negozio vero, il tempo che il carrello ci mette a rispondere. |
HOLD | script.js | 1.8 | I secondi in cui resta Added to bag prima di tornare ad Add to bag. |
MEASURE | script.js | 96 | La larghezza in pixel a cui l’asse del carattere prova a tenere ogni parola. |
AXIS | script.js | [78, 125] | Quanto possono stringersi e allargarsi le lettere per tenere la misura (Mona Sans va da 75 a 125). |
WEIGHT | script.js | [600, 780] | Il peso delle lettere, e il peso che prende per un attimo una lettera quando tocca la riga. |
MOVE | script.js | 0.75 | I secondi di una ricomposizione. |
STAGGER | script.js | 0.045 | I secondi fra una lettera che entra e la successiva (quelle che escono vanno un po’ più svelte). |
DROP | script.js | 15 | I pixel di cui cade una lettera che esce, e da cui cade una lettera che entra. |
WAVE | script.js | [30, 0.95] | L’onda di Adding: di quanto si allarga una lettera quando l’onda le passa sopra, e i secondi di un passaggio. |
SPRING | script.js | [520, 0.62] | La molla della pillola: la rigidezza e lo smorzamento (sotto 1 va un po’ oltre e torna). |
SWELL | script.js | 8 | I pixel di cui si gonfia la pillola sotto il puntatore. |
Per il pulsante che mette un prodotto nel carrello, e in genere per ogni azione con un’attesa e un esito (Save, Saving, Saved; Send, Sending, Sent): funziona meglio quando le parole dei tre stati hanno molte lettere in comune. Serve un carattere variabile con l’asse della larghezza: con un carattere fisso le lettere si ricompongono lo stesso, ma la misura la tiene solo la pillola.
La pillola è la stessa, alta 60, e sta comoda nei 390 pixel anche con Added to bag. Senza puntatore non c’è il gonfiarsi dell’hover: il tocco schiaccia la pillola e la rilascia sulla molla, e fa partire il giro intero, con le stesse animazioni del computer.
Niente lettere che cadono o scivolano, niente onda e niente molla: a ogni cambio la riga sfuma, la parola nuova si compone al suo posto con la pillola già della misura giusta e la riga torna. Durante Adding la scritta pulsa piano di trasparenza, e la spunta compare già disegnata.
GSAP 3.15.0, Mona Sans (font variabile, con gli assi del peso e della larghezza) 5.3.0.
Compressi con gzip, i tre file della demo pesano 8,8 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.