
Il pulsante d’invio
Pulsanti, Transizioni, SVG
NuovaGratis
Gli ordini all’ingrosso di una torrefazione, con un filtro dove ogni stato è una tasca. Cambiando filtro, gli ordini nuovi escono dalla loro tasca e si aprono al loro posto, fra le righe di prima che si scostano; poi ogni ordine che non c’entra più si stringe sulla sua etichetta di stato, l’etichetta vola nella sua tasca, sparisce dietro il bordo e la tasca la prende con una mossa sua (la fiamma guizza, il sacchetto si gonfia, il furgone molleggia), e la tabella si stringe. Mai vuota, ferma in meno di un secondo. Aperto, un ordine mostra la curva di tostatura del suo lotto, disegnata col colore dei chicchi a ogni temperatura.
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 table with pockets</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/bricolage-grotesque@5.3.0/standard.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the table with pockets: a coffee roastery's wholesale orders. Every status tab is a pocket: filtering, the
orders that do not belong close in on their status label and the label flies into its pocket; choosing a
pocket, its orders come out and open up in their places. An order opens on the roast curve of its batch -->
<section class="orders" aria-labelledby="orders-title" data-orders data-autoclic>
<header class="orders__head">
<h2 class="orders__title" id="orders-title">Wholesale orders</h2>
<p class="orders__note">Roasted this week</p>
</header>
<div class="tabs" role="group" aria-label="Show orders" data-tabs>
<span class="tabs__knob" aria-hidden="true" data-knob></span>
<button class="tab" type="button" aria-pressed="true" data-filter="all">
<span class="tab__in">
<span class="tab__label">All</span>
<span class="tab__count" data-count></span>
</span>
</button>
<button class="tab tab--roasting" type="button" aria-pressed="false" data-filter="roasting">
<span class="tab__in">
<span class="tab__icon" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M12 3.2c1.3 3.4 5.8 5.6 5.8 11a5.8 5.8 0 0 1-11.6 0c0-2.8 1.5-4.6 2.9-5.8.2 1.8.9 2.8 1.9 3.2-.5-3 .1-5.8 1-8.4z"/><path d="M12 20.2a2.5 2.5 0 0 1-2.5-2.5c0-1.5 1.2-2.4 2-3.6.4 1.1 1.1 1.7 1.8 2.1.7.4 1.2 1 1.2 1.6a2.5 2.5 0 0 1-2.5 2.4z"/></svg></span>
<span class="tab__label">Roasting</span>
<span class="tab__count" data-count></span>
</span>
</button>
<button class="tab tab--packed" type="button" aria-pressed="false" data-filter="packed">
<span class="tab__in">
<span class="tab__icon" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M6.3 8.6h11.4v10.6a1.4 1.4 0 0 1-1.4 1.4H7.7a1.4 1.4 0 0 1-1.4-1.4z"/><path d="M6.9 8.6 7.8 3.8h8.4l.9 4.8"/><path d="M10 6.2h4"/><circle cx="12" cy="13.6" r="1.9"/></svg></span>
<span class="tab__label">Packed</span>
<span class="tab__count" data-count></span>
</span>
</button>
<button class="tab tab--shipped" type="button" aria-pressed="false" data-filter="shipped">
<span class="tab__in">
<span class="tab__icon" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M2.8 6.4h11v10.2h-11z"/><path d="M13.8 9.6h3.9l3.5 3.6v3.4h-7.4"/><circle cx="7" cy="17.4" r="1.9"/><circle cx="17.2" cy="17.4" r="1.9"/></svg></span>
<span class="tab__label">Shipped</span>
<span class="tab__count" data-count></span>
</span>
</button>
</div>
<div class="sheet" data-sheet>
<table class="table" aria-labelledby="orders-title" data-table>
<thead>
<tr>
<th class="c-cafe" scope="col">Café</th>
<th class="c-coffee" scope="col">Coffee</th>
<th class="c-kg num" scope="col">Weight</th>
<th class="c-total num" scope="col">Total</th>
<th class="c-state" scope="col">Status</th>
</tr>
</thead>
<tbody data-rows></tbody>
</table>
</div>
<div class="flight" aria-hidden="true" data-flight></div>
<p class="sr" aria-live="polite" data-live></p>
</section>
</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.
114 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 «La tabella con le tasche» da Animorio e adattala al mio sitoOgni ordine ha un posto nella tabella: row (la riga vera), wait (il posto tenuto, invisibile, mentre la sua etichetta arriva), hold (il posto tenuto mentre la finestra si chiude), free (il posto vuoto, l’etichetta è partita) e none (in tasca). Al cambio di filtro la tabella passa per l’unione dei due elenchi, nell’ordine dei dati: i posti degli ordini che arrivano compaiono, invisibili (visibility hidden), fra le righe di prima, che scivolano per far posto con una trasformazione sul tr. Gli ordini che arrivano escono subito dalla tasca; quelli che vanno via restano righe vere finché l’ultimo nuovo sta per atterrare (e mai oltre il momento in cui il primo comincia ad aprirsi, così c’è sempre una riga da leggere). Poi, una volta sola, i posti vuoti spariscono e le righe salgono. I due stormi non volano mai insieme.
Una riga che va via è sostituita, nello stesso fotogramma, da una copia (la riga clonata in una tabella con le stesse colonne, lette dalle intestazioni in un colgroup, e la sua tostatura se era aperta) dentro una finestra: un div con overflow hidden i cui bordi vanno da quelli della riga a quelli dell’etichetta in CLOSE secondi, mentre la copia sfuma e il fondo prende la tinta dell’etichetta. L’etichetta vola su una Bézier cubica col primo punto di controllo dritto sopra la partenza e il secondo dritto sotto la tasca (SWING della salita): parte e arriva in verticale, si inclina fino a 8 gradi verso dove va, si alza verso chi guarda fino al 28% in più con la sua ombra, in FLY secondi (più o meno secondo la strada), accelerando verso la tasca e frenando verso la riga.
Lo strato delle etichette in volo sta sopra la tabella e sotto le tasche (z-index): l’etichetta passa dietro il bordo di sotto del binario e lì sparisce, senza dissolvenza. La tasca la prende: il suo contenuto salta di 3 pixel con un back.out in 0,22 secondi (un filtro si usa tante volte di fila), il conto si gonfia, e l’icona fa la sua mossa, la fiamma si allunga dalla base, il sacchetto si schiaccia, il furgone sobbalza inclinandosi sulle ruote di dietro. Le mosse sono sull’svg, la pressione del pulsante (scale 0,96) sul pulsante: un elemento per GSAP e uno per il CSS.
Un clic a metà riprende ogni ordine da dov’è: un’etichetta che stava arrivando torna in tasca (il suo posto si libera), una che stava andando via torna al suo posto (se la finestra si stava ancora chiudendo, si riapre lì), una riga che doveva ancora partire viene decisa di nuovo; se la meta di un’etichetta non è cambiata, continua per la sua strada. Un clic su una riga durante il cambio aspetta che la tabella sia ferma. Coi valori di partenza, misurati fotogramma per fotogramma: le prime righe nuove si leggono fra 250 e 333 millisecondi, la tabella è ferma entro 750 e tutto, tasche comprese, entro 900.
Costruita alla larghezza vera del suo riquadro, così le scritte restano alla loro misura. La temperatura dei chicchi è una curva di Hermite cubica che passa per la carica (200 gradi), il punto di svolta (92 gradi a 1:15), l’ingiallimento (150), il first crack (196) e lo scarico, con le pendenze prese dai ritmi di salita vicini, che quindi rallentano come in un tamburo vero; un punto ogni 4 secondi. A ogni fotogramma si ridisegna fino a q della strada: la linea, l’area sotto, un filo verticale e la temperatura sulla punta. L’area ha un gradiente con una fermata ogni ventiquattresimo del tempo, del colore del chicco alla temperatura di quel momento (verde, giallo, cannella al first crack, marroni), e una maschera che la schiarisce verso il fondo. Per un ordine ancora nel tamburo la curva si ferma ad adesso e il resto del piano compare tratteggiato.
Una table con th scope col e scope row, il nome del caffè è un pulsante con aria-expanded e aria-controls sulla riga del dettaglio, le tasche sono pulsanti con aria-pressed in un gruppo (le frecce passano dall’una all’altra), una regione aria-live dice Showing 2 packed orders, Esc chiude il dettaglio. La tabella tiene l’altezza di tutte le sue righe (min-height), così quello che viene dopo non salta. Un clic da script (l’anteprima della libreria) fa il giro: Shipped e apre Copper Pot, Packed, All, Roasting e apre Tamarind House, chiude e All.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
ORDERS | script.js | [['Little Owl Café', 'Huila, Colombia', 12, 318, 'packed'], …] | Gli ordini: caffè, origine, chili, totale in euro e stato (roasting, packed o shipped). |
ROASTS | script.js | [['Medium', '8:52', '10:40', 212, 'Red apple, panela', 'Thu 8 Oct'], …] | La tostatura di ogni ordine: livello, first crack, scarico (minuti:secondi), temperatura di scarico, cosa c’è nella tazza, consegna e, per quelli ancora nel tamburo, da quanto ci sono. |
FLY | script.js | 0.28 | I secondi del volo di un’etichetta verso la sua tasca, o fuori. |
CLOSE | script.js | 0.12 | I secondi in cui una riga si stringe sulla sua etichetta (e poco di più per riaprirsi). |
STAGGER | script.js | 0.025 | I secondi fra la partenza di un ordine e del successivo. |
SWING | script.js | 0.45 | Quanto sale dritta un’etichetta prima di piegare verso la tasca, in parte della salita: 0 è una linea dritta. |
DRAW | script.js | 1.3 | I secondi in cui si disegna la curva di tostatura. |
Per gli ordini di un negozio all’ingrosso, le spedizioni di un magazzino, le pratiche di uno studio, i ticket di un’assistenza, le candidature di un annuncio: ogni elenco diviso per stato, dove aiuta vedere dove sono andate le righe che il filtro nasconde.
A 390 pixel le colonne Coffee e Weight scompaiono e passano sotto il nome del caffè (la regione e i chili); le etichette si stringono all’86% con l’asse della larghezza di Bricolage Grotesque, le righe sono alte 62 pixel e le quattro tasche si dividono la larghezza, alte 44, con le parole e i conti (le icone restano nelle etichette). La tostatura va sopra i suoi dati. Le animazioni sono le stesse: le etichette salgono lungo la colonna degli stati fino alle tasche.
Niente vola e niente scivola: le righe che escono spariscono, quelle che entrano compaiono sfumando al loro posto, la pillola è subito sotto la tasca scelta e la tostatura si apre già disegnata, con una dissolvenza.
GSAP 3.15.0, Bricolage Grotesque (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 17 KB; le librerie: GSAP 28 KB.
Provata il 7 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.