
Il pulsante di mercurio
Pulsanti, WebGL, Fisica, Hover
NuovaGratis
Una pillola di vetro spesso sopra il suo piccolo quadro, un riquadro blu dove due righe di lettere grandi scorrono senza fermarsi: il vetro piega davvero le lettere che gli passano sotto, sempre di più verso il bordo e con un filo d'arcobaleno, una linea di luce corre sul bordo verso il puntatore, e premuto si schiaccia su una molla. Cliccato diventa una goccia rotonda che tiene due posti, poi si allarga nella risposta.
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 liquid glass button</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/inter@5.3.0/index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/unbounded@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the button: a pill of thick glass over its own small picture, a rounded cobalt panel where two lines of type
slide past each other. Picture and glass are drawn in the same WebGL canvas, inside the panel: first the
picture, then the glass that bends it. Over the glass, a clear <button> moved and sized by the same springs.
The words on the glass are painted by the script from the three faces below (rest, busy, done) -->
<div class="glass" data-glass data-autoclic>
<div class="glass__slot" data-slot>
<canvas class="glass__scene" data-canvas aria-hidden="true"></canvas>
<button class="glass__btn" type="button" data-btn>
<span class="glass__face" data-face="rest" aria-hidden="true">
<svg viewBox="0 0 24 24"><path d="M4 7.5A1.5 1.5 0 0 1 5.5 6h13A1.5 1.5 0 0 1 20 7.5v2.2a2.3 2.3 0 0 0 0 4.6v2.2a1.5 1.5 0 0 1-1.5 1.5h-13A1.5 1.5 0 0 1 4 16.5v-2.2a2.3 2.3 0 0 0 0-4.6z"/><path d="M14.5 8v8" data-dashed/></svg>
<span data-text>Get tickets</span>
</span>
<span class="glass__face" data-face="busy" aria-hidden="true">
<span data-text>Holding your seats</span>
</span>
<span class="glass__face" data-face="done" aria-hidden="true">
<svg viewBox="0 0 24 24"><path d="M5.5 12.5l4.2 4.2 8.8-9.4" data-check/></svg>
<span data-text>2 seats held</span>
<span data-sub>Row F</span>
</span>
</button>
</div>
<!-- the line under the panel: empty at rest, it says what the button is doing -->
<p class="glass__hint"><span data-hint></span></p>
<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>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.
23 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 «Il pulsante di vetro liquido» da Animorio e adattala al mio sitoNiente backdrop-filter: per piegare quello che c'è sotto, il vetro deve poterlo leggere, quindi il quadro e il vetro li disegna lo stesso canvas WebGL, grande quanto il riquadro e con i suoi angoli tondi. Prima il quadro, in una texture grande quanto il riquadro: il blu più le due righe di lettere, dipinte una volta su un canvas 2D alla misura in cui si vedono e ripetute di lato con fract(); poi il vetro, che legge quella texture piegata. Così funziona uguale in Chrome, Safari e Firefox.
La pillola è una distanza con segno: un segmento orizzontale con un raggio, lungo quanto la larghezza meno l'altezza. Così la stessa funzione fa la pillola larga, quella schiacciata e la goccia rotonda, e dà per ogni pixel la normale del bordo e quanto è lontano dal bordo, cioè dove si trova sulla curva.
Nel mezzo piatto il vetro legge il quadro ingrandito di ZOOM. Sul bordo, largo BEVEL pixel, la curva è 1 − √(1 − s²): zero dove comincia il bordo, sempre più ripida verso il filo. Il pixel legge il quadro spostato verso l'esterno di questa curva per BEND, quindi le lettere che stanno appena fuori vengono risucchiate e strizzate dentro. Le letture sono tre, una per canale, col rosso spostato un po' meno e il blu un po' di più (PRISM): l'arcobaleno leggero sul filo.
La luce viene dal puntatore (o, senza, oscilla piano in alto a sinistra): una linea sottile poco dentro al bordo, forte dove il bordo la guarda e debole dalla parte opposta, e un riflesso più largo sulla curva. L'ombra è la stessa distanza spostata in basso di 10 pixel e sfumata. Le parole sono dipinte su un canvas in due canali, rosso per le lettere e verde per un alone, e il vetro le colora guardando quanto è chiaro il quadro per una quarantina di pixel intorno: bianche sul blu, blu scuro sulle lettere crema.
Larghezza, altezza, spostamento e spessore della lente sono cinque molle (SPRING: rigidità e smorzamento), integrate a passi di 1/240 di secondo dentro a un fotogramma limitato a 1/30. Sotto il puntatore la pillola cresce del 4% e si sporge; premuta si schiaccia di SQUISH e la lente si fa più spessa; lasciata riceve una spinta e rimbalza. Siccome la rifrazione si calcola dalla forma, cambia insieme a lei. Il pulsante vero è un button trasparente messo esattamente sopra, mosso dalle stesse molle: il bordo del focus e i tocchi combaciano col vetro.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
ROWS | script.js | ['Look', 'Through'] | Le due righe di lettere che scorrono dietro al vetro. |
DRIFT | script.js | 52 | Quanto in fretta scorrono le lettere, in pixel al secondo. |
BEND | script.js | 44 | Quanto lontano il bordo del vetro va a prendere quello che c'è fuori, in pixel. |
BEVEL | script.js | 30 | Quanto è largo il bordo curvo del vetro, in pixel. |
ZOOM | script.js | 0.07 | Quanto ingrandisce il mezzo piatto del vetro. |
PRISM | script.js | 0.16 | Quanto si separano rosso e blu sul bordo: l'arcobaleno. |
FROST | script.js | 1.6 | La sfocatura dentro al vetro, in pixel. |
SPRING | script.js | [420, 13] | La molla del vetro: la rigidità e lo smorzamento (più basso, più tremola). |
SQUISH | script.js | 0.16 | Quanto si schiaccia il vetro quando lo premi. |
HOLD | script.js | 2 | I secondi in cui gira l'arco mentre si tengono i posti. |
DONE | script.js | 3.6 | I secondi in cui il pulsante dice 2 seats held prima di tornare a riposo. |
Per il pulsante principale sopra un'immagine viva: la copertina di un evento, di un disco, di un'app, un'intestazione con un video o un gradiente che si muove. Lo stile Liquid Glass di Apple, ma su qualunque browser. Rende quando sotto c'è qualcosa di contrastato che passa: sopra una tinta unita il vetro non ha niente da piegare.
Il riquadro è largo quanto lo schermo meno 32 pixel, al massimo 400, e le lettere e la sua altezza lo seguono; il pulsante è un po' più basso. Il tocco schiaccia il vetro e il rilascio lo fa rimbalzare come col mouse, e la luce del bordo va verso il dito finché è giù, poi torna a oscillare. La riga sotto dice Tap invece di Click. Il canvas si disegna al massimo a densità 2.
Le lettere del riquadro sono ferme, il vetro le piega lo stesso e la luce del bordo segue ancora il puntatore. Niente molle: la pillola non si gonfia, non si schiaccia e non rimbalza, e cambia forma senza viaggiare; le parole cambiano in dissolvenza e al posto dell'arco che gira c'è un anello che respira.
GSAP 3.15.0, Inter (font variabile) 5.3.0, Unbounded (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 13 KB; le librerie: GSAP 28 KB.
Provata il 4 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.