Vai al contenuto
animorio
EN
Torna alla libreria

L’orologio che conta i minuti

Fra un capitolo e l’altro entra una scheda scura: il nome compare di colpo, poi un orologio enorme conta i minuti fino all’ora del capitolo e la pagina nuova arriva di lato.

Transizioni, TestoGSAPMediaGratis

Il codice

Una cartella che funziona da sola: index.html, style.css, script.js e le librerie da CDN.

<!doctype html>
<html lang="it">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>L’orologio che conta i minuti</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>
  <!-- i fotogrammi: scene in bianco e nero disegnate a mano, riquadro 300 x 200 -->
  <svg class="scene" aria-hidden="true" focusable="false" width="0" height="0">
    <defs>
      <linearGradient id="g-notte" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#090909" /><stop offset="1" stop-color="#262626" /></linearGradient>
      <radialGradient id="g-faro"><stop offset="0" stop-color="#ffffff" /><stop offset="0.32" stop-color="#ececec" /><stop offset="1" stop-color="#ececec" stop-opacity="0" /></radialGradient>
      <linearGradient id="g-fascio" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#ffffff" stop-opacity="0.55" /><stop offset="1" stop-color="#ffffff" stop-opacity="0" /></linearGradient>
      <linearGradient id="g-cielo" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#dcdcdc" /><stop offset="1" stop-color="#9c9c9c" /></linearGradient>
      <radialGradient id="g-luce"><stop offset="0" stop-color="#ffffff" /><stop offset="0.5" stop-color="#d9d9d9" /><stop offset="1" stop-color="#d9d9d9" stop-opacity="0" /></radialGradient>
      <pattern id="p-scacchi" width="26" height="26" patternUnits="userSpaceOnUse" patternTransform="skewY(-6)">
        <rect width="26" height="26" fill="#efefef" /><rect width="13" height="13" fill="#121212" /><rect x="13" y="13" width="13" height="13" fill="#121212" />
      </pattern>

      <symbol id="s-fari" viewBox="0 0 300 200">
        <rect width="300" height="200" fill="url(#g-notte)" />
        <rect y="150" width="300" height="50" fill="#121212" />
        <path d="M58 140 Q150 112 242 140 L252 152 L48 152 Z" fill="#040404" />
        <path d="M104 128 L0 200 L150 200 Z" fill="url(#g-fascio)" opacity="0.45" />
        <path d="M196 128 L300 200 L150 200 Z" fill="url(#g-fascio)" opacity="0.45" />
        <circle cx="104" cy="130" r="30" fill="url(#g-faro)" />
        <circle cx="196" cy="130" r="30" fill="url(#g-faro)" />
      </symbol>

      <symbol id="s-gomme" viewBox="0 0 300 200">
        <rect width="300" height="200" fill="#bdbdbd" />
        <rect y="160" width="300" height="40" fill="#8f8f8f" />
        <g fill="none">
          <circle cx="104" cy="126" r="40" stroke="#151515" stroke-width="26" />
          <circle cx="104" cy="126" r="53" stroke="#2b2b2b" stroke-width="4" stroke-dasharray="3 5" />
          <circle cx="196" cy="126" r="40" stroke="#151515" stroke-width="26" />
          <circle cx="196" cy="126" r="53" stroke="#2b2b2b" stroke-width="4" stroke-dasharray="3 5" />
          <circle cx="150" cy="44" r="30" stroke="#1d1d1d" stroke-width="20" />
        </g>
        <circle cx="104" cy="126" r="17" fill="#7a7a7a" />
        <circle cx="196" cy="126" r="17" fill="#7a7a7a" />
        <circle cx="150" cy="44" r="12" fill="#8a8a8a" />
      </symbol>

      <symbol id="s-bandiera" viewBox="0 0 300 200">
        <rect width="300" height="200" fill="url(#g-cielo)" />
        <rect x="68" y="26" width="6" height="174" fill="#1a1a1a" />
        <path d="M74 32 C118 16 160 48 204 34 C230 26 250 28 264 32 L264 124 C250 120 230 118 204 126 C160 140 118 108 74 124 Z" fill="url(#p-scacchi)" />
        <path d="M74 32 C118 16 160 48 204 34 C230 26 250 28 264 32 L264 124 C250 120 230 118 204 126 C160 140 118 108 74 124 Z" fill="#000" opacity="0.14" />
      </symbol>

      <symbol id="s-casco" viewBox="0 0 300 200">
        <rect width="300" height="200" fill="#2a2a2a" />
        <rect y="152" width="300" height="48" fill="#191919" />
        <path d="M90 152 C86 92 122 54 170 54 C218 54 238 92 238 128 L238 152 Z" fill="#e3e3e3" />
        <path d="M148 96 C170 86 214 86 238 100 L238 130 C212 124 172 124 148 130 Z" fill="#0f0f0f" />
        <path d="M100 120 C118 72 170 62 214 72" fill="none" stroke="#8c8c8c" stroke-width="10" />
      </symbol>

      <symbol id="s-rettilineo" viewBox="0 0 300 200">
        <rect width="300" height="200" fill="#cdcdcd" />
        <rect y="90" width="300" height="110" fill="#5a5a5a" />
        <path d="M141 90 L159 90 L300 200 L0 200 Z" fill="#222" />
        <path d="M141 90 L0 200" stroke="#f1f1f1" stroke-width="7" stroke-dasharray="9 9" />
        <path d="M159 90 L300 200" stroke="#f1f1f1" stroke-width="7" stroke-dasharray="9 9" />
        <g fill="#e9e9e9">
          <path d="M149.2 98 L150.8 98 L151.3 106 L148.7 106 Z" />
          <path d="M148.2 116 L151.8 116 L152.8 130 L147.2 130 Z" />
          <path d="M146.6 144 L153.4 144 L155.4 166 L144.6 166 Z" />
          <path d="M144 182 L156 182 L158.4 200 L141.6 200 Z" />
        </g>
      </symbol>

      <symbol id="s-semaforo" viewBox="0 0 300 200">
        <rect width="300" height="200" fill="#141414" />
        <rect x="146" y="0" width="8" height="70" fill="#222" />
        <rect x="38" y="68" width="224" height="60" rx="8" fill="#2a2a2a" />
        <circle cx="70" cy="98" r="30" fill="url(#g-luce)" />
        <circle cx="110" cy="98" r="30" fill="url(#g-luce)" />
        <circle cx="70" cy="98" r="14" fill="#fafafa" />
        <circle cx="110" cy="98" r="14" fill="#fafafa" />
        <circle cx="150" cy="98" r="14" fill="#3b3b3b" />
        <circle cx="190" cy="98" r="14" fill="#3b3b3b" />
        <circle cx="230" cy="98" r="14" fill="#3b3b3b" />
      </symbol>

      <symbol id="s-volante" viewBox="0 0 300 200">
        <rect width="300" height="200" fill="#d4d4d4" />
        <circle cx="150" cy="104" r="68" fill="none" stroke="#141414" stroke-width="18" />
        <path d="M150 104 L86 90 M150 104 L214 90 M150 104 L150 170" stroke="#141414" stroke-width="12" stroke-linecap="round" />
        <circle cx="150" cy="104" r="22" fill="#2b2b2b" />
      </symbol>

      <symbol id="s-box" viewBox="0 0 300 200">
        <rect width="300" height="200" fill="#999" />
        <rect x="40" y="34" width="220" height="166" fill="#0e0e0e" />
        <rect x="40" y="34" width="220" height="72" fill="#bcbcbc" />
        <g stroke="#7b7b7b" stroke-width="3">
          <path d="M40 44 H260 M40 54 H260 M40 64 H260 M40 74 H260 M40 84 H260 M40 94 H260" />
        </g>
        <rect x="118" y="146" width="64" height="34" fill="#3a3a3a" />
        <circle cx="128" cy="186" r="7" fill="#5a5a5a" />
        <circle cx="172" cy="186" r="7" fill="#5a5a5a" />
      </symbol>

      <symbol id="s-tribuna" viewBox="0 0 300 200">
        <rect width="300" height="200" fill="#ececec" />
        <path d="M0 36 L300 16 L300 28 L0 50 Z" fill="#1c1c1c" />
        <path d="M0 70 L300 54 L300 64 L0 82 Z" fill="#8a8a8a" />
        <path d="M0 96 L300 78 L300 90 L0 110 Z" fill="#747474" />
        <path d="M0 124 L300 104 L300 118 L0 140 Z" fill="#5e5e5e" />
        <path d="M0 154 L300 132 L300 148 L0 172 Z" fill="#484848" />
        <rect y="178" width="300" height="22" fill="#2e2e2e" />
      </symbol>

      <symbol id="s-pioggia" viewBox="0 0 300 200">
        <rect width="300" height="200" fill="#4a4a4a" />
        <g stroke="#cfcfcf" stroke-width="1.6" stroke-linecap="round" opacity="0.7">
          <path d="M20 10 l8 22 M60 30 l8 22 M100 6 l8 22 M140 40 l8 22 M180 12 l8 22 M220 34 l8 22 M260 8 l8 22 M40 70 l8 22 M80 94 l8 22 M120 66 l8 22 M160 100 l8 22 M200 72 l8 22 M240 96 l8 22 M280 60 l8 22 M30 130 l8 22 M70 150 l8 22 M110 124 l8 22 M150 150 l8 22 M190 128 l8 22 M230 150 l8 22 M270 120 l8 22" />
        </g>
        <path d="M0 200 C80 146 220 146 300 200 Z" fill="#232323" />
        <path d="M150 196 L70 150" stroke="#0f0f0f" stroke-width="6" stroke-linecap="round" />
      </symbol>
    </defs>
  </svg>

  <!-- i capitoli: uno alla volta; fra l'uno e l'altro passa la scheda con l'orologio -->
  <main class="pagine">
    <section class="pagina pagina--giallo attiva" data-titolo="Partenza" data-giorno="Primo giorno" data-da="06:15" data-a="06:30" data-sotto="Il furgone lascia l’officina prima che faccia chiaro" aria-label="Partenza">
      <div class="pagina__testo">
        <p class="pagina__quando">Primo giorno, 06:30</p>
        <h2 class="pagina__titolo">Partenza</h2>
        <p class="pagina__corpo">Il furgone esce quando è ancora buio. Dietro, le gomme legate con le cinghie e un thermos che nessuno ha chiuso bene.</p>
      </div>
      <figure class="pagina__foto" aria-hidden="true"><div class="pagina__foto-dentro"><svg viewBox="0 0 300 200" preserveAspectRatio="xMidYMid slice"><use href="#s-gomme" /></svg></div></figure>
    </section>
    <section class="pagina pagina--carta" data-titolo="Il box" data-giorno="Primo giorno" data-da="06:30" data-a="09:15" data-sotto="Le serrande si alzano una dopo l’altra" aria-label="Il box">
      <div class="pagina__testo">
        <p class="pagina__quando">Primo giorno, 09:15</p>
        <h2 class="pagina__titolo">Il box</h2>
        <p class="pagina__corpo">Ogni box ha già il suo rumore: un compressore, una radio accesa, una chiave che cade sul cemento.</p>
      </div>
      <figure class="pagina__foto" aria-hidden="true"><div class="pagina__foto-dentro"><svg viewBox="0 0 300 200" preserveAspectRatio="xMidYMid slice"><use href="#s-box" /></svg></div></figure>
    </section>
    <section class="pagina pagina--inchiostro" data-titolo="La notte" data-giorno="Primo giorno" data-da="21:40" data-a="22:30" data-sotto="I fari passano più veloci del rumore" aria-label="La notte">
      <div class="pagina__testo">
        <p class="pagina__quando">Primo giorno, 22:30</p>
        <h2 class="pagina__titolo">La notte</h2>
        <p class="pagina__corpo">Dopo il tramonto la pista diventa una fila di fari. Il rumore arriva sempre un attimo dopo la luce.</p>
      </div>
      <figure class="pagina__foto" aria-hidden="true"><div class="pagina__foto-dentro"><svg viewBox="0 0 300 200" preserveAspectRatio="xMidYMid slice"><use href="#s-fari" /></svg></div></figure>
    </section>
    <section class="pagina pagina--carta" data-titolo="L’alba" data-giorno="Secondo giorno" data-da="05:20" data-a="06:05" data-sotto="La pioggia smette quando nessuno guarda" aria-label="L’alba">
      <div class="pagina__testo">
        <p class="pagina__quando">Secondo giorno, 06:05</p>
        <h2 class="pagina__titolo">L’alba</h2>
        <p class="pagina__corpo">Ha piovuto tutta la notte. Il primo a vedere il cielo che si apre è chi asciuga i cordoli.</p>
      </div>
      <figure class="pagina__foto" aria-hidden="true"><div class="pagina__foto-dentro"><svg viewBox="0 0 300 200" preserveAspectRatio="xMidYMid slice"><use href="#s-pioggia" /></svg></div></figure>
    </section>
    <section class="pagina pagina--giallo" data-titolo="L’arrivo" data-giorno="Secondo giorno" data-da="15:10" data-a="15:30" data-sotto="La bandiera scende una volta sola" aria-label="L’arrivo">
      <div class="pagina__testo">
        <p class="pagina__quando">Secondo giorno, 15:30</p>
        <h2 class="pagina__titolo">L’arrivo</h2>
        <p class="pagina__corpo">Ventiquattro ore per venti secondi di bandiera. Poi tutti corrono in pista e i box restano vuoti.</p>
      </div>
      <figure class="pagina__foto" aria-hidden="true"><div class="pagina__foto-dentro"><svg viewBox="0 0 300 200" preserveAspectRatio="xMidYMid slice"><use href="#s-bandiera" /></svg></div></figure>
    </section>
  </main>

  <!-- la scheda scura: prima il nome del capitolo, poi l'orologio che conta fino all'ora giusta -->
  <div class="scheda" aria-hidden="true">
    <p class="scheda__titolo"><span class="scheda__parola">Partenza</span></p>
    <div class="scheda__orologio">
      <p class="scheda__giorno"><span>Primo giorno</span></p>
      <p class="scheda__ora"><span class="cifra">0</span><span class="cifra">6</span><span class="due-punti">:</span><span class="cifra">1</span><span class="cifra">5</span></p>
      <p class="scheda__sotto"></p>
    </div>
  </div>

  <button type="button" class="avanti">Capitolo dopo</button>
  <p class="annuncio" aria-live="polite"></p>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
  <script src="script.js"></script>
