
Il menu a sipario
Menu, Fisica, WebGL, Transizioni
NuovaGratis
Il menu di una fabbrica di dolci incartato come una caramella di stagnola color rubino, con le due code attorcigliate: premuto, le code si svolgono girando in versi opposti, la carta si srotola e si stende piatta con le grinze che restano, e sopra compaiono le voci stampate in crema. Sotto il puntatore la stagnola si increspa e luccica; scelta una voce, la caramella si riavvolge con un rimbalzo.
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 candy wrapper menu</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/full.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/full-italic.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the menu of a sweet shop, wrapped like a sweet: at rest it is a candy in ruby foil with its two ends twisted.
Pressed, the ends untwist the opposite ways, the wrapper unrolls and lies flat with its creases, and the menu
is printed on it. The foil is a WebGL mesh drawn by the script; the links below are the real menu, laid over
the flat wrapper -->
<div class="candy" data-candy>
<span class="candy__shadow" data-shadow aria-hidden="true"></span>
<canvas class="candy__gl" data-canvas aria-hidden="true"></canvas>
<button class="candy__toggle" type="button" aria-expanded="false" aria-controls="sweets-menu" data-toggle data-autoclic>
<span class="candy__word" data-name>Open the menu</span>
<svg class="candy__cross" viewBox="0 0 24 24" aria-hidden="true" data-cross><path d="M6.5 6.5l11 11M17.5 6.5l-11 11"/></svg>
</button>
<nav class="candy__nav" id="sweets-menu" aria-label="Main" data-nav inert>
<ul class="candy__list">
<li><a class="sweet" href="#" data-item><span class="sweet__name">Bonbons</span><span class="sweet__note">Hand-wrapped, sold by the jar</span></a></li>
<li><a class="sweet" href="#" data-item><span class="sweet__name">Chocolate</span><span class="sweet__note">Bars, pralines and truffles</span></a></li>
<li><a class="sweet" href="#" data-item><span class="sweet__name">Gift tins</span><span class="sweet__note">Packed and posted for you</span></a></li>
<li><a class="sweet" href="#" data-item><span class="sweet__name">The factory</span><span class="sweet__note">Tours on Saturday mornings</span></a></li>
<li><a class="sweet" href="#" data-item><span class="sweet__name">Visit us</span><span class="sweet__note">The shop on Mill Lane</span></a></li>
</ul>
</nav>
</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.
27 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 caramella» da Animorio e adattala al mio sitoLa carta è una griglia di 140 per 88 punti che lo script ricalcola a ogni fotogramma, in un buffer di WebGL. Ogni colonna della griglia è una striscia che gira intorno alla caramella: la sua posizione lungo la caramella passa da quella incartata (corpo e code) a quella stesa, mentre la striscia è piegata lungo un cerchio.
Ogni punto ha la sua distanza lungo la carta, s, e sta sull’arco di un cerchio di curvatura k: y = sin(ks)/k, z = (cos(ks) − 1)/k. Con k = 2π diviso la lunghezza la striscia è un cerchio chiuso, con k che scende a zero si raddrizza tenendo la sua lunghezza, come la carta vera; con back.out la curvatura va un poco sotto zero e la carta si piega dall’altra parte prima di posarsi.
Tutto il resto è uno spostamento lungo la normale dell’arco: verso l’asse dove la caramella si stringe al collo, avanti e indietro con un’onda a triangolo per le pieghe raccolte (PLEATS), poco per le grinze del foglio steso. La torsione fa scorrere s di un angolo per il raggio, crescente lungo ogni coda e di segno opposto sui due lati: svolgendo le code, il numero va a zero e le code girano in versi opposti.
Le normali vengono dalla griglia (differenze fra i vicini). Nel fragment shader una noise cellulare dà a ogni faccetta della stagnola una sua inclinazione, mescolata con quelle vicine perché le grinze siano nette ma non vetro tagliato, e più lunga sulle code; il riflesso di un piccolo studio fotografico (una grande luce morbida, una striscia, soffitto e pavimento) colora il metallo. L’interno è carta argentata, le pieghe chiuse si scuriscono, e la stampa crema è opaca.
La cornice, il nome del negozio e la parola Menu stanno su una texture disegnata una volta su un canvas grande quanto il foglio steso; Menu è disegnata schiacciata come la schiaccia l’incarto, così da caramella si legge giusta, e sparisce mentre la carta si apre. Le voci sono link veri, sopra il foglio steso: compaiono con una timeline di GSAP alla fine dell’apertura e, sotto il puntatore, danno allo shader il punto da cui parte l’increspatura e il riquadro del luccichio.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
OPEN | script.js | 1.7 | I secondi di tutto lo scartare (riavvolgere è un po’ più veloce). |
TWIST | script.js | 2.6 | Quanto è attorcigliata ogni coda, in radianti. |
PLEATS | script.js | 11 | Quante pieghe fa la carta raccolta intorno alle code. |
CRINKLE | script.js | 0.34 | Quanto sono forti le grinze della stagnola, le faccette che luccicano. |
WRINKLE | script.js | 1.8 | Quanto sono alte le grinze rimaste sul foglio steso, in pixel. |
RIPPLE | script.js | 2 | Quanto è alta l’increspatura sotto la voce puntata, in pixel. |
SHINE | script.js | 1 | Quanto è forte il luccichio che corre sulla stagnola. |
TILT | script.js | [24, -12] | Di quanti gradi la carta si inclina all’indietro e gira mentre si srotola. |
SETTLE | script.js | elastic.out(1, 0.42) | Come si assestano le code quando si riattorcigliano: il rimbalzo. |
Per il sito di una pasticceria, una confetteria, una fabbrica di cioccolato o un negozio di regali: dove il menu può essere un piccolo dolce da scartare. Con quattro-sei voci corte; per un menu lungo il foglio non basta.
Il riquadro è largo al massimo lo schermo meno 32 pixel e il foglio si ricalcola a ogni cambio di larghezza. Il tocco apre e chiude; senza puntatore la caramella non rotola in attesa, e la voce toccata si increspa e luccica prima che la carta si riavvolga.
Niente torsione né srotolamento: la caramella e il foglio steso si scambiano in dissolvenza, le voci compaiono senza muoversi, la stagnola non si increspa (il luccichio, che è solo luce, resta).
GSAP 3.15.0, Fraunces 5.3.0.
Compressi con gzip, i tre file della demo pesano 13 KB; le librerie: GSAP 28 KB.
Provata il 9 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.