Vai al contenuto
animorio
EN
Tutti i componenti

La nav di vetro colorato

Navigazione, Hover, Fisica, ImmaginiCanvas, GSAPImpegnativaPeso compresso: Demo 20 KBGSAP 28 KBGratisScarica lo zip

La barra in alto di un museo del vetro fatta come una vetrata: ogni voce è una lancetta di vetro colorato a sesto acuto, chiusa nel suo piombo, con le venature, le bollicine e il bordo dipinto più scuro del vetro soffiato. Una luce calda dietro la barra passa attraverso la tessera della pagina in cui si è e getta il suo colore sul pavimento sotto la barra, rovesciato e allargato come la luce delle vetrate in una chiesa; puntando un'altra voce la luce le scivola dietro su una molla. Vetro, piombo e riflesso sono calcolati pixel per pixel.

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 stained glass nav</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/cinzel@5.3.0/index.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/mona-sans@5.3.0/wdth.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the top bar of a glass museum, made as a leaded window: every link is a lancet of coloured glass in its dark
         lead, with the grain, the cords and the seeds of hand-made glass. A warm light behind the bar shines through
         the tile of the page you are on and throws its colour on the floor under the bar, like the light on the floor
         of a church; pointing at another tile the light slides behind it. On a phone the links open in a second
         window, one row of glass each, and the light drops into it -->
    <div class="vitrail" data-vitrail data-autoclic>
      <header class="bar" data-bar>
        <canvas class="glass" aria-hidden="true" data-glass></canvas>

        <a class="brand" href="#" aria-label="Aldgrave Glass Museum, home" data-brand>
          <span class="brand__rondel" aria-hidden="true" data-rondel></span>
          <span class="brand__name">Aldgrave</span>
        </a>

        <nav class="nav" id="aldgrave-links" aria-label="Main" data-nav>
          <canvas class="nav__glass" aria-hidden="true" data-panel-glass></canvas>
          <ul class="list" data-list>
            <li class="item" data-glass-color="ruby"><a class="link" href="#" data-link><span class="link__word" data-text="Collection">Collection</span></a></li>
            <li class="item" data-glass-color="cobalt"><a class="link" href="#" aria-current="page" data-link><span class="link__word" data-text="Exhibitions">Exhibitions</span></a></li>
            <li class="item" data-glass-color="amber"><a class="link" href="#" data-link><span class="link__word" data-text="Studio">Studio</span></a></li>
            <li class="item" data-glass-color="emerald"><a class="link" href="#" data-link><span class="link__word" data-text="Learn">Learn</span></a></li>
            <li class="item" data-glass-color="violet"><a class="link" href="#" data-link><span class="link__word" data-text="Shop">Shop</span></a></li>
          </ul>
        </nav>

        <div class="end" data-end>
          <a class="cta" href="#" data-cta><span class="cta__bg" aria-hidden="true" data-cta-bg></span><span class="cta__label">Tickets</span></a>
        </div>

        <button class="toggle" type="button" aria-expanded="false" aria-controls="aldgrave-links" data-toggle>
          <span class="toggle__label" data-toggle-label>Menu</span>
          <svg class="toggle__icon" viewBox="0 0 20 20" aria-hidden="true">
            <path class="toggle__line" d="M3.5 7.5L16.5 7.5" data-line/>
            <path class="toggle__line" d="M3.5 12.5L16.5 12.5" data-line/>
          </svg>
        </button>
      </header>

      <!-- the light that comes through the glass, on the floor under the bar (and under the window of the phone) -->
      <canvas class="floor" aria-hidden="true" data-floor></canvas>
      <canvas class="floor floor--panel" aria-hidden="true" data-panel-floor></canvas>
    </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.

38 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 nav di vetro colorato» da Animorio e adattala al mio sito

Cosa fa

Su un fondo bianco una barra alta 64 pixel e larga fino a 1000, fatta come una vetrata: una cornice di piombo scuro con gli angoli tondi e dentro sette lancette di vetro una accanto all'altra, ognuna con la punta del suo arco che tocca la cornice. A sinistra il nome Aldgrave in capitali romane scure, dipinto su un vetro antico chiaro accanto a un tondo di vetro soffiato verde oro con i suoi anelli; poi le cinque voci su vetri colorati: Collection rubino, Exhibitions cobalto, Studio ambra, Learn smeraldo, Shop viola, con le lettere chiare come se fossero state molate via dal colore e un filo scuro intorno; in fondo il pulsante scuro Tickets su un altro vetro chiaro. Ogni tessera colorata è tagliata in tre pezzi da due piombi obliqui, uno di vetro più scuro e uno più pallido dello stesso colore, e sopra l'arco ci sono due angoli di vetro chiaro; dove i piombi si incontrano c'è una goccia di stagno. Il vetro non è piatto: ha le venature allungate del vetro tirato a mano, qualche ciuffo opalino, le bollicine e il bordo più scuro lungo il piombo. All'apertura i vetri si schiariscono come al mattino e una luce calda si accende dietro Exhibitions: la tessera si illumina di un blu pieno, le lettere si scaldano e sotto la barra si allarga sul pavimento una pozza di luce blu, con le righe d'ombra dei piombi e i puntini chiari delle bollicine, che sbiadisce allontanandosi. Puntando un'altra voce la luce le scivola dietro su una molla, passa un poco oltre e torna, e la pozza sul pavimento cambia colore con lei; la pagina in cui si è resta un po' accesa e getta ancora un velo del suo colore. Scegliendo una voce la luce si ferma lì e ha un piccolo bagliore. Con Tab o con le frecce la luce segue il fuoco, segnato da un anello d'oro intorno alla parola.

