Vai al contenuto
animorio
EN
Tutti i componenti

Il timer del pomodoro che matura

Timer, Fisica, TransizioniCanvas, GSAPImpegnativaPeso compresso: Demo 21 KBGSAP 28 KBGratisScarica lo zip

Un timer per la tecnica del pomodoro dove il tempo è un pomodoro vero che matura sul ramo: parte verde e duro e nei venticinque minuti diventa giallo, arancio e rosso lucido, dal fondo verso il picciolo come nella pianta, con la buccia che si tende, i riflessi che si fanno netti e i sepali che si aprono, mentre il ramo si piega sotto il peso. A zero il pomodoro si stacca, cade con un rimbalzo morbido e parte la pausa, con un fiore giallo che sboccia al suo posto.

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">
  <title>The ripening tomato timer</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/full.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- a pomodoro timer where the time is a real tomato ripening on the vine: it starts green and hard, and over the
         twenty-five minutes it turns from the blossom end up, through breaker, turning, pink and light red, to a glossy
         red, its skin tightening and its sepals opening, while the branch bends under it. At zero the ripe tomato lets
         go at its knuckle, drops with a soft bounce, and the break begins while a new flower opens on the stalk -->
    <section class="pomo" aria-label="Pomodoro timer" data-timer>
      <div class="pomo__vine" data-vine>
        <canvas class="pomo__canvas" aria-hidden="true" data-canvas></canvas>
      </div>

      <div class="pomo__readout" data-readout>
        <span class="pomo__time" role="timer" aria-live="off" aria-atomic="true">
          <span class="pomo__digits" aria-hidden="true" data-time></span>
          <span class="sr" data-time-words></span>
        </span>
        <p class="pomo__state"><span class="pomo__word" data-word></span><span class="pomo__detail" data-detail></span></p>
      </div>

      <div class="pomo__controls" data-controls>
        <button class="pomo__reset" type="button" aria-label="Reset" aria-disabled="true" data-reset>
          <span class="pomo__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="pomo__go" type="button" data-go data-autoclic>
          <span class="pomo__shine" aria-hidden="true"></span>
          <span class="pomo__go-words" data-go-words>Start</span>
        </button>
        <span class="pomo__picked" role="img" aria-label="No tomatoes picked today" data-picked>
          <svg class="pomo__mini" viewBox="0 0 32 32" aria-hidden="true" data-mini>
            <defs>
              <radialGradient id="pomo-mini-skin" cx="38%" cy="36%" r="70%">
                <stop offset="0" stop-color="#ff7a55"/>
                <stop offset="0.45" stop-color="#e2321d"/>
                <stop offset="1" stop-color="#a3140f"/>
              </radialGradient>
            </defs>
            <path d="M16 9.2c-3.1-1.7-6.4-1.4-8.6.7-2.7 2.4-3.4 6.6-1.9 10.2 1.6 3.8 5.6 6.4 10.5 6.4s8.9-2.6 10.5-6.4c1.5-3.6.8-7.8-1.9-10.2-2.2-2.1-5.5-2.4-8.6-.7z" fill="url(#pomo-mini-skin)"/>
            <path d="M10.4 12.6c.8-1.3 2.2-2 3.4-2.1" fill="none" stroke="#ffd9c8" stroke-width="1.3" stroke-linecap="round" opacity="0.85"/>
            <path d="M16 10.4l-1.6-3 1.6 1.1 1.5-2.4.1 2.7 3.1-.6-2.3 2.1 2.9 1.3-3.4.1-.7 2-1.2-1.9-2.6 1.4 1.3-2.2-3.2-.6 3-.9z" fill="#3f7a25"/>
            <path d="M16 8.4c.1-1.6.7-2.9 1.8-3.8" fill="none" stroke="#3f7a25" stroke-width="1.6" stroke-linecap="round"/>
          </svg>
          <span class="pomo__count" aria-hidden="true" data-count></span>
        </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>

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.

28 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 timer del pomodoro che matura» da Animorio e adattala al mio sito

Cosa fa

