Vai al contenuto
animorio
EN
Tutti i componenti

Il pulsante del registratore di cassa

Pulsanti, Fisica, 3DSolo CSS, GSAPImpegnativaPeso compresso: Demo 12 KBGSAP 28 KBGratisScarica lo zip

Il Checkout · €48.00 di un negozio come un registratore di cassa smaltato d'altri tempi: nella pillola color sangue di bue, filettata d'oro, una tastiera di nove tasti in tre colonne costruita in CSS 3D, sopra un'insegna dorata con la finestrella del totale, sotto il cassetto. Al clic i tasti del totale si abbassano uno dopo l'altro e tornano su con la loro molla, le bandierine 4, 8 e 00 saltano su nella finestrella oscillando sul loro perno, la molla del cassetto lo spinge fuori, batte sul fermo e rimbalza, e la scritta diventa Paid · Order 4821. Un altro clic richiude il cassetto con un tonfo e le bandierine ricadono.

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 cash register button</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/mona-sans@5.3.0/wdth.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/big-shoulders-display@5.3.0/wght.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the cash register button: the Checkout of a shop as an enamelled cash register of the old days. In the pill a
         bank of keys in columns, over it the window where the amount flags come up, under it the cash drawer. A click
         rings the total up: the keys go down one after the other on their springs, the flags with the total jump up
         in the window, the drawer is kicked out and bounces on its stop, and the pill says Paid with the order number.
         Another click pushes the drawer shut and the register is back at rest -->
    <div class="till" data-till>
      <div class="till__unit">
        <!-- the drawer under the pill: the tray with the notes and the coins, and its front -->
        <div class="till__drawer" aria-hidden="true" data-drawer>
          <div class="till__slide" data-slide>
            <svg class="till__tray" viewBox="0 0 170 40" preserveAspectRatio="none" data-tray></svg>
            <div class="till__front">
              <span class="till__pull"></span>
            </div>
          </div>
        </div>
        <div class="till__body" data-body>
          <!-- the sign over the pill: a gilt frame, and behind its glass the flags of the amount -->
          <div class="till__sign" aria-hidden="true">
            <span class="till__crest">Amount</span>
            <span class="till__window" data-window>
              <span class="till__mark">€</span>
              <span class="till__slot" data-slot="tens"><span class="till__flag" data-flag="tens">4</span></span>
              <span class="till__slot" data-slot="units"><span class="till__flag" data-flag="units">8</span></span>
              <span class="till__mark till__mark--dot">.</span>
              <span class="till__slot till__slot--wide" data-slot="cents"><span class="till__flag" data-flag="cents">00</span></span>
            </span>
          </div>
          <button class="till__btn" type="button" data-btn data-autoclic>
            <span class="till__fill" aria-hidden="true"></span>
            <!-- the keys: three columns of three, built in CSS 3D by script.js -->
            <span class="till__bed" aria-hidden="true">
              <span class="till__bank" data-bank></span>
            </span>
            <span class="till__faces">
              <span class="till__face" data-face="rest">
                <span class="till__word" data-wide="Checkout · €48.00" data-rest-text>Checkout · €48.00</span>
              </span>
              <span class="till__face" data-face="busy" aria-hidden="true">
                <span class="till__quiet" data-busy-text>Ringing up…</span>
              </span>
              <span class="till__face" data-face="done" aria-hidden="true">
                <span class="till__paid" data-paid-text>Paid</span>
                <span class="till__sep">·</span>
                <span class="till__order" data-order-text>Order 4821</span>
              </span>
            </span>
          </button>
        </div>
      </div>
      <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.

30 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 registratore di cassa» da Animorio e adattala al mio sito

Cosa fa

