
Il pulsante d’invio
Pulsanti, Transizioni, SVG
NuovaGratis
L’indirizzo di consegna nel checkout di un negozio: nome, via, città, codice postale controllato sulla forma del paese scelto, e paese. Con tutto a posto la scheda stessa diventa l’etichetta di spedizione: i bordi dei campi svaniscono, la scheda si stringe e prende le righe nere di un’etichetta, le parole volano dai campi alle loro righe cambiando misura e peso, il percorso si batte nel riquadro nero e una testina di stampa passa sull’etichetta e stampa un vero codice a barre Code 128.
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 address that becomes a label</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/geist@5.3.0/index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/geist-mono@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the delivery address of a checkout: with every field right, the card turns into the shipping label, the words
fly from the fields to their lines and a real Code 128 barcode is printed under them. Sending is pretended:
see post() in the script -->
<div class="ship" data-ship data-autoclic>
<div class="sheet" data-sheet>
<form class="addr" action="#" novalidate aria-labelledby="ship-title" data-form>
<h2 class="addr__title" id="ship-title">Delivery address</h2>
<div class="field" data-field="name">
<label class="field__label" for="ship-name">Full name</label>
<div class="field__box" data-box>
<input class="field__input" id="ship-name" name="name" type="text" autocomplete="shipping name" autocapitalize="words" spellcheck="false" enterkeyhint="next" maxlength="40" aria-describedby="ship-name-err" aria-invalid="false" data-input>
<span class="field__caret" aria-hidden="true" data-caret></span>
</div>
<p class="field__err" id="ship-name-err" data-err></p>
</div>
<div class="field" data-field="street">
<label class="field__label" for="ship-street">Street and number</label>
<div class="field__box" data-box>
<input class="field__input" id="ship-street" name="street" type="text" autocomplete="shipping address-line1" spellcheck="false" enterkeyhint="next" maxlength="48" aria-describedby="ship-street-err" aria-invalid="false" data-input>
<span class="field__caret" aria-hidden="true" data-caret></span>
</div>
<p class="field__err" id="ship-street-err" data-err></p>
</div>
<div class="addr__row">
<div class="field" data-field="city">
<label class="field__label" for="ship-city">Town or city</label>
<div class="field__box" data-box>
<input class="field__input" id="ship-city" name="city" type="text" autocomplete="shipping address-level2" spellcheck="false" enterkeyhint="next" maxlength="32" aria-describedby="ship-city-err" aria-invalid="false" data-input>
<span class="field__caret" aria-hidden="true" data-caret></span>
</div>
<p class="field__err" id="ship-city-err" data-err></p>
</div>
<div class="field field--post" data-field="post">
<label class="field__label" for="ship-post">Postcode</label>
<div class="field__box" data-box>
<input class="field__input" id="ship-post" name="post" type="text" autocomplete="shipping postal-code" autocapitalize="characters" autocorrect="off" spellcheck="false" enterkeyhint="next" maxlength="10" aria-describedby="ship-post-err" aria-invalid="false" data-input>
<span class="field__caret" aria-hidden="true" data-caret></span>
</div>
<p class="field__err" id="ship-post-err" data-err></p>
</div>
</div>
<div class="field field--country" data-field="country">
<label class="field__label" for="ship-country">Country</label>
<div class="field__box" data-box>
<select class="field__input field__select" id="ship-country" name="country" autocomplete="shipping country" data-country>
<option value="GB">United Kingdom</option>
<option value="IE">Ireland</option>
<option value="IT">Italy</option>
<option value="DE">Germany</option>
<option value="FR">France</option>
<option value="US">United States</option>
</select>
<svg class="field__chev" viewBox="0 0 12 12" aria-hidden="true"><path d="M2.5 4.5 6 8l3.5-3.5"/></svg>
</div>
</div>
<div class="addr__foot">
<button class="send" type="submit" data-send>
<span class="send__bg" aria-hidden="true"></span>
<span class="send__label">Ship here</span>
</button>
</div>
</form>
<!-- the label the card turns into: drawn for the eye, the form above stays the real thing -->
<div class="label" aria-hidden="true" data-label>
<div class="label__from">
<span class="label__cap">From</span>
<span>Larkspur Goods · Unit 4, Mill Lane · Bristol</span>
</div>
<div class="label__main">
<div class="label__to">
<span class="label__cap">Ship to</span>
<span class="label__line label__line--name" data-to="name"></span>
<span class="label__line" data-to="street"></span>
<span class="label__line label__line--city"><span data-to="city"></span> <span data-to="post"></span></span>
<span class="label__line label__line--country" data-to="country"></span>
</div>
<div class="label__sort" data-sort>
<span class="label__cap label__cap--inv">Route</span>
<span class="label__route" data-route></span>
</div>
</div>
<div class="label__code">
<svg class="label__bars" data-bars preserveAspectRatio="none"></svg>
<span class="label__head" data-head></span>
<span class="label__track" data-track></span>
</div>
</div>
</div>
<div class="ship__after" data-after>
<p class="after__line"><span data-after-text>Arrives Thursday, tracked all the way.</span> <button class="after__change" type="button" data-change>Change</button></p>
</div>
<p class="sr" role="status" 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.
33 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 «L’indirizzo che diventa etichetta» da Animorio e adattala al mio sitoOgni campo ha la sua label, autocomplete di spedizione, aria-invalid e aria-describedby alla riga sotto. Il codice postale si controlla con la forma del paese scelto (Regno Unito, Irlanda, Italia, Germania, Francia, Stati Uniti), diventa maiuscolo mentre scrivi senza spostare il cursore e prende lo spazio giusto quando lo lasci. La riga dell’errore ha un’altezza sua che si apre e si chiude con un tween, quindi i campi sotto scendono e risalgono morbidi.
All’invio, su ogni campo si posa una copia delle sue parole nello stesso carattere e nella stessa posizione, e le parole vere diventano trasparenti. Le righe dell’etichetta, già riempite ma invisibili, danno la meta: x, il centro della riga, la misura e il peso. Ogni copia vola con x, y, scale e fontWeight su un’unica timeline, sfalsata di STAGGER; a metà volo le righe in maiuscolo prendono le maiuscole, e all’arrivo la copia lascia il posto alla riga vera.
Nello stesso momento i nomi e i bordi dei campi svaniscono, l’altezza della scheda va da quella del modulo a quella dell’etichetta, gli angoli da 20 a 6 pixel, il bordo dal grigio al nero con un’ombra: la scheda non viene sostituita, cambia mestiere. Il ritorno fa il volo al contrario, partendo dalla riga più bassa, così le parole che scendono non incrociano quelle che aspettano sopra.
Il numero di tracciamento nasce dall’indirizzo (un hash FNV delle righe, nove cifre, fra le due lettere del mittente e il paese). Il codice a barre è Code 128 set B: l’inizio, ogni carattere con le sue sei larghezze di barra e spazio, il carattere di controllo (somma pesata modulo 103) e la fine, con dieci moduli di silenzio ai lati. Le barre sono rettangoli SVG su una viewBox in moduli, larghe un numero intero di pixel (MODULE) e con shape-rendering crispEdges, quindi si leggono.
La stampa è un oggetto da 0 a 1 portato da GSAP in PRINT secondi, senza ease: a ogni passo il clip-path del codice a barre si apre da sinistra fino a quel punto e la riga arancione della testina sta lì, mentre il numero si batte carattere per carattere al ritmo della testina. Nel riquadro Route si battono l’inizio e la fine del codice postale.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
FLIGHT | script.js | 0.8 | I secondi che le parole impiegano a volare dai campi all’etichetta. |
STAGGER | script.js | 0.07 | I secondi fra la partenza di una parola e quella dopo. |
PRINT | script.js | 0.9 | I secondi che la testina impiega ad attraversare il codice a barre. |
MODULE | script.js | 2 | La larghezza della barra più sottile, in pixel (scende se l’etichetta è stretta). |
SENDER | script.js | LG | Le due lettere con cui comincia il numero di tracciamento. |
WAIT | script.js | 0.5 | Quanti secondi dura il salvataggio finto dell’indirizzo. |
Nel passo della consegna di un checkout, in un negozio che spedisce: l’etichetta dice a chi compra, meglio di un riepilogo, che l’indirizzo è giusto e dove andrà il pacco. Va bene anche nella pagina degli indirizzi di un account o in un’app di spedizioni.
La scheda prende la larghezza dello schermo (358 pixel su un telefono di 390), città e codice postale restano affiancati, i campi sono alti 46 pixel e i caratteri 16, quindi Safari non ingrandisce. Il codice postale apre la tastiera con le maiuscole, Country apre il selettore del telefono. Sull’etichetta il riquadro del percorso si stringe e il codice a barre resta a moduli interi, centrato.
Niente voli, niente scatti e niente testina: le righe degli errori compaiono in dissolvenza, e all’invio il modulo svanisce e l’etichetta compare già stampata, col codice a barre e il numero interi. Change fa lo stesso al contrario.
GSAP 3.15.0, Geist (font variabile) 5.3.0, Geist Mono (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 12 KB; le librerie: GSAP 28 KB.
Provata il 19 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.