</body>
</html>

Cosa fa

Ogni capitolo ha un'ora. Per passare al successivo entra da destra una scheda nera che diventa grigio inchiostro; sopra, di colpo, il nome del capitolo largo quanto lo schermo. Dopo un secondo e mezzo il nome sparisce e al suo posto c'è un orologio enorme che conta i minuti dall'ora di prima a quella del capitolo, con i due punti che lampeggiano e le cifre che fanno un piccolo salto a ogni minuto. Sotto, il giorno e una frase che sale parola per parola. Finito il conteggio, la pagina nuova arriva di lato e copre la scheda; la sua foto resta un attimo indietro dentro la cornice.

Come funziona

La scheda

Una scheda fissa entra con xPercent da 100 a 0 in 0,8 secondi con expo.out (dal basso al telefono) e intanto il suo fondo va dal nero al grigio inchiostro. Nome e orologio non si animano: compaiono e spariscono con un set di visibility, tagli netti come in un montaggio.

Il conteggio

L'orologio conta in minuti totali (ore per 60 più minuti), così passa le ore e anche la mezzanotte. Un oggetto va dai minuti di partenza a quelli d'arrivo con power2.inOut; in onUpdate si arrotonda per difetto e si riscrive l'ora solo quando il minuto cambia, con un piccolo salto delle cifre al posto del ticchettio.

