Vai al contenuto
animorio
EN
Tutti i componenti

La barra con la pedina

Navigazione, Fisica, 3DSolo CSS, GSAPImpegnativaPeso compresso: Demo 11 KBGSAP 28 KBGratisScarica lo zip

La barra in basso di un'app per le serate di giochi da tavolo, in feltro verde: la voce scelta sta sotto una pedina d'avorio con la sua icona incisa. Scegliendone un'altra la pedina viene lanciata lì, si gira in aria e mostra l'icona nuova incisa sull'altra faccia, atterra sul bordo e traballa come una moneta che gira sul tavolo, sempre più veloce, finché si posa.

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 game piece tab bar</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/gabarito@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the tab bar of a board game nights app, in green felt. The tab you are on sits under an ivory game piece with
         its icon carved in the top. Choosing another tab, the piece is tossed there: it flips over in the air and
         shows the new icon, carved on its other face, lands on its rim and rattles down flat like a coin spun on a
         table. The piece is built by the script from the icons below, in layers, and moved in 3D -->
    <nav class="bar" aria-label="Main" data-bar>
      <button class="tab" type="button" data-tab data-autoclic>
        <span class="tab__print" data-print><svg class="tab__icon" viewBox="0 0 24 24" aria-hidden="true" data-icon>
          <path d="M12 3.6c1.55 0 2.75 1.2 2.75 2.7 0 .85-.4 1.6-1 2.05l4.45 1.6c1.05.4 1.55 1.3 1.25 2.15-.3.8-1.1 1.1-2 .9l-2.1-.4 2.5 5.95c.35.9-.25 1.8-1.25 1.8h-2l-2.6-3.85-2.6 3.85h-2c-1 0-1.6-.9-1.25-1.8l2.5-5.95-2.1.4c-.9.2-1.7-.1-2-.9-.3-.85.2-1.75 1.25-2.15l4.45-1.6c-.6-.45-1-1.2-1-2.05 0-1.5 1.2-2.7 2.75-2.7z"/>
        </svg></span>
        <span class="tab__label">Games</span>
      </button>
      <button class="tab" type="button" data-tab>
        <span class="tab__print" data-print><svg class="tab__icon" viewBox="0 0 24 24" aria-hidden="true" data-icon>
          <path d="M18.9 14.3a7.6 7.6 0 1 1-9.3-9.3a6.2 6.2 0 0 0 9.3 9.3z"/>
          <path d="M17.3 3.4l.6 1.5 1.5.6-1.5.6-.6 1.5-.6-1.5-1.5-.6 1.5-.6z"/>
        </svg></span>
        <span class="tab__label">Nights</span>
      </button>
      <button class="tab" type="button" data-tab>
        <span class="tab__print" data-print><svg class="tab__icon" viewBox="0 0 24 24" aria-hidden="true" data-icon>
          <path d="M3.6 20.2h16.8M9.2 20.2V11.2h5.6v9M3.6 20.2v-5.4h5.6M20.4 20.2v-4h-5.6"/>
          <path d="M12 3.7l.75 1.7 1.85.2-1.4 1.25.4 1.85L12 7.75l-1.6.95.4-1.85-1.4-1.25 1.85-.2z"/>
        </svg></span>
        <span class="tab__label">Scores</span>
      </button>
      <button class="tab" type="button" data-tab data-autoclic>
        <span class="tab__print" data-print><svg class="tab__icon" viewBox="0 0 24 24" aria-hidden="true" data-icon>
          <rect x="4.2" y="15.4" width="15.6" height="4.8" rx="1.2"/>
          <rect x="6.4" y="10.6" width="13" height="4.8" rx="1.2"/>
          <rect x="4.8" y="5.8" width="11.6" height="4.8" rx="1.2"/>
        </svg></span>
        <span class="tab__label">Shelf</span>
      </button>
      <button class="tab" type="button" data-tab data-autoclic>
        <span class="tab__print" data-print><svg class="tab__icon" viewBox="0 0 24 24" aria-hidden="true" data-icon>
          <path d="M12 4.2a3.6 3.6 0 1 0 0 7.2a3.6 3.6 0 1 0 0-7.2zM5 19.8c.8-3.6 3.6-5.6 7-5.6s6.2 2 7 5.6"/>
        </svg></span>
        <span class="tab__label">Profile</span>
      </button>
      <!-- the piece's shadow on the felt (clipped to the bar) and the piece itself: both drawn over the tabs, neither
           takes the taps -->
      <span class="bar__shade" aria-hidden="true"><span class="bar__shadow" data-shadow></span></span>
      <span class="piece" aria-hidden="true" data-piece><span class="piece__body" data-body></span></span>
    </nav>
  </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.

