Vai al contenuto
animorio
EN
Tutti i componenti

Il pulsante del marcatempo

Pulsanti, Fisica, TransizioniCanvas, GSAPImpegnativaPeso compresso: Demo 13 KBGSAP 28 KBGratisScarica lo zip

Il pulsante Clock in di un'app dei turni, fatto come un orologio marcatempo da fabbrica: la pillola è la macchina smaltata color sangue di bue, con il quadrante nella punta tonda (le lancette segnano l'ora del computer di chi guarda e quella dei minuti scatta ogni minuto) e la fessura in alto, dove aspetta un cartellino di cartoncino col nome stampato. Al clic il cartellino entra nella fessura, la macchina dà il colpo, e il cartellino risale su una molla, rimbalzando e oscillando, con l'ora vera stampata in inchiostro viola un po' sbavato. La scritta diventa Clocked in · e l'ora, con le cifre che girano come ruote dei caratteri. Il clic dopo timbra Clock out sulla riga sotto, in rosso; quello dopo ancora prende un cartellino nuovo.

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 time clock button</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/archivo@5.3.0/wdth.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/courier-prime@5.3.0/700.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the time clock button: the Clock in button of a shift app, built as a factory time recorder. The pill is the
         machine, enamelled, with its dial in the round left end (the hands show the time of the computer you are on)
         and the card slot along its top, with a time card waiting in it. A click pushes the card down into the slot,
         the machine strikes, and the card springs back up with the time printed on it in smudged ink; the next click
         clocks out on the line under it -->
    <div class="clock" data-clock>
      <div class="clock__card-win" aria-hidden="true" data-win>
        <canvas class="clock__card" data-card></canvas>
      </div>
      <button class="clock__btn" type="button" data-btn data-autoclic>
        <span class="clock__fill" aria-hidden="true"></span>
        <span class="clock__slot" aria-hidden="true" data-slot></span>
        <svg class="clock__dial" viewBox="-24 -24 48 48" aria-hidden="true" data-dial>
          <defs>
            <linearGradient id="clock-bezel" x1="0" y1="0" x2="1" y2="1">
              <stop offset="0" stop-color="#ffffff"/>
              <stop offset="0.35" stop-color="#c9ccd0"/>
              <stop offset="0.62" stop-color="#7d8288"/>
              <stop offset="1" stop-color="#e9ebee"/>
            </linearGradient>
            <radialGradient id="clock-face" cx="0.42" cy="0.36" r="0.7">
              <stop class="clock__stop-light" offset="0"/>
              <stop class="clock__stop" offset="1"/>
            </radialGradient>
          </defs>
          <circle class="clock__bezel" r="22.5" fill="url(#clock-bezel)"/>
          <circle class="clock__rim" r="19.4"/>
          <circle class="clock__face" r="18.6" fill="url(#clock-face)"/>
          <g class="clock__ticks" data-ticks></g>
          <g data-shake>
            <path class="clock__hand clock__hand--hour" d="M-1.5 2.6 L-0.9 -8.6 L0 -10.2 L0.9 -8.6 L1.5 2.6 Z" data-hour/>
            <path class="clock__hand" d="M-1 3.4 L-0.6 -14.2 L0 -15.6 L0.6 -14.2 L1 3.4 Z" data-minute/>
            <circle class="clock__cap" r="1.9"/>
          </g>
          <circle class="clock__glass" r="18.6"/>
        </svg>
        <span class="clock__faces">
          <span class="clock__face" data-face="ready">
            <span class="clock__word" data-wide="Clock in" data-ready-text>Clock in</span>
          </span>
          <span class="clock__face" data-face="next" aria-hidden="true">
            <span class="clock__lead" data-next-lead>Clocked in · 09:12</span>
            <span class="clock__word" data-wide="Clock out" data-next-text>Clock out</span>
          </span>
          <span class="clock__face clock__face--busy" data-face="busy" aria-hidden="true">
            <span class="clock__shine" data-busy-text>Clocking in…</span>
          </span>
          <span class="clock__face" data-face="big" aria-hidden="true">
            <span class="clock__big" data-big-text>Clocked in · 09:12</span>
          </span>
        </span>
      </button>
      <p class="sr" aria-live="polite" data-live></p>
    </div>
  </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 pulsante del marcatempo» da Animorio e adattala al mio sito

Cosa fa

