Vai al contenuto
animorio
EN
Tutti i componenti

Il menu che si arrotola

Menu, 3D, WebGL, FisicaWebGL, GSAPImpegnativaPeso compresso: Demo 9,8 KBGSAP 28 KBGratisScarica lo zip

Il menu di un albergo sta sotto un foglio di carta spessa color crema con la parola Menu: premendolo il foglio si arrotola dal basso come una pergamena, un vero rotolo in WebGL avvolto su una spirale che si ingrossa, con il retro della carta in vista e l'ombra sul menu. Il rotolo si afferra e si trascina; lasciato, va su o giù con la sua inerzia.

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 roll-up menu</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/opsz.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/opsz-italic.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/figtree@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the roll-up menu: the menu lies under a sheet of thick cream paper with Menu printed on it. Pressed, the
         sheet rolls up from the bottom like a scroll (a real cylinder, drawn in WebGL) and uncovers the menu; the
         roll can be taken and dragged up and down -->
    <div class="roll" data-roll>
      <nav class="roll__menu" id="roll-menu" aria-label="Main" data-menu inert>
        <ul class="roll__list">
          <li><a class="item" href="#" data-link><span class="item__name">Rooms</span><span class="item__note">Suites and garden rooms</span></a></li>
          <li><a class="item" href="#" data-link><span class="item__name">Dining</span><span class="item__note">Two kitchens, one terrace</span></a></li>
          <li><a class="item" href="#" data-link><span class="item__name">Spa</span><span class="item__note">Thermal pools, open till late</span></a></li>
          <li><a class="item" href="#" data-link><span class="item__name">Offers</span><span class="item__note">Stay three nights, pay for two</span></a></li>
        </ul>
        <a class="book" href="#" data-link>
          <span>Book</span>
          <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12h13.5M13 6.5l5.5 5.5-5.5 5.5"/></svg>
        </a>
      </nav>

      <!-- the sheet of paper, drawn in WebGL; without WebGL a plain sheet that slides up -->
      <canvas class="roll__paper" aria-hidden="true" data-paper></canvas>
      <div class="roll__plain" aria-hidden="true" data-plain><span>Menu</span></div>

      <!-- the real button: the whole sheet while it is down, the roll at the top once it is up -->
      <button class="roll__grip" type="button" aria-expanded="false" aria-controls="roll-menu" data-grip data-autoclic>
        <span class="sr" data-name>Open the menu</span>
      </button>
    </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.

27 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 «Il menu che si arrotola» da Animorio e adattala al mio sito

Cosa fa

Su un fondo nero un foglio di carta spessa color crema, con le fibre appena visibili e gli angoli arrotondati, con stampata grande in corsivo verde scuro la parola Menu e un filetto sotto. Col mouse sopra (o col dito che preme) il bordo di sotto si solleva appena in un ricciolo. Cliccando, il foglio si arrotola dal basso verso l'alto: il bordo si arriccia, diventa un rotolo che sale sopra la carta ancora piatta mostrando sopra il retro più scuro e caldo della carta, con la luce in alto e l'ombra sotto, e si fa più grosso a ogni giro. Sotto il rotolo cade un'ombra sul pannello verde scuro del menu, che si scopre dal basso: Rooms, Dining, Spa e Offers in un grande carattere con grazie, ognuna con la sua riga (Suites and garden rooms, Two kitchens, one terrace…), e un pulsante dorato Book. Il rotolo si ferma in cima. Lo si può afferrare e trascinare su e giù, e lasciato prosegue verso l'alto o verso il basso con la velocità che aveva. Premendo il rotolo, scegliendo una voce o con Esc il foglio si srotola e copre di nuovo il menu. La voce indicata diventa dorata e corsiva.

Come funziona

Una griglia di vertici

Il foglio è una griglia di 13 per 721 vertici, fitta in altezza perché anche il primo giro, il più stretto, resti tondo. Ogni vertice porta solo le sue coordinate nel foglio (u, v): la forma la calcola il vertex shader a ogni fotogramma da tre numeri, la linea dove la carta lascia il tavolo, il raggio del giro esterno e lo spessore della carta.

La spirale di Archimede

Sopra la linea il foglio è piatto. Sotto, la lunghezza s dalla linea si avvolge su una spirale il cui raggio cala di uno spessore a ogni giro: r = R − k·φ, con k = THICK/2π. L'arco percorso è s = R·φ − k·φ²/2, quindi φ = (R − √(R² − 2ks))/k, e il punto è (linea + r·sin φ, R − r·cos φ). Il raggio esterno viene dalla carta già avvolta: R = √(CORE² + THICK·L/π). Così il rotolo si stacca dalla carta piatta senza spigoli, il bordo di sotto finisce al centro e il rotolo si ingrossa davvero.