21 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 «La barra con la pedina» da Animorio e adattala al mio sito

Cosa fa

Su un fondo bianco, da sola al centro, una barra di feltro verde scuro alta 70 pixel, con la grana fine del panno e una luce un po' più chiara in alto a sinistra, e cinque voci stampate sul feltro in verde chiaro: un meeple (l'omino dei giochi da tavolo), una luna con una stellina, un podio con una stella, una pila di scatole e una persona, coi nomi Games, Nights, Scores, Shelf e Profile. Sopra Scores sta una pedina d'avorio spessa come quelle della dama, col fianco rigato che si vede appena sotto, un solco tondo vicino al bordo e il podio inciso in verde scuro nel mezzo; il nome sotto di lei è chiaro e più grasso. All'arrivo la barra sale e la pedina cade dall'alto girandosi di mezzo giro, tocca sul bordo e traballa fino a posarsi. Scegliendo un'altra voce la pedina viene lanciata: si stacca dal feltro e sale in un arco sopra la barra, mentre la sua ombra scivola di lato e si sfuma, e in aria si gira di mezzo giro (tre mezzi giri per una voce lontana); di taglio mostra il fianco rigato, e la faccia che viene su ha incisa l'icona della voce nuova. Arriva un poco prima di essere piatta, cade sul bordo e traballa come una moneta fatta girare sul tavolo: l'inclinazione gira intorno sempre più veloce mentre cala, il fianco rigato compare da un lato e poi dall'altro, la luce scivola sulla faccia e l'incisione prende la luce dal lato giusto, fino a un tremolio veloce e a un ultimo colpetto quando si posa. Il nome della voce nuova si accende appena la pedina tocca, quello vecchio si spegne appena parte, e l'icona stampata che la pedina lascia scoperta rimbalza un poco sul feltro. Col mouse sopra un'altra voce, o col dito giù, la pedina si inclina verso di lei come se stesse per saltare, e premendo si abbassa appena. Cliccando la voce già scelta la pedina fa un saltello sul posto con un giro intero. Le frecce, Inizio e Fine scelgono da tastiera.

Come funziona

Una pedina di dischi

La pedina è un elemento in CSS 3D: otto dischi impilati a un pixel l'uno dall'altro, in due toni alternati, fanno il fianco rigato, e sopra e sotto ci sono due facce con backface-visibility hidden, ognuna con un SVG: il solco tondo e l'icona disegnata due volte, un labbro chiaro sotto e il taglio scuro sopra. Di taglio i dischi lascerebbero delle fessure: una fascia perpendicolare alle facce fa il fianco pieno, e si vede solo allora. Le icone delle facce si copiano da quelle della barra.

Il lancio

Ogni lancio è un volo balistico scritto a mano: lungo la barra la pedina va dritta a velocità costante, l'altezza è una parabola (che parte dall'altezza di adesso, se la pedina è già in aria) e il giro intorno all'asse verticale è uniforme. I mezzi giri sono dispari, così viene su l'altra faccia, ed è quella, mentre guarda in giù, a ricevere l'icona nuova; FLIPS aggiunge giri interi per le voci lontane. L'altezza si vede come grandezza e come salita sullo schermo, e l'ombra sul feltro scivola di lato, cresce e sfuma.

Atterrare sul bordo

Il giro si ferma TILT gradi prima del piatto, e in quel momento la stessa rotazione si riscrive come un'inclinazione intorno a un asse nel piano (rotateZ, rotateX, rotateZ al contrario): nessuno scatto. Da lì l'inclinazione cala come la radice del tempo che resta, e la sua direzione gira a una velocità inversamente proporzionale all'inclinazione, come nel disco di Eulero: lenta all'inizio, un tremolio veloce alla fine, poi un colpetto. La stessa inclinazione, verso una voce, è il gesto di quando il mouse ci passa sopra.

La luce

A ogni fotogramma, con le stesse rotazioni del CSS, si calcolano la normale della faccia che guarda in su e i suoi due assi sullo schermo. Dalla normale viene quanto la faccia schiarisce o scurisce sotto la luce, che arriva da in alto a sinistra, e dove scivola il riflesso; dai suoi assi, da che parte dell'incisione sta il labbro chiaro. L'ombra si stringe quando la pedina è di taglio e si allunga dal lato rialzato quando è inclinata.

