Vai al contenuto
animorio
EN
Tutti i componenti

Il favo che si riempie

Caricamento, Fisica, TransizioniCanvas, GSAPImpegnativaPeso compresso: Demo 14 KBGSAP 28 KBGratisScarica lo zip

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.

Il codice

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>

Playground

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

Oppure chiedila a Claude Code

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 sito

Cosa fa

Su un fondo nero, da solo al centro, un pezzo di favo di cera dorata largo 380 pixel: una cinquantina di celle esagonali vuote e scure, con un po’ di luce che passa dal fondo sottile di cera, e intorno le celle a metà costruite che sfumano nel buio. Gli angoli delle celle sono spostati di poco, come in un favo vero. Sotto ci sono contacts.csv, 2,400 contacts · 418 KB e la pillola Import contacts. Puntando la pillola, nella cella al centro si raccoglie una goccia di miele, pronta a scendere. Premuta, l’importazione parte: la riga dice Importing contacts, sotto i contatti arrivati (1,282 of 2,400 contacts), a destra la percentuale grande, e la pillola diventa Cancel col solo contorno. Ogni cella è un blocco di circa 47 contatti, e quattro blocchi viaggiano insieme: in ogni cella scende un filo di miele che ondeggia appena, e il miele sale dal fondo con un piccolo cumulo dove il filo lo tocca e il menisco che si arrampica sulle due pareti, con una riga di luce sulla superficie. Il miele è chiaro vicino alla superficie e diventa ambra scura sul fondo, più scuro ancora lungo le pareti, e la luce che lo attraversa si raccoglie in basso al centro come in una lente. Quando il blocco è arrivato il filo si assottiglia e la sua coda cade dentro la cella; piena la cella, un opercolo di cera la chiude dalle pareti verso il centro, come un diaframma, e alla fine si gonfia con un piccolo rimbalzo e un lampo di luce sulla cupola. Le celle si riempiono a spirale dal centro, così il favo sigillato cresce come lo costruirebbero le api. Nella demo un’importazione ogni due si ferma a metà: in una cella il filo scende ma il miele non si raccoglie, il filo si spezza e il fondo di cera si incrina con quattro crepe rosse mentre la cella trema; i blocchi già in viaggio finiscono, la riga diventa Import paused in rosso con Rows 1,085–1,131 couldn’t be read, e la pillola dice Retry, che richiude le crepe e riempie la cella. Alla fine tutto il favo è sigillato, un riflesso caldo lo attraversa in diagonale e la riga diventa Import complete con una spunta che si disegna e 2,400 added · 37 duplicates merged. Import again fa sciogliere gli opercoli e scendere il miele dal bordo verso il centro e ricomincia; Cancel svuota il favo e torna a riposo.

Come funziona

La griglia esagonale, fatta a mano

Le 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°.

Il favo vuoto si dipinge una volta sola

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.

Il miele col menisco e la luce

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.

I blocchi e la densità

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.

Errore, fine e chi non vede

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.

Valori da cambiare

NomeFileDi partenzaCosa cambia
SECONDSscript.js7Quanto dura l’importazione della demo, in secondi (una vera segue i suoi blocchi).
CONTACTSscript.js2400I contatti da importare: si dividono fra le celle.
CELLscript.js19Il raggio di una cella, in unità del disegno largo 380: celle più piccole, più blocchi. Da 14 a 26.
WORKERSscript.js4Quanti blocchi si importano insieme, cioè quante celle si riempiono alla volta.
ORDERscript.js'spiral'L’ordine delle celle: 'spiral' a spirale dal centro, 'wave' a fronte d’onda da sinistra.
FAIL_EVERYscript.js2Nella demo, un’importazione ogni quante va storta (0 mai).
FAIL_ATscript.js0.45A che punto dell’importazione c’è il blocco che non si legge, da 0 a 1.
THICKscript.js0.22Quanto è denso il miele: i secondi che il livello ci mette a raggiungere i dati.
CAPscript.js0.34Quanto ci mette l’opercolo di cera a chiudere una cella piena, in secondi.
WORDSscript.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.
LABELSscript.js{ busy: 'Cancel', error: 'Retry', done: 'Import again' }Le scritte del pulsante negli stessi tre momenti; quella a riposo è in index.html.

Provali nel Playground

Quando usarla

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.

Sul telefono

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.

Con il movimento ridotto

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.

Trappole

  • Ridipingendo una cella, il suo esagono veniva prima cancellato con clearRect: sul bordo antialiasato restava un pixel mezzo trasparente e intorno alla cella compariva una cucitura scura. Il favo vuoto è opaco dentro ogni esagono, quindi basta copiarlo sopra senza cancellare.
  • Il lampo sulla cupola dell’opercolo era disegnato prima del contorno della cella: lo stroke() seguente ripassava l’ellisse appena fatta e su ogni cella compariva un anello grigio. Il lampo ora viene per ultimo.
  • Gli angoli spostati a caso staccavano le celle fra loro: ogni angolo va spostato con un hash della sua posizione arrotondata, non della cella, così le celle vicine lo spostano allo stesso modo.
  • Gli opercoli color crema, opachi, facevano del favo finito un pavimento di piastrelle chiare: ora la cera è un po’ trasparente sopra il miele e ogni cella ha una tinta leggermente diversa.
  • Il blocco fallito restava nella lista di quelli in viaggio e teneva il ciclo di disegno sveglio per sempre: nell’errore esce dalla lista e ci rientra con Retry, in testa.
  • Le cifre tabellari di Mona Sans hanno l’1 con la grazia e sembrano da macchina da scrivere: la percentuale e il conteggio usano le cifre normali.

Librerie

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.

Collaudo

Provata il 8 ottobre 2026

  • Computer: Fatto
  • Telefono: Fatto
  • Movimento ridotto: Fatto
  • Safari su iPhone: Da fare

Licenza d’uso

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.

Tutti i componenti