
Il pulsante a strati
Pulsanti, Hover, Fisica
Gratis
La barra in alto di una squadra di calcio, col fondo fatto da una curva di stadio: centinaia di cartoncini quadrati, una faccia scura e una oro. Sotto la voce corrente i cartoncini mostrano l'oro in una pillola; scegliendo un'altra voce la curva fa la ola, una colonna di cartoncini che si alzano e si ribaltano corre fin là, la vecchia macchia si spegne e la nuova si accende. Puntando una voce i cartoncini fremono in un'onda circolare.
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 Mexican wave nav</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/saira@5.3.0/wdth.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the top bar of a football club. Its background is a stand of supporters holding up hundreds of small cards,
each with a plain face and a face in the club's gold: under the current link the cards show gold, and
choosing another link a Mexican wave runs there, the cards rising and turning over as it passes -->
<header class="ola" data-bar>
<canvas class="ola__stand" aria-hidden="true" data-stand></canvas>
<canvas class="ola__stand ola__stand--veil" aria-hidden="true" data-veil></canvas>
<span class="ola__lights" aria-hidden="true"></span>
<a class="brand" href="#" aria-label="Ostrel Athletic, home" data-brand>
<svg class="brand__crest" viewBox="0 0 24 28" aria-hidden="true">
<path class="brand__shield" d="M12 1.6 21.4 4.6v8.2c0 6.1-3.9 10.6-9.4 13.6C6.5 23.4 2.6 18.9 2.6 12.8V4.6z"/>
<path class="brand__band" d="M3.4 16.2 20.6 7.4v4.4L4.9 19.9z"/>
<path class="brand__ball" d="M12 4.9 13.6 8.3l3.7.4-2.8 2.5.8 3.6L12 13l-3.3 1.8.8-3.6-2.8-2.5 3.7-.4z"/>
</svg>
<span class="brand__name">Ostrel <span class="brand__light">Athletic</span></span>
</a>
<nav class="strip" aria-label="Main" data-strip>
<ul class="list" data-list>
<li><a class="link" href="#" data-link data-autoclic><span class="link__word">Fixtures</span></a></li>
<li><a class="link" href="#" aria-current="page" data-link><span class="link__word">Squad</span></a></li>
<li><a class="link" href="#" data-link data-autoclic><span class="link__word">Tickets</span></a></li>
<li><a class="link" href="#" data-link data-autoclic><span class="link__word">Club</span></a></li>
<li><a class="link" href="#" data-link data-autoclic><span class="link__word">Shop</span></a></li>
</ul>
</nav>
<a class="cta" href="#" aria-label="Become a member" data-cta><span class="cta__long">Become a member</span><span class="cta__short">Join</span></a>
</header>
</main>
<script src="script.js"></script>
</body>
</html>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
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 nav con la ola» da Animorio e adattala al mio sitoLa barra è divisa in una griglia di celle di CARD pixel (dieci righe in una barra alta 60), e ogni cella è un cartoncino con un angolo, una velocità di rotazione e l'angolo a cui la sua molla lo tira. Ognuno ha anche una piccola inclinazione di riposo, una luminosità, una rigidezza e un ritardo suoi, presi da un generatore casuale col seme: la curva è viva ma uguale a ogni caricamento.
Girare un cartoncino vuol dire spostare di π l'angolo a cui lo tira la sua molla, sempre in avanti: la faccia oro è quella che si vede quando il coseno dell'angolo è negativo. La molla (rigidezza FLIP, smorzamento WOBBLE) si integra in passi di 1/120 di secondo, così anche una molla dura resta stabile; il passo del fotogramma è al massimo 1/30 di secondo, e il cartoncino va un po' oltre e torna, come girato da una mano.
Scegliendo una voce, ogni cartoncino sulla strada fra la pillola vecchia e quella nuova riceve due giri in calendario: verso l'oro nel momento in cui la colonna lo raggiunge (la distanza divisa per SPEED, più LEAN millisecondi per riga, così la colonna si inclina, più il suo ritardo) e verso la faccia che deve tenere dopo BAND/SPEED secondi. Quelli fuori dalla strada che devono cambiare faccia girano in ordine di distanza. La pillola nuova è un rettangolo arrotondato intorno alla parola, misurato sui centri dei cartoncini.
Sotto i cartoncini c'è l'equazione delle onde in 2D, discreta, risolta 240 volte al secondo: ogni cella va verso le vicine (u'' = c²∇²u), una mano la riporta a riposo (−ω²u), perde un po' di moto e i bordi della barra riflettono. La colonna della ola spinge in su le celle che attraversa e lascia una scia; all'arrivo e sotto il puntatore una campana gaussiana apre un anello che si allarga. Il valore dell'onda inclina e solleva i cartoncini.
Ogni cartoncino si disegna sulla tela come un rettangolo alto quanto il coseno del suo angolo, sollevato e un po' ingrandito mentre gira e sulla cresta. La sua luce è la parte diffusa (normale per la direzione dei riflettori, dall'alto e dal davanti) più un lampo quando la faccia guarda le luci; quando è di taglio si vede il bordo chiaro, spesso quanto il seno dell'angolo.
A ogni fotogramma si conta quanti cartoncini sotto ogni parola mostrano l'oro e lo si scrive in --on: il CSS mescola con color-mix il colore della parola dal chiaro allo scuro e le dà un alone dello stesso colore dei cartoncini che ha sotto, che copre le fessure fra loro. Quando niente si muove più il ciclo si ferma.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
CARD | script.js | 6 | Quanto stanno lontani i cartoncini, in pixel: meno ne mette di più. |
SPEED | script.js | 560 | Quanto corre la ola dalla voce vecchia alla nuova, in pixel al secondo. |
BAND | script.js | 150 | Quanto è larga la colonna di cartoncini oro che corre con l'onda, in pixel. |
FLIP | script.js | 380 | Quanto è dura la molla che gira ogni cartoncino: più alta, un giro più svelto. |
WOBBLE | script.js | 0.34 | Quanto poco dondola un cartoncino dopo il giro: meno lo fa dondolare di più. |
LIFT | script.js | 2.6 | Quanto si alza un cartoncino mentre gira e sulla cresta dell'onda, in pixel. |
RIPPLE | script.js | 0.9 | Quanto fremono i cartoncini intorno al puntatore su una voce (0, per niente). |
LEAN | script.js | 9 | Quanto si inclina la colonna, in millisecondi fra una riga di cartoncini e la successiva. |
Per la testata di una squadra, di un campionato, di un festival, di un locale dove si guardano le partite, di un negozio di articoli sportivi o di un'app di biglietti per gli stadi. Coi colori in :root diventa la curva di qualunque squadra: basta cambiare --card e --team.
La barra è alta 56 pixel e larga quanto lo schermo meno 32: resta lo stemma senza il nome e il pulsante dice solo Join (il nome per chi legge lo schermo resta Become a member). I cartoncini si rimpiccioliscono con la barra, sempre dieci righe. Le voci scorrono di lato dentro la barra, che sfuma dal lato dove ce ne sono altre nascoste; la voce scelta scivola al centro e la ola corre già verso il posto dove arriverà. Scorrendo a mano, la pillola segue la parola girando i cartoncini. Il dito su una voce apre l'onda circolare dove tocca.
Niente ola, niente molle e niente onde: la pillola oro è già al suo posto sotto la voce corrente e, scegliendo un'altra voce, la curva vecchia sparisce in una dissolvenza sopra quella nuova, con la pillola già sotto la parola scelta. Le pressioni non rimpiccioliscono niente.
Saira (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 12 KB, e non servono librerie.
Provata il 8 ottobre 2026
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.
Con l’email e la password del tuo account.
oppure con l’email
Hai fatto l’accesso come .
Con l’account scarichi lo zip di ogni animazione e di ogni pacchetto, gratis.