Su un fondo bianco una pillola smaltata color sangue di bue, alta 60 pixel, con un riflesso morbido in alto e un'ombra calda sotto. Nella punta tonda di sinistra un quadrante da orologio di fabbrica, largo 46 pixel: la ghiera di nichel lucido, il fondo color crema, sessanta tacche (più grosse ogni cinque), due lancette nere a punta e il cappellotto rosso; le lancette segnano l'ora del computer, e quella dei minuti scatta al minuto dopo con un piccolo tremito, come sui marcatempo veri. In alto, lungo il bordo, la fessura: una feritoia scura coi labbri di nichel. Nella fessura aspetta un cartellino di cartoncino manila, con le fibre, il nome NOOR HADDAD stampato in rosso e una doppia riga sotto; ne spunta solo la testa. In Archivo color avorio, Clock in. All'arrivo la macchina sale piano e il cartellino cade nella fessura e oscilla. Col mouse sopra la scritta si allarga sull'asse della larghezza, lo smalto si gonfia con un rimbalzo e il cartellino si alza un poco e dondola, come per farsi prendere; premendo scende un poco. Al clic la scritta diventa Clocking in…, con un riflesso che la attraversa; il cartellino viene spinto giù nella fessura fino in fondo, un istante dentro la macchina, poi il colpo: lo smalto si schiaccia e torna con un rimbalzo, il quadrante sobbalza e le lancette tremano. Il cartellino risale lanciato, va oltre, ricade, rimbalza e si posa più in alto di prima, dondolando nella fessura: sulla prima riga c'è l'ora stampata, IN e l'ora del computer, in inchiostro viola con le cifre un po' storte, una seconda battuta leggera accanto, l'inchiostro sbavato e più chiaro dove il nastro è consumato, ancora un po' lucido e scuro finché non si asciuga. La scritta diventa Clocked in · 09:12 (l'ora vera), con le cifre che girano come le ruote dei caratteri prima di fermarsi; poi la riga si rimpicciolisce e sale, e sotto arriva Clock out. Un altro clic: il cartellino rientra, il colpo, e risale con la seconda timbratura sotto la prima, OUT e l'ora in rosso; la scritta dice Clocked out e l'ora, poi Clock in. Il clic dopo è un turno nuovo: il vecchio cartellino viene sfilato verso l'alto e sparisce, uno bianco cade nella fessura e viene timbrato. Con la tastiera il fuoco mostra un anello color sangue di bue, la scritta si allarga e il cartellino si alza; Invio o Spazio timbrano. Al telefono il tocco timbra.

Come funziona

La macchina e il quadrante

La pillola è un button con lo smalto su uno strato suo (così si gonfia e si schiaccia senza muovere niente) e la fessura in CSS: una feritoia con un gradiente scuro e quattro box-shadow che fanno i labbri di nichel. Il quadrante è un SVG: la ghiera con un gradiente lineare, il fondo con uno radiale, le sessanta tacche create dallo script, e le lancette girate da GSAP intorno al centro (svgOrigin). L'ora è quella di new Date(Date.now()); un delayedCall di GSAP aspetta il giro del minuto e fa scattare la lancetta con elastic.out, come sui marcatempo veri, senza ridisegnare niente fra un minuto e l'altro.

Il cartellino nella fessura

Il cartellino è un canvas di 60 per 74 pixel dentro una finestra con overflow: hidden il cui bordo basso è proprio la fessura: quello che scende sotto sparisce nella macchina. La sua altezza fuori dalla fessura è h, e lo script lo sposta con translateY(−h) e lo fa dondolare con rotate, col transform-origin a h pixel dalla sua testa, cioè nel punto in cui la fessura lo stringe. Il cartoncino si dipinge una volta fuori dallo schermo: il manila col bordo più scuro, settanta fibre chiare e scure messe da un hash, il nome stampato col letterSpacing del canvas e le righe azzurre.

La molla e il colpo

Fermo, il cartellino segue una molla smorzata verso la sua altezza (SPRING oscillazioni al secondo, smorzamento DAMPING): sotto il mouse l'obiettivo sale di 5 pixel, premendo scende di 5. Per timbrare GSAP lo spinge giù con power3.in fino in fondo, 0,22 secondi dentro la macchina, poi il colpo: lo smalto si schiaccia di un decimo e torna con elastic.out, il quadrante sobbalza e le lancette girano di 7 gradi e tornano. Allora il cartellino riceve una velocità verso l'alto di 330 · KICK pixel al secondo: la molla lo porta oltre la sua altezza, lo riprende, rimbalza; il fondo della fessura è un arresto rigido. Una seconda molla, più dura, lo fa dondolare dopo una spinta di lato. Passi di 1/240 di secondo, fotogramma limitato a 1/30; fermo il cartellino, il ciclo dorme.

L'inchiostro sbavato

Ogni timbratura si stampa una volta sola su un canvas suo: IN o OUT e l'ora, in Courier Prime grassetto, una cifra alla volta, ognuna un poco fuori dalla riga (come le ruote dei caratteri), tutta la riga appena storta. Una seconda passata leggera, spostata di mezzo pixel, è la ruota che rimbalza sul nastro; uno shadowBlur dello stesso colore è l'inchiostro che si spande nelle fibre. Poi i pixel passano per una maschera di rumore: due ottave di rumore a valori lisci rendono l'inchiostro irregolare, un seno lungo la riga lo schiarisce dove il nastro è consumato, e dove il rumore fine è basso restano dei vuoti. SMUDGE regola tutto, da 0 (stampa pulita) a 2 (nastro vecchio). L'ultima timbratura nasce bagnata, più scura, e si asciuga in due secondi e mezzo.

Le cifre che girano

Arrivato il cartellino, la scritta Clocked in · 09:12 si costruisce con uno span per ogni cifra. Ogni cifra mostra cifre a caso, cambiate da un tween di GSAP (non da un timer, così il banco può rallentarle), per 0,32 secondi più 0,09 per ogni cifra prima: si fermano una dopo l'altra, da sinistra, e ognuna dà un piccolo saltello con back.out. Il carattere ha le cifre tabellari, così la riga non balla mentre girano. Poi la riga grande si misura e va con il suo scale proprio dove sta la riga piccola, e sotto sale l'azione dopo.

Gli stati

Tre stati che girano: prima del turno (Clock in), durante (Clock out), e di nuovo prima del turno, con un cartellino nuovo: il vecchio viene sfilato in alto e svanisce, quello bianco cade nella fessura con power2.in e viene timbrato. Il pulsante è un button vero, aria-disabled mentre lavora; una zona aria-live dice Clocking in…, poi Clocked in at e l'ora. Con HOURS_24 a false l'ora è sulle dodici ore (5:46 PM, e sul cartellino 5:46P). Un giro dura circa 3,3 secondi, più dei 2,8 fra due clic dell'anteprima: un clic cade nell'attesa e ogni timbratura resta in vista.

Valori da cambiare

NomeFileDi partenzaCosa cambia
PERSONscript.jsNoor HaddadIl nome stampato in testa al cartellino, in maiuscolo.
CLOCK_INscript.jsClock inLa scritta prima del turno.
CLOCK_OUTscript.jsClock outLa scritta durante il turno.
CLOCKING_INscript.jsClocking in…La scritta mentre timbra l'entrata; è anche quello che dice la zona aria-live.
CLOCKING_OUTscript.jsClocking out…La scritta mentre timbra l'uscita.
CLOCKED_INscript.jsClocked inLa scritta a entrata timbrata, prima dell'ora.
CLOCKED_OUTscript.jsClocked outLa scritta a uscita timbrata, prima dell'ora.
HOURS_24script.jstrueL'ora sulle ventiquattro ore (17:46); spento, sulle dodici (5:46 PM).
SPRINGscript.js2.6La molla del cartellino, in oscillazioni al secondo: più alta, rimbalzi svelti e corti; più bassa, lenti e lunghi.
DAMPINGscript.js0.16Quanto si smorzano i rimbalzi: 0,05 il cartellino ballonzola a lungo, 0,7 quasi non rimbalza.
KICKscript.js1Con quanta forza la macchina rilancia il cartellino dopo il colpo: 0 risale piano sulla molla, 2 vola alto.
SMUDGEscript.js1Quanto è sbavato l'inchiostro: 0 una stampa pulita, 2 un nastro vecchio, con le cifre storte e i vuoti.

Provali nel Playground

Quando usarla

Per il pulsante che segna l'inizio e la fine di qualcosa: la timbratura di un'app dei turni o delle presenze, il timer di un'app per fatturare le ore, l'inizio di una sessione di lavoro o di studio, l'entrata in un coworking, in una palestra o in un cantiere. Va collegato alla timbratura vera del tuo sito (la chiamata al server che registra l'ora): qui è tutto simulato, e l'ora è quella del computer di chi guarda.

