
Il pulsante da far scorrere
Pulsanti, Fisica, Transizioni
NuovaGratis
L’importazione di 2.400 contatti fatta come un pezzo di favo di cera: ogni cella è un blocco di contatti. Un filo di miele scende nella cella e il miele sale col suo menisco che si arrampica sulle pareti, chiaro dove è sottile e scuro dove è spesso; quando il blocco è arrivato un opercolo di cera chiude la cella dalle pareti verso il centro e si gonfia con un piccolo rimbalzo. Le celle si riempiono quattro alla volta a spirale dal centro. Se un blocco non si legge la sua cella resta vuota e la cera si incrina; alla fine un riflesso caldo attraversa il favo sigillato: Import complete.
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, viewport-fit=cover">
<title>The filling honeycomb</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/mona-sans@5.3.0/standard.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the filling honeycomb: a contacts import shown as a piece of wax comb. Every cell is a batch of contacts: it fills
with honey that rises with its meniscus, glowing where the light comes through, and when it is full a wax cap
closes over it from the walls inwards and swells a little. The cells fill in a spiral from the middle. The comb
is painted by script.js on the canvas, one cell at a time -->
<section class="favo" aria-label="Contacts import" data-favo>
<div class="favo__comb" role="progressbar" aria-label="Import progress" aria-valuemin="0" aria-valuemax="100"
aria-valuenow="0" aria-valuetext="Ready to import" data-comb>
<canvas class="favo__paint" aria-hidden="true" data-paint></canvas>
</div>
<div class="favo__info" aria-hidden="true">
<p class="favo__title">
<svg class="favo__tick" viewBox="0 0 24 24" data-tick><path d="M5.5 12.6l4.2 4.2 8.8-9.4" pathLength="1"/></svg>
<span class="favo__swap" data-title>contacts.csv</span>
</p>
<p class="favo__pct" data-pct>0%</p>
<p class="favo__meta"><span class="favo__swap" data-meta>2,400 contacts · 418 KB</span></p>
</div>
<div class="favo__buttons">
<button class="pill" type="button" data-go data-autoclic><span class="pill__label" data-label>Import contacts</span></button>
</div>
<p class="sr" role="status" 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.
39 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 favo che si riempie» da Animorio e adattala al mio sitoLe celle sono esagoni con la punta in alto su coordinate assiali: x = R·√3·(q + r/2), y = 1,5·R·r. Restano blocchi quelle il cui centro sta dentro un’ellisse più piccola del favo di un raggio; quelle fra le due ellissi sono celle a metà costruite, scurite verso il nero. Ogni angolo della griglia viene spostato di un valore preso da un hash della sua posizione arrotondata, quindi tutte le celle che lo condividono lo spostano allo stesso modo e il favo resta chiuso ma non perfetto. La parete è l’esagono interno, rimpicciolito verso il centro di WALL/2 ÷ cos 30°.
Cera, fondi, ombre delle pareti in alto e luce sulle pareti in basso vanno su un canvas a parte, all’apertura e a ogni cambio di misura. A ogni fotogramma si ridipingono solo le celle che sono cambiate: per ognuna si ritaglia il suo esagono, si copia sopra lo stesso pezzo del favo vuoto con drawImage e si disegnano miele, filo, opercolo e crepe. Le celle non si sovrappongono, quindi nessuna cella sporca le vicine. Solo il riflesso finale ridipinge tutto, per poco più di un secondo; quando niente si muove non si disegna niente.
La superficie è una funzione di x: il livello, meno il menisco che sale vicino alle pareti con due esponenziali (le pareti si trovano incrociando l’orizzontale col poligono interno), meno un cumulo gaussiano dove arriva il filo. Il poligono si riempie con un gradiente verticale che parte dalla superficie ed è sempre della stessa scala, così una cella appena iniziata è chiara e una piena va fino all’ambra scura: più miele, meno luce. Sopra vanno un gradiente radiale scuro verso le pareti, uno chiaro in modalità screen in basso al centro e due righe di luce sotto la superficie.
Le celle si ordinano per anello esagonale più l’angolo intorno al centro (una spirale) o, con ORDER = 'wave', per una retta inclinata più un po’ di rumore. WORKERS blocchi viaggiano insieme, ognuno con la sua durata e a volte una sosta. Il livello insegue i dati con un ritardo esponenziale di THICK secondi, ma con una velocità minima, altrimenti l’ultimo per cento non arriverebbe mai. Piena la cella, una timeline GSAP chiude l’opercolo come un diaframma (un esagono col buco esagonale, riempito con evenodd), poi lo gonfia del 5% e lo lascia tornare con elastic.out.
Il blocco che va storto fa scendere il filo per 0,7 secondi senza miele, poi si ferma: quattro crepe a zigzag calcolate da un hash crescono dal centro della cella mentre trema, e i blocchi in viaggio finiscono da soli. Retry richiude le crepe e rimette il blocco in testa alla coda. Il favo è un role=progressbar con aria-valuenow e aria-valuetext aggiornati al massimo ogni mezzo secondo, aria-busy mentre lavora e una riga aria-live per inizio, errore, fine e annullamento. I clic da script (quelli dell’anteprima della libreria) non annullano mai e ripartono solo dopo 2,4 secondi di Import complete.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
SECONDS | script.js | 7 | Quanto dura l’importazione della demo, in secondi (una vera segue i suoi blocchi). |
CONTACTS | script.js | 2400 | I contatti da importare: si dividono fra le celle. |
CELL | script.js | 19 | Il raggio di una cella, in unità del disegno largo 380: celle più piccole, più blocchi. Da 14 a 26. |
WORKERS | script.js | 4 | Quanti blocchi si importano insieme, cioè quante celle si riempiono alla volta. |
ORDER | script.js | 'spiral' | L’ordine delle celle: 'spiral' a spirale dal centro, 'wave' a fronte d’onda da sinistra. |
FAIL_EVERY | script.js | 2 | Nella demo, un’importazione ogni quante va storta (0 mai). |
FAIL_AT | script.js | 0.45 | A che punto dell’importazione c’è il blocco che non si legge, da 0 a 1. |
THICK | script.js | 0.22 | Quanto è denso il miele: i secondi che il livello ci mette a raggiungere i dati. |
CAP | script.js | 0.34 | Quanto ci mette l’opercolo di cera a chiudere una cella piena, in secondi. |
WORDS | script.js | { busy: 'Importing contacts', error: 'Import paused', done: 'Import complete' } | Le scritte sotto il favo mentre importa, nell’errore e alla fine; quella a riposo è in index.html. |
LABELS | script.js | { busy: 'Cancel', error: 'Retry', done: 'Import again' } | Le scritte del pulsante negli stessi tre momenti; quella a riposo è in index.html. |
Per l’importazione di contatti in un CRM o in una newsletter, il caricamento di un CSV in un foglio o in un database, la sincronizzazione di una rubrica, l’indicizzazione di documenti o qualunque lavoro diviso in blocchi paralleli dove vale la pena vedere quali blocchi sono finiti e quale si è fermato. Il favo sta bene anche in un prodotto dal tono caldo e artigianale.
Il favo è largo 380 pixel e sul telefono prende la larghezza dello schermo meno 16 pixel per lato (358 a 390): il disegno scala con la larghezza e le celle restano le stesse. La pillola è alta 44 e si usa col tocco; la goccia che si raccoglie puntando la pillola e la pillola che si gonfia ci sono solo col mouse o con la tastiera.
Niente filo, niente miele che sale, niente diaframma né rimbalzo: il miele di ogni cella compare con una dissolvenza quando il blocco arriva, poi l’opercolo si posa con una dissolvenza. Le crepe compaiono intere con una dissolvenza, senza tremare, e alla fine niente riflesso: compare la spunta. Le parole cambiano con una dissolvenza.
GSAP 3.15.0, Mona Sans (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 14 KB; le librerie: GSAP 28 KB.
Provata il 8 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.