Su un fondo bianco, un ramo di pomodoro entra da sinistra, peloso e con le sue foglie seghettate, e a metà regge un pomodoro verde, schiacciato e costoluto, appeso al suo picciolo col nodo a metà; sotto, sul pavimento che non si vede, la sua ombra morbida. Più giù il tempo in grandi cifre, 25:00, Ready · 25 min focus, e tre cose: un pulsante tondo per azzerare, spento, una pillola rosso pomodoro con Start e un piccolo pomodoro grigio, quelli raccolti oggi. Con Start il pomodoro fa un piccolo dondolo e comincia a oscillare nella brezza; le cifre scendono e accanto a Focus compare lo stadio di maturazione, col suo colore: Green, Breaker, Turning, Pink, Light red, Red. Il pomodoro matura davvero: prima il verde impallidisce, poi dal fondo sale un rosa ambrato a chiazze, poi giallo, arancio e rosso, e le spalle intorno al picciolo restano verdi più a lungo. Intanto la buccia si tende: le costole si ammorbidiscono, la luce si stringe e sul rosso si specchia netta una finestra a due vetri; i sepali, che prima abbracciavano il frutto, si aprono e si arricciano. Il ramo si piega sotto il peso, e le cifre si fanno più morbide e più piene. Passandoci sopra col puntatore, o toccandolo, il pomodoro dondola e le foglie tremano. A zero il pomodoro resta un momento rosso e lucido, Ripe · time for a break, poi trema sul nodo del picciolo, si stacca e cade: atterra schiacciandosi, rimbalza piano, rotola un poco e si assesta sul fianco, mentre il ramo, libero, scatta in su e oscilla. Il pomodoro piccolo accanto ai pulsanti si colora e prende il numero 1. Parte la pausa, 05:00, Break · step away: sul picciolo spunta un bocciolo che si apre in un fiore giallo, i petali piegati all'indietro intorno al cono delle antere. Alla fine della pausa i petali cadono, il pomodoro raccolto sparisce e al posto del fiore si gonfia un pomodoro verde nuovo. Pause ferma tutto, Resume riparte; il pulsante tondo, durante il lavoro, riporta il pomodoro al verde, e durante la pausa la salta.

Come funziona

La buccia, pixel per pixel

Il pomodoro è un ellissoide schiacciato visto un poco dall'alto, dipinto su un canvas nascosto. Per ogni pixel, una volta sola per ogni misura, si calcolano la normale, quanto sta in alto rispetto al fondo del frutto, l'angolo intorno al picciolo e un rumore morbido. Le costole sono sei solchi che partono dal picciolo, forti sulle spalle e spariti a metà: non cambiano il contorno se non di poco, piegano la normale lungo l'angolo. Intorno al picciolo le normali si piegano verso l'interno: la fossetta. Così dipingere vuol dire, per ogni pixel, qualche moltiplicazione e due potenze, al massimo trenta volte al secondo.

Matura dal fondo

La maturazione locale è la maturazione del timer meno l'altezza sul frutto, più il rumore: il colore sale dal fondo a chiazze e le spalle restano verdi per ultime, come nella pianta. Il colore viene da una tabella di 256 passi fra le tappe che usano i coltivatori (verde, verde pallido, breaker, turning, pink, light red, red), mescolate come le vede l'occhio e non nella luce lineare, che fra verde e arancio passava per il marrone. Sul verde ci sono dei puntini chiari, tondi, sparsi su una griglia intorno al frutto, che spariscono col rosso.

La buccia che si tende

Con la maturazione le costole si ammorbidiscono e la luce si stringe: l'esponente del riflesso passa da 16 a 136. La finestra è il riflesso della direzione di vista confrontato con la direzione della luce, misurato su due assi di traverso: due vetri con la croce in mezzo, sfumati sul verde cerato e netti sul rosso lucido. L'ombra non è grigia: la polpa lascia passare la luce, quindi in ombra il colore diventa più profondo, il colore al quadrato. Sotto c'è la luce che rimbalza dal pavimento, sul bordo quella del cielo.

Sepali, fiore, ramo e foglie

I sepali sono sei lame in 3D intorno all'asse del picciolo: ognuna parte da un anello con un'inclinazione e si arriccia lungo la sua lunghezza, e si disegna come una foglia che si assottiglia, dalla più lontana alla più vicina. Chiuse abbracciano il frutto verde, aperte si piegano all'indietro. Il fiore della pausa usa le stesse lame per i petali, che da bocciolo puntano in giù e poi si rovesciano intorno al cono delle antere. Il ramo è una trave a sbalzo tenuta fuori dal disegno: la sua forma è quella della freccia sotto un peso nel nodo, e la freccia è una molla smorzata che segue il peso del pomodoro. Le foglie, fatte di foglioline seghettate disegnate una volta come Path2D, stanno su molle che il ramo e il puntatore smuovono.

Il pendolo, la caduta e il rotolare

Il picciolo è un pendolo con la rigidità del gambo: la brezza lo spinge mentre il tempo corre, il puntatore gli dà una spinta. Siccome ruotare l'immagine ruoterebbe anche il riflesso, la buccia si ridipinge con la luce girata all'indietro dello stesso angolo. A zero il pomodoro si stacca al nodo con la velocità del suo dondolo, cade con la gravità, all'urto si schiaccia lungo la verticale intorno al punto di contatto e rimbalza; poi rotola senza strisciare, e la gravità lo riporta sul fianco largo, perché un frutto schiacciato in piedi sta più in alto.