Sul telefono

La macchina è larga circa 245 pixel e il cartellino spunta sopra la fessura: a 390 pixel ci sta con margine, e con scritte più lunghe il carattere non cambia ma la pillola si allarga fino al bordo. Il tocco spinge il cartellino un poco giù (come il dito che preme) e timbra.

Con il movimento ridotto

Il cartellino sta già fuori dalla fessura e non si muove; la macchina non si schiaccia, la pillola non si gonfia e la scritta non si allarga (sotto il mouse lo smalto si schiarisce appena). Timbrando, la riga nuova compare sul cartellino in dissolvenza e le parole cambiano in dissolvenza, senza cifre che girano; il cartellino nuovo arriva in dissolvenza al posto del vecchio. Le lancette segnano l'ora senza scatti.

Trappole

  • Il gradiente del quadrante aveva stop-color="var(--dial)" scritto come attributo dell'SVG: gli attributi di presentazione non leggono le variabili CSS e il fondo restava nero. Gli stop hanno una classe e il colore sta nel CSS.
  • La finestra del cartellino era messa con calc(50% − metà della pillola): ma il contenitore è largo quanto la pillola, e il cartellino finiva fuori dalla fessura. La finestra ora si mette direttamente sulla posizione della fessura.
  • Per il cartellino nuovo una rotazione data da un tween e la molla che lo raddrizza si contendevano lo stesso valore, e il cartellino tremava a scatti. Ora il cartellino che esce riceve solo una spinta di lato, e la molla fa il resto.
  • L'inchiostro, a 8,6 pixel e con la maschera di rumore che toglieva fino a metà della densità, era pallido e si leggeva a stento. Ora il carattere è di 9,2 pixel, la prima battuta è piena e la maschera toglie al massimo il 42 per cento.
  • Le lancette lette da Date.now() nel banco del sito seguono l'orologio virtuale: rallentando l'anteprima anche il minuto rallenta. Il controllo del minuto è un delayedCall di GSAP, non un setInterval, così resta d'accordo col banco.

Librerie

GSAP 3.15.0, Archivo (font variabile) 5.3.0, Courier Prime 5.3.0.

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

Collaudo

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