
Il menu a fluido
Menu, WebGL, Fisica, Transizioni
NuovaGratis
Il menu di un cinema sta su un piccolo palco dietro un sipario di velluto rosso: premendo Menu le due tende scorrono sul binario, vengono legate ai lati con le pieghe che ondeggiano e sotto un occhio di bue compaiono le voci. Il sipario è una stoffa simulata davvero, punti e fili in WebGL, e col puntatore vicino il suo bordo si scosta e si increspa.
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 curtain menu</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/bodoni-moda@5.3.0/opsz.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/bodoni-moda@5.3.0/opsz-italic.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/hanken-grotesk@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the curtain menu: the button that opens and closes it, and the stage in its gilded arch, closed by the
curtain, with the menu standing behind it -->
<div class="theatre" data-theatre>
<div class="bar">
<button class="toggle" type="button" aria-expanded="false" aria-controls="programme" data-toggle data-autoclic>
<svg class="toggle__icon" viewBox="0 0 24 24" aria-hidden="true">
<path class="toggle__rail" d="M2.5 3.5h19"/>
<path class="toggle__drape toggle__drape--left" d="M3.5 4h8.2c-.4 5.6-2.6 11.3-8.2 16.2z"/>
<path class="toggle__drape toggle__drape--right" d="M20.5 4h-8.2c.4 5.6 2.6 11.3 8.2 16.2z"/>
</svg>
<span class="toggle__words" aria-hidden="true"><span class="toggle__word" data-word>Menu</span></span>
<span class="sr" data-name>Open the menu</span>
</button>
</div>
<!-- the stage: the menu stands on it, behind the curtains. The curtains and the valance over them are a cloth
simulated in WebGL on the canvas, which lets the pointer through to the menu once they are open -->
<div class="frame">
<div class="scene" data-stage>
<div class="set" aria-hidden="true">
<span class="set__spot" data-spot></span>
<span class="set__floor"><svg viewBox="0 0 100 100" preserveAspectRatio="none"><path d="M6.8 0L-2.8 100M10.4 0L1.6 100M14.0 0L6.0 100M17.6 0L10.4 100M21.2 0L14.8 100M24.8 0L19.2 100M28.4 0L23.6 100M32.0 0L28.0 100M35.6 0L32.4 100M39.2 0L36.8 100M42.8 0L41.2 100M46.4 0L45.6 100M50.0 0L50.0 100M53.6 0L54.4 100M57.2 0L58.8 100M60.8 0L63.2 100M64.4 0L67.6 100M68.0 0L72.0 100M71.6 0L76.4 100M75.2 0L80.8 100M78.8 0L85.2 100M82.4 0L89.6 100M86.0 0L94.0 100M89.6 0L98.4 100M93.2 0L102.8 100"/></svg></span>
</div>
<nav class="programme" id="programme" aria-label="Main" data-menu inert>
<ul class="programme__list">
<li><a class="act" href="#" data-link><span class="act__name">What’s on</span><span class="act__note">Eighteen nights in October</span></a></li>
<li><a class="act" href="#" data-link><span class="act__name">Films</span><span class="act__note">On 35 and 70 mm</span></a></li>
<li><a class="act" href="#" data-link><span class="act__name">Supper club</span><span class="act__note">Tables from 6 pm</span></a></li>
<li><a class="act" href="#" data-link><span class="act__name">Private hire</span><span class="act__note">Up to 240 guests</span></a></li>
<li><a class="act" href="#" data-link><span class="act__name">Visit</span><span class="act__note">Box office and directions</span></a></li>
</ul>
<div class="programme__foot" data-extra>
<a class="tickets" href="#">Book tickets</a>
</div>
</nav>
<canvas class="cloth" data-cloth aria-hidden="true"></canvas>
<div class="velvet" data-velvet aria-hidden="true"><span></span><span></span></div>
<div class="apron" data-apron aria-hidden="true"></div>
</div>
</div>
</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.
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 «Il menu a sipario» da Animorio e adattala al mio sitoOgni tenda è una griglia di 40 per 34 punti. A ogni passo (fisso, un sessantesimo di secondo) un punto si muove di quanto si è mosso nel passo prima, frenato appena, più la gravità: è l’integrazione di Verlet, che non tiene velocità ma la posizione di prima. Poi i fili fra punti vicini (in orizzontale, in verticale, in diagonale, e a due passi in verticale per non piegarsi troppo) vengono riportati alla loro lunghezza STIFF volte di fila. Un filo resiste tanto all’allungarsi e quasi niente all’accorciarsi: così raccolto il velluto si piega morbido invece di accartocciarsi.
La prima riga è appesa ai ganci del binario, che vanno avanti e indietro in profondità (0, 1, 0, −1, con piccole differenze fra una piega e l’altra): i fili orizzontali nascono più lunghi del passo fra due ganci di FULLNESS volte, ed è quella stoffa in più che fa le pieghe. Aprendo, i ganci si avvicinano fino a GATHER della larghezza del palco e le pieghe si fanno più profonde da sole, perché il filo resta lungo uguale.
Mentre il sipario si apre, una riga a metà altezza viene tirata un po’ a ogni iterazione verso un punto che parte dai ganci e arriva al nodo, in TIE (di lato e in basso): tirata subito al nodo, la stoffa sotto ci girerebbe sopra di colpo. L’apertura stessa (da 0 a 1) avanza dentro la simulazione, un passo alla volta: su un telefono lento che fa meno passi del dovuto la corda non va avanti senza la stoffa.
Le tende sono due reti di triangoli con le normali ricalcolate a ogni fotogramma dai punti vicini. Lo shader dà al velluto il suo aspetto: luce diffusa, una lucentezza dove la piega gira di taglio (1 − n.z), buio in fondo alle pieghe secondo la profondità del punto, e un filo di rumore. In basso la frangia: fili d’oro ritorti disegnati con un seno sulla coordinata della stoffa, con le punte sfrangiate scartando dei pixel; sopra, un gallone. La mantovana è lo stesso shader su una forma ferma a festoni, con le rosette disegnate nello shader.
I punti a meno di un sesto del palco dal puntatore vengono spinti di lato (soprattutto lungo il bordo libero, che così si apre), trascinati dal suo movimento e gonfiati in avanti, con un’increspatura che continua anche col puntatore fermo. A riposo una corrente leggera (BREEZE) muove il velluto in basso. La tela lascia passare il puntatore: sotto c’è il menu vero, con i suoi link.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
OPEN | script.js | 1.8 | I secondi del sipario che si apre (chiudendo ci mette un po’ meno). |
GATHER | script.js | 0.3 | Dove si ferma la cima di ogni tenda aperta, in frazione della larghezza del palco dal suo lato. |
TIE | script.js | [0.12, 0.52] | Dove viene legata ogni tenda: di lato e in basso, in frazioni del palco. |
FULLNESS | script.js | 1.8 | Quanto il velluto è più largo della metà di palco che copre: di più, pieghe più profonde. |
SWAY | script.js | 1 | Quanto il sipario si scosta e ondeggia vicino al puntatore. |
BREEZE | script.js | 0.6 | La corrente d’aria che muove il velluto a riposo. |
STIFF | script.js | 10 | Quante volte a ogni passo i fili vengono riportati alla loro lunghezza: meno, una stoffa più elastica (e più leggera da calcolare). |
Per il sito di un teatro, un cinema, un club, un ristorante con la sala o un evento: dove aprire il menu può essere un piccolo spettacolo e il velluto c’entra davvero. Per un sito di tutti i giorni è troppo: il sipario chiede un momento di attenzione.
Il palco si stringe alla larghezza dello schermo e diventa alto; lì le tende si raccolgono più strette (il 70% di GATHER e di TIE), con meno stoffa e il nodo un po’ più in basso, per lasciare libero il menu. Il tocco apre e chiude; il dito che scorre sul sipario lo fa ondeggiare come il mouse.
Il sipario non scorre: si dissolve e ricompare già aperto e legato (o già chiuso), con le pieghe ferme, senza corrente e senza ondeggiare sotto il puntatore; le voci compaiono in dissolvenza senza salire.
GSAP 3.15.0, Bodoni Moda (font variabile) 5.3.0, Hanken Grotesk (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 14 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.