Su un fondo nero una pillola di smalto color sangue di bue, alta 60 pixel, con un filetto d'oro che corre tutto intorno appena dentro il bordo e un riflesso caldo in alto a sinistra; a destra Checkout · €48.00 in Mona Sans color avorio. Nella punta di sinistra un incavo scuro, col suo filetto d'oro, tiene nove tasti in tre colonne, decine di euro, euro e centesimi: 50, 40, 30; 8, 5, 1; .50, .25, .00. Ogni tasto ha la faccia di celluloide color avorio con la cifra in Big Shoulders, l'anello di nichel e lo stelo, ed è visto un poco dall'alto, in prospettiva. Sopra la pillola un'insegna dorata con la scritta Amount e una finestrella di vetro scuro dove stanno solo il simbolo dell'euro e il punto; sotto la pillola si vede appena il frontale del cassetto con la maniglia d'ottone. Passando sopra la pillola la scritta si allarga, il fondo si gonfia con un rimbalzo e i tasti tremano sulle loro molle, una colonna dopo l'altra. Al clic arriva Ringing up… e i tasti del totale si abbassano uno dopo l'altro: 40, poi 8, poi .00; ognuno si scalda di un velo d'oro, va giù, e quando il dito lo lascia risale oltre il suo posto e torna. A ogni tasto la sua bandierina bianca salta su nella finestrella, inclinandosi sul perno mentre sale, passa un poco la sua altezza e si ferma: 4, 8, 00, e nella finestrella si legge € 48.00. Poi la molla del cassetto lo spinge fuori: si scopre il vassoio con le banconote nei loro scomparti e le monete dorate e d'argento nelle coppette, il cassetto batte contro il fermo e rimbalza due volte, e a ogni colpo il registratore sobbalza. La pillola dice Paid, in oro, che si alza come una bandierina, e Order 4821. Un altro clic spinge il cassetto dentro, che si chiude con un tonfo (il registratore salta e la pillola si schiaccia), le bandierine ricadono sotto il bordo della finestrella e torna Checkout · €48.00; la vendita dopo sarà l'ordine 4822. Con la tastiera il fuoco mostra un anello dorato che passa dietro l'insegna e i tasti tremano; Invio o Spazio battono il totale. Al telefono il tocco fa tremare i tasti e batte il totale.

Come funziona

I tasti in CSS 3D

Un piano largo 76 pixel è girato di rotateX(52deg) dentro un incavo con perspective: 190px, così i tasti si vedono un poco dall'alto e quelli in fondo sembrano più lontani. Ogni tasto è una pila di otto dischi con transform-style: preserve-3d: un'ombra sfocata sul piano, quattro dischi stretti per lo stelo, due anelli di nichel (un gradiente conico) e la faccia di celluloide con la cifra. Ogni disco sta a translateZ(var(--h) · var(--f)), dove --f è la sua frazione dell'altezza: lo script scrive solo --h per tasto, e premendo la pila si schiaccia tutta insieme, con lo stelo che sparisce sotto la faccia.

Costruiti grandi e rimpiccioliti

Chrome dipinge un livello in 3D alla misura che ha prima della trasformazione: i tasti costruiti a 16 pixel venivano sgranati e le cifre si leggevano male. Ora i tasti sono costruiti quattro volte più grandi (64 pixel, cifre a 29) dentro un contenitore con scale3d(0.25, 0.25, 0.25) e anche le altezze sono moltiplicate per quattro: lo scale3d rimpicciolisce anche l'asse Z, così la prospettiva resta quella giusta e le facce escono nitide a ogni densità di schermo.

Le molle dei tasti

L'altezza di ogni tasto è una molla: h'' = ω² · (H0 − TRAVEL · press − h) − 2 · ζ · ω · h', con ω = 2π · 9 e ζ = KEY_BOUNCE. GSAP muove solo press, il dito: scende in 75 millisecondi con power2.in, resta giù un attimo e si alza di colpo; è la molla a riportare su il tasto, che passa il suo posto e torna. Il piano non si attraversa: sotto 0,6 pixel il tasto si ferma. Al passaggio del puntatore ogni tasto riceve una piccola velocità, colonna per colonna a 45 millisecondi l'una dall'altra, e trema sulla sua molla.

Le bandierine

Ogni bandierina sta in una fessura con overflow: hidden e perspective: 60px, nascosta sotto il bordo con translateY(105%). Quando il suo tasto tocca il fondo, l'obiettivo della sua molla (ω = 2π · 5,5, smorzamento 0,26) passa a 1 e riceve una spinta: sale, va un poco oltre e si ferma. Mentre sale si inclina sul perno con rotateX proporzionale alla sua velocità, così sembra montata su un'asta e non su una guida. Le cifre vengono da TOTAL: decine, unità e centesimi; i tasti di ogni colonna sono la cifra che serve e due vicine, così cambiando il totale nel Playground la tastiera e le bandierine si rifanno da sole.

Il cassetto

