
L’indicatore a lancetta
Contatori, Fisica, SVG
NuovaGratis
Una striscia di schede come in cima a un browser, senza marchi: si trascinano e le altre si scansano su molle, quella in mano si inclina con la velocità mentre i suoi piedini curvi restano piantati sulla barra. Il più apre una scheda che cresce dal pulsante, la croce ne chiude una che si stringe, e con tante schede restano solo le icone.
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 browser tabs</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/geist@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- a strip of tabs like a browser's: drag them and the others move aside on springs, the dragged one leans with
its speed; the active tab is one SVG shape with curved feet that melts into the bar underneath -->
<div class="browser" data-browser>
<div class="strip" data-strip>
<svg class="sheet" aria-hidden="true" data-sheet><path class="sheet__shade" data-shade/><path class="sheet__body" data-body/><path class="sheet__edge" data-edge/></svg>
<div class="tabs" role="tablist" aria-label="Open tabs" aria-describedby="tabs-help" data-tabs>
<div class="tab" role="tab" data-icon="mail" data-autoclic>Inbox</div>
<div class="tab" role="tab" data-icon="road" data-active>Q3 roadmap</div>
<div class="tab" role="tab" data-icon="plane" data-autoclic>Flight to Lisbon</div>
<div class="tab" role="tab" data-icon="pot">Weeknight recipes</div>
<div class="tab" role="tab" data-icon="notes" data-autoclic>Design review notes</div>
<div class="tab" role="tab" data-icon="peak">Trail maps</div>
</div>
<button class="plus" type="button" aria-label="New tab" data-plus>
<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M8 3v10M3 8h10"/></svg>
</button>
</div>
<!-- the bar under the active tab: the same colour, so the tab and the bar are one piece -->
<div class="bar" role="tabpanel" data-panel>
<div class="bar__nav" aria-hidden="true">
<svg viewBox="0 0 16 16"><path d="M10 3.5L5.5 8l4.5 4.5"/></svg>
<svg viewBox="0 0 16 16"><path d="M6 3.5L10.5 8 6 12.5"/></svg>
<svg viewBox="0 0 16 16"><path d="M12.6 8.6a4.7 4.7 0 1 1-1.5-4.1"/><path d="M11.6 1.9v2.9H8.7"/></svg>
</div>
<div class="bar__address">
<span class="bar__icon" data-bar-icon></span>
<span class="bar__title" aria-live="polite" data-bar-title></span>
</div>
</div>
<p class="sr" id="tabs-help">Arrow keys switch tabs, Shift with an arrow moves a tab, Delete closes it.</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>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.
26 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 «Le schede del browser» da Animorio e adattala al mio sitoLo spazio fra le due estremità, meno il più, si divide fra le schede aperte dentro TAB_WIDTH; quando diventano strette, la scheda attiva tiene ACTIVE_MIN e le altre si dividono il resto. Ogni scheda ha così una x e una larghezza di arrivo, e il più si mette subito dopo l’ultima. Dopo una chiusura col mouse le larghezze possono stringersi ma non allargarsi, finché il puntatore non lascia la striscia.
La x e la larghezza di ogni scheda, la x del più e i due bordi della forma attiva sono numeri con una velocità, tirati verso la loro meta da una molla smorzata (SPRING) in un ciclo di requestAnimationFrame, col passo limitato a 1/30 di secondo. Il ciclo si spegne quando tutto è fermo. Una scheda nuova parte larga zero dalla x del più; una chiusa ha larghezza di arrivo zero e si toglie dalla pagina quando ci arriva.
La scheda attiva è un tracciato SVG riscritto a ogni fotogramma dai suoi due bordi: dal piede sinistro (un quarto di cerchio di raggio FOOT che curva verso la barra) su per il lato, gli angoli in alto, giù per l’altro lato e fuori lungo il piede destro. Quando cambia scheda il bordo verso cui si va usa la molla piena e l’altro una molla più morbida (TRAIL), così la forma si allunga e poi si raccoglie.
Con pointer events e setPointerCapture la scheda presa segue la mano; la sua velocità, filtrata, dà l’inclinazione (LEAN gradi per pixel al secondo, fino a MAX_LEAN), su una sua molla che la riporta dritta. Il contenuto ruota attorno alla base e nella forma si spostano solo gli angoli in alto: i piedini restano sulla barra. Il posto della scheda è il numero di altre schede di cui ha passato il centro; lasciata, entra nel posto con la velocità della mano.
La striscia è un tablist con un solo elemento raggiungibile col Tab (tabindex mobile): le frecce cambiano scheda, Home e End vanno ai capi, Maiuscole e una freccia spostano la scheda di un posto, Canc la chiude. La barra sotto è il tabpanel, etichettato dalla scheda attiva, e l’ordine degli elementi nella pagina segue quello sullo schermo dopo ogni spostamento.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
SPRING | script.js | [320, 0.72] | Le schede che vanno al loro posto: la forza della molla e lo smorzamento (1 = senza rimbalzo). |
TRAIL | script.js | 0.42 | Quanto è più morbida la molla del bordo dietro della forma attiva: più basso, si allunga di più. |
LEAN | script.js | 0.011 | I gradi di inclinazione della scheda trascinata per ogni pixel al secondo di velocità. |
MAX_LEAN | script.js | 8 | L’inclinazione massima della scheda trascinata, in gradi. |
TAB_WIDTH | script.js | [38, 224] | La larghezza minima e massima di una scheda, in pixel. |
ACTIVE_MIN | script.js | 118 | La larghezza che la scheda attiva tiene finché c’è posto, perché il titolo si veda. |
FOOT | script.js | 9 | Il raggio dei piedini curvi della scheda attiva, in pixel. |
NEW_TITLE | script.js | 'New tab' | Il titolo di una scheda aperta col più. |
Per un’app con più documenti aperti insieme (un editor, un client di posta, uno strumento di design, un terminale nel browser), per i file di un IDE, o per una pagina che mostra un prodotto con l’aspetto di un browser. Da due a una quindicina di schede.
A 390 pixel le schede sono strette: la scheda attiva tiene il titolo e la croce, le altre mostrano solo l’icona. Si trascinano col dito (touch-action: pan-y, così il dito in verticale scorre ancora la pagina), si toccano per sceglierle, e il più apre una scheda finché c’è posto per un’altra icona. Niente sfora di lato.
Niente molle e niente inclinazione: le schede vanno subito al loro posto, la forma attiva salta alla nuova scheda, quella trascinata segue la mano e lasciata si posa; una scheda chiusa sparisce e una nuova compare già larga. Il titolo nella barra cambia in dissolvenza.
GSAP 3.15.0, Geist (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 9,3 KB; le librerie: GSAP 28 KB.
Provata il 5 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.