
Il menu a mazzetta di colori
Menu, Fisica, Transizioni, Hover
NuovaGratis
Il timer di un’app di meditazione, dove una seduta dura quanto un bastoncino d’incenso: il bastoncino brucia nella sua ciotola di celadon mentre il tempo scende, il fumo sale in fili che ondeggiano e si arricciano, la cenere cresce sulla punta e cade nella ciotola, e una mano passata nel fumo lo scompiglia. A zero la brace si spegne e un bastoncino nuovo sale dalla cenere.
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 incense timer</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/newsreader@5.3.0/opsz.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the incense timer: a sitting lasts as long as a stick of incense. The stick burns down in its bowl while the
smoke rises in threads that curl, the ash grows on the tip and drops into the bowl, and a hand passing
through the smoke stirs it -->
<section class="sit" aria-label="Meditation timer" data-timer>
<div class="sit__scene" data-scene>
<canvas class="sit__canvas" aria-hidden="true" data-canvas></canvas>
</div>
<div class="sit__readout">
<span class="sit__time" role="timer" aria-atomic="true" data-time-box>
<span class="sit__digits" aria-hidden="true" data-time></span>
<span class="sr" data-time-words></span>
</span>
<span class="sit__state" aria-hidden="true" data-state></span>
</div>
<div class="sit__controls" data-controls>
<button class="sit__reset" type="button" aria-label="Start over" aria-disabled="true" data-reset>
<span class="sit__turn">
<svg viewBox="0 0 24 24" aria-hidden="true" data-reset-icon><path d="M5.6 9.2A7.2 7.2 0 1 1 4.9 14.2"/><path d="M5.2 4.6v4.8H10"/></svg>
</span>
</button>
<button class="sit__go" type="button" data-go data-autoclic>
<span class="sit__words" data-go-words></span>
</button>
<span class="sit__balance" aria-hidden="true"></span>
</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.
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 timer a incenso» da Animorio e adattala al mio sitoDalla brace escono tre fili di sbuffi, RATE al secondo ciascuno, quasi dallo stesso punto. Ogni sbuffo sale a RISE pixel al secondo e viene portato dal rotore (curl) di un rumore di Perlin in 3D a due ottave: un campo che gira ma non raccoglie e non disperde, come l’aria. Il rumore scorre verso l’alto insieme al fumo, così i riccioli salgono con lui. Appena uscito dalla punta il campo pesa poco e il fumo sale dritto; più in alto pesa di più (SWIRL) e il filo ondeggia e si arriccia. I tre fili leggono il rumore un poco sfalsato nel tempo, quindi partono insieme e si separano salendo. Ogni sbuffo nasce dove sarebbe stato nel suo istante esatto dentro il fotogramma, così sono tutti alla stessa distanza.
Gli sbuffi di un filo si uniscono nell’ordine in cui sono nati. Un tratto stirato è un filo più sottile, quindi sfuma; la distanza è smussata sui vicini, per non far tremolare la trasparenza da un giunto all’altro. Ogni tratto va in un gruppo per età e trasparenza (un Path2D per gruppo) e si disegna in modo additivo, coi capi piatti. Il corpo morbido del fumo è lo stesso disegno, largo, su un canvas grande un quarto, stirato sopra il quadro: la sfocatura viene gratis. Invecchiando il filo netto sparisce prima del corpo morbido, e il colore passa dall’azzurro al grigio, come nel fumo vero.
Il puntatore (mouse o dito) lascia dei soffi: un punto, la velocità della mano, un raggio che si allarga e una forza che si spegne in un terzo di secondo. Gli sbuffi vicini vengono spinti nel verso della mano e girati in un vortice. Il verso del vortice dipende dal lato del passaggio su cui si trova lo sbuffo, quindi ne nascono due, come nella scia vera. Un soffio vicino alla punta ravviva la brace e il fumo per qualche istante (HAND).
La cenere cresce sulla punta quanto la parte bruciata, con un bordo irregolare e un po’ storta. Arrivata a una lunghezza scelta a caso in ASH, si piega sulla brace come un’asta sul suo piede (accelerazione 3g/2L per il seno dell’angolo) e, passati i 35 gradi, si stacca con la velocità che aveva e cade girando. Dove tocca la cenere della ciotola si sbriciola in pezzetti che rimbalzano una volta; fermi, si disegnano su un canvas a parte che si sovrappone alla ciotola, così restano senza costare niente.
Il tempo che resta viene dall’orologio (performance.now), non dai fotogrammi, quindi una scheda rimasta in background finisce comunque in orario. La parte bruciata è il tempo passato. Begin è una timeline GSAP: fiammella, brace, la fiammella che si spegne e lo sbuffo. Pause porta la brace a un rosso spento e il fumo a zero, la fine fa ravvivare la brace e la spegne, e una timeline affonda il mozzicone (la parte sotto la cenere è tagliata via) e fa risalire il bastoncino nuovo con un back.out. Le parole e le cifre cambiano salendo e sfocandosi. Il clic dell’anteprima (detail 0) fa solo cominciare e riprendere, mai mettere in pausa.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
SECONDS | script.js | 15 | Quanto dura una seduta: il bastoncino brucia in questi secondi (breve per la prova; in un’app vera minuti). |
RISE | script.js | 46 | Quanto in fretta sale il fumo, in pixel al secondo. |
SWIRL | script.js | 1 | Quanto il fumo ondeggia e si arriccia lontano dalla punta: 0 = un filo dritto. |
SMOKE | script.js | 1 | Quanto è denso il fumo. |
HAND | script.js | 1 | Quanto una mano (o un dito) passata nel fumo lo scompiglia; 0 = il fumo non si accorge della mano. |
ASH | script.js | [12, 22] | Quanto cresce la cenere sulla punta prima di cadere, in pixel: la più corta e la più lunga. |
AFTER | script.js | 2.6 | I secondi in cui il bastoncino consumato resta lì prima che ne salga uno nuovo. |
Per il timer di un’app di meditazione, di respirazione o di yoga, per una pausa di concentrazione, per lo studio a blocchi: dove il tempo deve passare con calma e senza ansia, e guardarlo fa parte del rilassarsi. Non è adatto a un conto alla rovescia che mette fretta.
Il componente è largo 320 pixel e sta in uno schermo di 390 senza sforare. Il dito trascinato nel fumo fa quello che fa il mouse; sul disegno la pagina non scorre (touch-action none), quindi il dito mescola il fumo invece di spostare la pagina. Il fumo costa poco (circa seicento sbuffi e un centinaio di tratti per fotogramma) e gira a 60 fotogrammi anche senza scheda grafica.
Il fumo non si muove: viene calcolato una volta sola, fermo, sta sulla punta dovunque sia e compare e sparisce in dissolvenza. Niente fiammella, niente tremolio della brace, niente mano nel fumo; la cenere non cade, sparisce in dissolvenza e i suoi pezzetti sono già nella ciotola. Il bastoncino nuovo compare al posto del vecchio senza salire, e le cifre e le parole cambiano in dissolvenza. Il bastoncino si accorcia lo stesso, perché è il tempo.
GSAP 3.15.0, Newsreader (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 16 KB; le librerie: GSAP 28 KB.
Provata il 6 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.