Le cifre ferme

Ogni cifra sta in una casella di larghezza fissa (0,5em, testo centrato): senza, mentre conta l'orologio trema. Le cifre tabellari (tabular-nums) farebbero lo stesso, ma in Mona Sans hanno lo zero barrato. I due punti lampeggiano in CSS con un'animazione step-end sulla visibility.

La pagina che arriva

Ogni pagina è un livello fisso a sé, così quella nuova può passare sopra la scheda con uno z-index più alto. Entra con x dalla larghezza dello schermo a 0; la foto dentro la cornice è più larga del 14% e parte spostata, così arriva un poco dopo la pagina.

Valori da cambiare

NomeFileDi partenzaCosa cambia
ENTRATAscript.js0.8Secondi della scheda che entra.
TITOLOscript.js1.5Per quanti secondi resta il nome del capitolo prima dell'orologio.
CONTAscript.js1Secondi del conteggio, qualunque sia la distanza fra le due ore.
ATTESAscript.js2.6Secondi su ogni pagina prima del capitolo dopo. Con 0 si cambia solo col pulsante.
data-da, data-aindex.html06:15, 06:30Su ogni pagina: l'ora da cui parte il conteggio e quella del capitolo.

Quando usarla

Per un racconto diviso in momenti: il programma di una giornata, le tappe di un viaggio, le ore di un evento. Il passaggio dura quattro secondi: va bene fra capitoli, non fra una pagina e l'altra di un sito qualsiasi.

Sul telefono

La scheda sale dal basso invece di entrare di lato, la foto va sopra il testo e l'orologio si adatta alla larghezza.

Con il movimento ridotto

Niente scheda e niente conteggio: il pulsante porta direttamente al capitolo dopo, che dice già la sua ora. I capitoli non cambiano da soli.

Trappole

  • Con cifre proporzionali ogni cifra ha la sua larghezza e l'orologio balla mentre conta: servono caselle fisse o cifre tabellari.
  • Conta in minuti totali, non in minuti e ore separati: altrimenti da 06:30 a 09:15 i minuti tornano indietro.
  • Se le pagine stanno tutte dentro un contenitore fisso, quello crea un contesto di sovrapposizione e la pagina nuova non passa mai sopra la scheda: ogni pagina dev'essere fissa per conto suo.
  • Il sito originale fa ticchettare l'orologio con un suono: se lo aggiungi, fallo partire solo dopo un clic e lascia sempre il modo di spegnerlo.

Librerie

GSAP 3.15.0, Mona Sans (font variabile) 5.3.0.

Peso: 23 KB dei nostri file.

Collaudo

Provata il 27 settembre 2026

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

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.

Tutte le animazioni