Come funziona

La vetrata è una mappa di pezzi

Lo script misura le voci nel DOM e ne ricava un piano: le zone una accanto all'altra (il nome, le cinque tessere, il pulsante), l'arco di ogni lancetta (y = F + RISE·(0,4u + 0,6(1 − √(1 − u))), con u la distanza dal centro sulla mezza larghezza: punta in mezzo, quasi dritto dove nasce), i due tagli obliqui di ogni tessera tenuti lontani dalla parola, il tondo accanto al nome. Per ogni pixel del canvas (fino a 300 000) una funzione pieceAt(x, y) dice a quale pezzo appartiene. Al telefono il piano è un'altra vetrata: righe colorate in una cornice di vetro chiaro con i quadretti d'oro.

Il piombo è un campo di distanze

Ogni pixel che confina con un pezzo diverso è un seme; la trasformata di distanza esatta di Felzenszwalb e Huttenlocher (due passate di parabole, prima le colonne poi le righe) dà a ogni pixel la distanza dal bordo più vicino, ammorbidita con due passate di sfocatura perché sui tagli obliqui la scaletta dei pixel non lasci il piombo attorcigliato come una corda. Dove la distanza è sotto 1,6 pixel c'è piombo; il gradiente del campo dà la normale del suo profilo tondo, illuminato dall'alto con una luce diffusa e un riflesso. Le gocce di stagno sono cerchi uniti al piombo con un minimo morbido, la cornice viene dalla distanza con segno di un rettangolo arrotondato.

Il vetro: spessore, venature, bollicine

Per ogni pezzo un rumore frattale allungato lungo un angolo tutto suo (scale di 30 e 6,5 pixel) fa le venature, un rumore fine fa la martellatura; il loro valore è lo spessore, cioè quanta luce passa, e la loro pendenza diventa uno spostamento (RIPPLE): ogni pixel cerca la luce in un punto un po' spostato, così la luce dietro trema attraverso le venature. Le tessere hanno qualche ciuffo opalino e il bordo dipinto più scuro lungo il piombo; le bollicine, una ogni 230 pixel quadrati circa, sono ellissi chiare al centro, dove concentrano la luce, e scure sul bordo. Tutto questo si calcola una volta per ogni misura.

A ogni fotogramma, un piccolo shader in JavaScript

Ogni pixel di vetro somma la luce del giorno, un po' più forte in alto, e la luce calda: una gaussiana ellittica centrata dietro la tessera (letta da una tabella di 1024 valori), più un secondo lume più debole dietro la pagina corrente quando la luce va altrove. Il colore del vetro per lo spessore per la luce passa da una curva di tono (1 − e^(−1,6x), poi la gamma) che arrotonda le parti forti invece di tagliarle; il piombo si mescola sopra con la sua copertura. Le lettere vere, nel DOM, ricevono --lit, quanto sono illuminate, per il colore e l'alone.

La luce sul pavimento guarda indietro

Il pavimento è un canvas a metà risoluzione sotto la barra. Ogni suo punto, per ogni luce, guarda indietro attraverso la vetrata: la riga t del pavimento corrisponde alla riga bottom − t·altezza della vetrata (il fondo cade vicino, l'alto lontano: l'immagine è rovesciata), e la x si avvicina alla luce di 1 + SPREAD·t, così la macchia si allarga. Il punto prende il colore del vetro che attraversa, la sua trasparenza e la luce che c'è dietro; il piombo lascia una riga d'ombra. Le luci si sommano come vetri sovrapposti.

La molla della luce, nello spazio delle voci

La luce non vive in pixel ma nello spazio delle voci (1,5 è a metà fra la seconda e la terza): una molla con la rigidità GLIDE e lo smorzamento ricavato da BOUNCE la porta alla voce puntata, a passi di 1/120 di secondo con il tempo limitato a 1/30. Così se la finestra cambia misura a metà corsa la vetrata si ricostruisce e la luce resta al suo posto relativo. In corsa la macchia si allunga con la velocità. Quando la molla è ferma e nessuna animazione è in corso il ciclo si spegne e non si disegna niente.