Il tempo e l'anteprima

Il tempo che resta viene dall'orologio (performance.now), così una scheda lasciata in background finisce in orario. Con QUICK un giro fatto a mano dura pochi secondi e le cifre mostrano i minuti veri; le cifre rotolano solo se il cambio prima è di più di un quarto di secondo fa. Le cifre sono in Fraunces: con la maturazione l'asse SOFT va da 0 a 100 e il peso da 360 a 560, e nella pausa tornano sode. Il clic dell'anteprima (detail 0) fa partire solo un giro veloce intero, lavoro, caduta, pausa e pomodoro nuovo, e i clic da script che arrivano mentre gira non fanno niente. role="timer" con aria-live off, e una regione aria-live che parla solo ai cambi di stato.

Valori da cambiare

NomeFileDi partenzaCosa cambia
FOCUSscript.js25I minuti di un giro di lavoro.
BREAKscript.js5I minuti della pausa che segue.
QUICKscript.js20Per provarlo, un giro fatto partire a mano dura questi secondi (le cifre mostrano comunque i minuti veri); 0 = nel tempo vero.
PREVIEWscript.js[8, 3]Nell'anteprima della libreria, i secondi del lavoro e della pausa.
BENDscript.js1Quanto si piega il ramo sotto il pomodoro: 0 = rigido.
SWAYscript.js1Quanto dondola il pomodoro nella brezza e sotto il puntatore: 0 = fermo.
BOUNCEscript.js0.34Quanto rimbalza il pomodoro maturo quando tocca terra: 0 = si posa e basta.

Provali nel Playground

Quando usarla

Per il timer di un'app di concentrazione o di studio, di un gestore di attività, di un'estensione per il browser o di un sito personale sulla produttività: dove chi lavora vuole vedere quanto manca con la coda dell'occhio, senza contare. Lo stesso pittore pixel per pixel serve per qualunque frutto che cambia colore col tempo (una pesca, una mela, un peperone) cambiando forma e tappe di colore.

Sul telefono

Il componente è largo 360 pixel e a 390 si stringe a 358 senza sforare; il disegno si ridipinge alla nuova misura. Il tocco sul pomodoro lo fa dondolare dalla parte opposta e un dito che scorre di lato smuove foglie e frutto, senza bloccare lo scorrimento in verticale. I pulsanti sono alti 48 e 56. La buccia si dipinge su circa cinquantamila pixel al massimo trenta volte al secondo, e mai quando è ferma.

Con il movimento ridotto

Il pomodoro matura lo stesso, perché è il tempo: cambia colore e lucentezza senza muoversi. Niente brezza, niente dondolo, il ramo non si piega; a zero il pomodoro non cade: svanisce dal ramo e compare a terra in dissolvenza. Il fiore compare già aperto in dissolvenza, il pomodoro nuovo arriva in dissolvenza e le cifre cambiano senza rotolare.

Trappole

  • Mescolando le tappe di colore nella luce lineare, fra il verde e l'arancio il pomodoro passava per un marrone oliva che sembrava marcio: le tappe ora si mescolano come le vede l'occhio, e fra il verde e il breaker c'è un verde pallido, come nel frutto vero.
  • Con l'ultima tappa troppo scura e poca luce d'ambiente il pomodoro maturo sembrava una prugna: rossi più accesi, ambiente più alto, e l'ombra fatta col colore al quadrato invece che col grigio.
  • I puntini chiari del verde, fatti tagliando un rumore a una soglia, venivano rettangoli storti: ora sono puntini tondi, uno per cella di una griglia intorno al frutto, spostati a caso e accesi solo in metà delle celle.
  • Aperti del tutto, i sepali si alzavano dritti come una corona: ora si aprono di traverso e si arricciano solo in punta.
  • Il pomodoro che dondola si disegna ruotato, e il riflesso ruotava con lui come se la lampada si muovesse: la buccia si ridipinge con la luce girata all'indietro dello stesso angolo.
  • Dopo l'entrata il ramo e le foglie continuavano a vibrare di meno di un pixel per quattro secondi, e il disegno non si fermava mai: molle più smorzate e una soglia sotto cui si fermano al loro posto; l'entrata si ferma in tre secondi.
  • Col movimento ridotto il pomodoro staccato spariva di colpo, perché non era più quello appeso: resta appeso mentre svanisce, e solo dopo esce dal disegno.

Librerie

GSAP 3.15.0, Fraunces (font variabile) 5.3.0.

Compressi con gzip, i tre file della demo pesano 21 KB; le librerie: GSAP 28 KB.

Collaudo

Provata il 17 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