Fronte, retro e luce

La normale viene dallo stesso angolo: (0, −sin φ, cos φ). Nel fragment shader, se guarda via dall'occhio si vede il retro della carta, di un altro colore e con la sua grana, e la normale si gira. Una luce dall'alto dà il chiaro sopra il rotolo e lo scuro sotto, con un filo di lucido; la carta piatta appena sopra il rotolo cade nella sua ombra. Un po' di prospettiva fa sembrare il rotolo, più vicino all'occhio, appena più grande.

L'ombra e la stampa

Prima della carta si disegna in trasparenza una fascia sotto il rotolo che sfuma verso il basso: l'ombra sul menu, più morbida alle estremità. La parola Menu, le fibre e le sfumature dei bordi sono disegnate in un canvas a doppia densità che diventa la texture; fuori dagli angoli arrotondati il fragment shader scarta i pixel.

Trascinare e lasciare

Il pulsante vero copre tutto il foglio quando è giù e solo la fascia del rotolo quando è su. Trascinando oltre 6 pixel la linea segue il dito, e la velocità si stima con una media mobile; lasciando, la posizione proiettata in avanti decide se andare su o giù, e una molla smorzata (SPRING, BOUNCE) porta il rotolo a destinazione partendo dalla velocità del dito. Si ridisegna solo mentre il rotolo si muove.

Valori da cambiare

NomeFileDi partenzaCosa cambia
THICKscript.js2.8Lo spessore della carta, in pixel: di più, un rotolo più grosso.
COREscript.js6Il raggio del primo giro, al centro del rotolo.
TOPscript.js22Quanta carta piatta resta sopra il rotolo quando è tutto su, in pixel.
SPRINGscript.js70Quanto forte il rotolo è tirato in cima o in fondo una volta lasciato.
BOUNCEscript.js0.8Quanto è frenato: meno, va oltre e oscilla.
SHADOWscript.js0.8Quanto è scura l'ombra del rotolo sul menu.
WORDscript.js'Menu'La parola stampata sul foglio.

Provali nel Playground

Quando usarla

Per il menu di un albergo, un ristorante, una cantina, una libreria o un museo: un sito con un carattere caldo e materico, dove aprire il menu può essere un piccolo gesto tattile. Funziona bene su un pannello a sé, al telefono o in una colonna.

Sul telefono

Il foglio è largo al massimo 360 pixel e si stringe con lo schermo; il canvas segue la densità dello schermo (fino a 2). Il rotolo si trascina col dito (il foglio non fa scorrere la pagina mentre lo si tocca), e il dito che preme solleva il bordo come il mouse sopra.

Con il movimento ridotto

Niente arrotolamento: il foglio svanisce in dissolvenza e ricompare già arrotolato in cima, o già disteso chiudendo. Trascinando, il rotolo segue il dito ma lasciato si mette subito al suo posto, senza inerzia.

Trappole

  • Con il rotolo fatto come un cilindro di raggio fisso i giri si compenetravano e il rotolo non cresceva: la spirale di Archimede con l'arco risolto in forma chiusa dà un raggio che cala di uno spessore a ogni giro, e il raggio esterno che dipende dalla carta avvolta.
  • Le uniformi usate sia nel vertex sia nel fragment shader (la linea e il raggio, per l'ombra sulla carta piatta) devono avere la stessa precisione: con mediump nel fragment il programma non si collegava. Il fragment usa highp dove c'è.
  • Trascinando il rotolo non si muoveva sullo schermo: il ciclo ridisegnava solo se la fisica cambiava la posizione, ma durante il trascinamento la posizione la cambia il puntatore. Ora il puntatore segna il disegno come da rifare.
  • Con meno righe nella griglia il primo giro, di raggio 6 pixel, diventava un poligono a spigoli: servono più di 700 righe sui 480 pixel del foglio.
  • Con il foglio chiuso l'ombra del rotolo sulla carta piatta scuriva il bordo di sotto anche senza rotolo: l'ombra cresce con la carta avvolta e a foglio disteso vale zero.

Librerie

GSAP 3.15.0, Fraunces (font variabile) 5.3.0, Figtree (font variabile) 5.3.0.

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

Collaudo

Provata il 5 ottobre 2026

  • Computer: Fatto
  • Telefono: Fatto
  • Movimento ridotto: Fatto
  • Safari su iPhone: Fatto

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