Valori da cambiare

NomeFileDi partenzaCosa cambia
GLIDEscript.js150Quanto tira la molla che porta la luce dietro la voce puntata: più alto, più svelta.
BOUNCEscript.js0.1Quanto la luce passa oltre la voce e torna indietro, in parte della strada (0, per niente).
LIGHTscript.js2.2Quanto è forte la luce calda dietro la barra.
DAYLIGHTscript.js0.3La luce del giorno, fioca, che passa da tutti i vetri: più alta, vetri più chiari anche al buio.
FLAREscript.js0.45Quanto si accende di più la luce quando si sceglie una pagina (0, per niente).
FLOORscript.js0.7Quanto è forte la luce colorata gettata sul pavimento (0, niente).
SPREADscript.js0.8Quanto si allarga la luce sul pavimento allontanandosi dalla barra.
SEEDSscript.js1Quante bollicine ci sono nel vetro (0, nessuna).
RIPPLEscript.js1Quanto il vetro irregolare piega la luce che ha dietro (0, vetro piatto).

Provali nel Playground

Quando usarla

Per la testata di chi ha a che fare col vetro, con la luce o con l'arte sacra: un museo del vetro, una galleria, una vetreria o una bottega di vetrate, un laboratorio di soffiatura, una chiesa o un'abbazia aperta alle visite, un festival di luce. Sta bene con poche voci corte, ognuna col suo colore; i colori dei vetri, del piombo e della luce si cambiano nelle variabili.

Sul telefono

Sotto i 760 pixel la barra è alta 60 pixel, larga quanto lo schermo meno 32 (358 a 390): a sinistra il nome con il tondo, a destra il pulsante Menu su una lancetta del colore della pagina in cui si è, con la luce dietro e la sua pozza sul pavimento. Toccato, sotto la barra scende una seconda vetrata con le cinque voci in righe di vetro colorato, in una cornice di vetro chiaro con i quadretti d'oro: la luce cala dall'alto dentro la riga della pagina corrente e la sua pozza si apre sotto la vetrata. Facendo scivolare il dito sulle righe la luce lo segue, e la riga su cui lo si alza viene scelta; il vetro del pulsante prende il suo colore e la vetrata si richiude. Sotto i 980 pixel il pulsante Tickets sparisce.

Con il movimento ridotto

La luce non viaggia: puntando o scegliendo un'altra voce si spegne in una breve dissolvenza dove era e si riaccende dietro la tessera nuova, con la sua pozza sul pavimento. Niente bagliore, niente scritte che si schiacciano, il pulsante non si allarga. Al telefono la vetrata compare e sparisce con una dissolvenza, con la luce già al suo posto.

Trappole

  • Il primo arco, 1 − √(1 − u), su tessere larghe 130 pixel e alte 54 era quasi una riga dritta in cima: la vetrata sembrava una fila di bottoni. L'arco ora ha una parte lineare che lo fa puntare, ogni tessera è tagliata in tre da due piombi obliqui e la cornice ha le gocce di stagno: si legge come vetrata al primo sguardo.
  • Sui tagli obliqui il piombo calcolato dalla trasformata di distanza era attorcigliato come una corda: i semi sono pixel a scaletta e il gradiente del campo cambiava direzione a ogni gradino. Due passate di sfocatura sul campo prima dell'ombreggiatura lo rendono liscio senza allargarlo.
  • La pozza sul pavimento era grigio lavanda invece che blu: il colore era quello del vetro normalizzato e passato dalla gamma, che lo sbiadiva. Ora è il colore del vetro come appare con la luce dietro, passato dalla stessa curva di tono della barra.
  • Con la luce dietro un'altra voce, il lume della pagina corrente gettava una scia lunga e storta sul pavimento: la proiezione usava come centro la luce principale per tutte e due. Ogni luce ora guarda indietro dal suo centro, e i contributi si sommano.
  • Con la luce piena il verde e l'ambra diventavano color menta e crema: l'alone bianco delle parti forti partiva troppo presto. Ora parte solo sopra 1,6 volte la luce piena ed è più debole, e i vetri accesi restano saturi.
  • Al telefono la vetrata, chiudendosi, si tagliava di lato: il browser riscrive inset(0px 0px 0% 0px round 15px) con tre valori, e GSAP interpolava i numeri nell'ordine sbagliato. La chiusura ora parte da una stringa scritta per intero.
  • La pozza sotto la vetrata del telefono, alta 270 pixel, finiva lontana e schiacciata in una riga: ora il pavimento mostra solo le righe intorno alla luce, con quella accesa in mezzo, e la pozza parte subito sotto la vetrata.

Librerie

GSAP 3.15.0, Cinzel (font variabile, con l'asse del peso) 5.3.0, Mona Sans (font variabile, con l'asse della larghezza, per il pulsante) 5.3.0.

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

Collaudo

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