Il cassetto è un vassoio in SVG (banconote negli scomparti, monete nelle coppette, l'ombra sotto il registratore) e un frontale smaltato, dentro un contenitore con overflow: hidden che comincia sotto la pillola. La molla lo spinge con una forza che cala mentre si apre, 2600 · KICK · (1 − x / (1,6 · OPEN)), e le guide lo frenano un poco; a OPEN pixel batte sul fermo e torna indietro col 38% della velocità, due o tre volte. Ogni colpo dà una spinta alla molla verticale del registratore, che sobbalza. Al primo colpo la pillola dice Paid e il numero d'ordine. Per chiuderlo un tween power2.in lo riporta a zero, poi il tonfo: il registratore salta, il fondo della pillola si schiaccia e le bandierine ricadono, dai centesimi alle decine.

Gli stati e il ciclo

Tre facce sovrapposte larghe quanto le parole (Checkout · €48.00, Ringing up…, Paid · Order 4821), la pillola misurata una volta sulla più larga. Il pulsante è un button vero con aria-disabled mentre i tasti battono e il cassetto si apre o si chiude, una zona aria-live che dice Ringing up…, poi Paid. Order 4821, €48.00. e infine Drawer closed, e da aperto un aria-label che dice Close the drawer. Battere il totale e aprire il cassetto dura circa 1,5 secondi, meno dei 2,8 fra due clic dell'anteprima: un clic apre, quello dopo chiude, e ogni vendita prende il numero d'ordine seguente. Il loop di fisica dorme quando tutto è fermo e nessun tween sta lavorando.

Valori da cambiare

NomeFileDi partenzaCosa cambia
LABELscript.jsCheckoutLa scritta a riposo, prima del totale.
TOTALscript.js48Il totale in euro, da 0,01 a 99,99: la tastiera mette in ogni colonna la cifra che serve e due vicine, e le bandierine mostrano il totale.
BUSYscript.jsRinging up…La scritta mentre i tasti battono; la dice anche la zona aria-live.
PAIDscript.jsPaidLa parola in oro quando il cassetto è fuori, prima del numero d'ordine.
ORDERscript.js4821Il numero del primo ordine: ogni vendita prende il seguente. In un sito vero è il numero che il tuo server dà all'ordine.
KEY_GAPscript.js0.3I secondi fra un tasto e il successivo.
TRAVELscript.js6Quanto scende un tasto premuto, in pixel (un tasto è alto 9).
KEY_BOUNCEscript.js0.18Come tornano su i tasti: 0,05 rimbalzano a lungo, 0,18 passano il loro posto e tornano, 1 salgono senza passarlo.
KICKscript.js1Quanto forte la molla spinge fuori il cassetto: 0,5 scivola fuori, 2 sbatte sul fermo e rimbalza di più.
OPENscript.js34Quanto esce il cassetto, in pixel: più esce, più si vede del vassoio.

Provali nel Playground

Quando usarla

Per il pulsante che chiude un acquisto: il Checkout o il Pay di un negozio online, la cassa di un'app per i negozi, un caffè o un mercato con un'identità d'epoca, una pasticceria, un barbiere, un negozio di dischi. Va collegato a un pagamento vero: qui il pagamento è simulato, e in un sito vero il cassetto si apre quando il server conferma l'ordine.

Sul telefono

La pillola è larga circa 280 pixel, con l'insegna sopra e il cassetto sotto: a 390 pixel ci sta con margine. Il tocco fa tremare i tasti, schiaccia il fondo e batte il totale; un altro tocco chiude il cassetto. I tasti restano della loro misura e nitidi anche a densità 3.

Con il movimento ridotto

I tasti non si muovono: la faccia di quello premuto si scalda d'oro e torna avorio. Le bandierine compaiono in dissolvenza già al loro posto, il cassetto sparisce chiuso e riappare aperto in dissolvenza, senza rimbalzi né sobbalzi, e le scritte arrivano in dissolvenza. La pillola non si gonfia e la scritta non si allarga (sotto il mouse il fondo si schiarisce appena). Il clic dopo chiude allo stesso modo.

Trappole

  • I tasti costruiti alla loro misura vera (16 pixel) uscivano sgranati: Chrome dipinge un livello in 3D alla misura che ha prima della trasformazione e poi lo ingrandisce per lo schermo, quindi le cifre .25 e 40 erano macchie. Costruiti quattro volte più grandi dentro uno scale3d(0.25, 0.25, 0.25), con le altezze moltiplicate per quattro perché scale3d rimpicciolisce anche Z, sono nitidi.
  • Con il piano girato di 46 gradi la fila di sotto usciva dall'incavo e copriva il filetto d'oro della pillola. A 52 gradi le file si avvicinano e tutti i tasti stanno nell'incavo, con la stessa altezza.
  • L'anello del fuoco da tastiera passava sopra l'insegna, proprio sulla finestrella delle bandierine. L'insegna ha uno z-index sopra il pulsante: l'anello le passa dietro.
  • Il vassoio aperto mostrava solo le monete: le banconote stavano nella parte che resta sotto la pillola. Gli scomparti sono stati spostati verso il frontale, e l'ombra sotto il registratore comincia scura e si schiarisce, così si capisce che il vassoio esce da sotto.

Librerie

GSAP 3.15.0, Mona Sans (font variabile) 5.3.0, Big Shoulders Display (font variabile) 5.3.0.

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

Collaudo

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