Barra e tastiera

Le voci sono button in un nav e quella scelta ha aria-current="page"; le frecce, Inizio e Fine scelgono e spostano il fuoco, che si vede solo da tastiera. Il ciclo sul ticker di GSAP non scrive niente quando la pedina è ferma. L'anteprima della libreria clicca Games, Shelf e Profile a turno: hanno data-autoclic.

Valori da cambiare

NomeFileDi partenzaCosa cambia
STARTscript.js2La voce scelta all'apertura della pagina (0 è la prima, 2 quella nel mezzo).
TOSSscript.js0.44I secondi di un lancio alla voce accanto (a una lontana un po' di più).
HEIGHTscript.js24Quanto sale la pedina in un lancio alla voce accanto, in pixel (un po' di più verso una lontana).
FLIPSscript.js1I giri in più di un lancio lontano (0: ogni lancio un solo mezzo giro).
RATTLEscript.js1.15I secondi che la pedina traballa sul bordo prima di posarsi (0: atterra piatta).
TILTscript.js24Quanto è inclinata quando tocca sul bordo, in gradi.
LEANscript.js12Quanto si inclina verso la voce sotto il mouse o sotto il dito, in gradi.

Provali nel Playground

Quando usarla

Per la barra in basso di un'app pensata per il telefono, con quattro o cinque sezioni, quando la navigazione può avere carattere: giochi da tavolo, un circolo, un'app di carte o di quiz, un'app per bambini. La pedina dice dove si è anche da ferma, e il lancio fa vedere da dove si viene e dove si va.

Sul telefono

La barra è larga al massimo 420 pixel e sul telefono si stringe allo schermo con 16 pixel di margine per lato (358 su un telefono di 390); resta alta 70 e ogni voce è un bersaglio di circa 69 per 70 pixel. Il dito giù su una voce fa inclinare e abbassare la pedina come il mouse sopra, e il tocco la lancia. In verticale la pagina scorre ancora (touch-action: pan-y).

Con il movimento ridotto

La pedina non vola, non si gira e non traballa: svanisce dalla voce vecchia e ricompare piatta sulla nuova, e il nome si accende in dissolvenza. All'arrivo la barra compare solo in dissolvenza, con la pedina già al suo posto; niente inclinazione verso il mouse, niente pressione.

Trappole

  • Di taglio, a metà del giro, gli otto dischi impilati si vedevano come un pettine con le fessure: una fascia perpendicolare alle facce fa il fianco pieno, e le facce la nascondono in tutti gli altri momenti.
  • Il giro e il traballare dovevano essere un movimento solo: il giro si ferma qualche grado prima del piatto e quella stessa rotazione, riscritta come inclinazione intorno a un asse nel piano, diventa l'inizio del traballare. Scritti come due movimenti, all'atterraggio la pedina scattava.
  • Con la prima legge del traballare l'inclinazione calava subito e l'accelerazione arrivava quando non si vedeva più niente: ora l'inclinazione cala come la radice del tempo che resta e la velocità del giro è inversamente proporzionale all'inclinazione, così il giro che accelera si vede.
  • Cambiando voce a mezz'aria l'icona nuova va sulla faccia che arriverà su, ma senza mai cambiare quella che si vede in quel momento: la faccia si sceglie dalla parità dei mezzi giri che restano, e se ne resta meno di mezzo se ne aggiungono due.
  • Lo strato della luce sopra l'incisione la sbiadiva quando la faccia si girava verso la lampada: ora tinge l'avorio sotto l'incisione, che resta netta. La faccia girata dall'altra parte diventava grigio sporco: si scurisce di meno e in un tono più caldo.
  • All'entrata il ciclo faceva già cadere la pedina per gravità, senza che si vedesse, e quando partiva la caduta vera era già a terra: il lancio parte subito con un tempo negativo e la pedina aspetta in alto.
  • In volo l'ombra scendeva sui nomi delle voci: la luce è alta, quindi l'ombra scivola soprattutto di lato e resta nella riga delle icone.
  • Il transform di GSAP sull'icona stampata che rimbalza avrebbe cancellato quello del CSS per l'hover: GSAP muove un involucro, il CSS l'icona dentro. E premendo sulla barra e lasciando fuori la pedina restava abbassata: il rilascio lo ascolta tutta la finestra.

Librerie

GSAP 3.15.0, Gabarito (font variabile) 5.3.0.

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

Collaudo

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