
Il rilievo a trattini
WebGL, 3D, Hover
Gratis
L’intestazione di una cioccolateria inventata, nello stile ricco: una scatola di nove praline costruita in 3D, verde petrolio con la stampa a caldo d’oro e il nastro di raso rosa annodato in un fiocco, che si inclina verso il puntatore. Un clic scioglie il nastro e apre il coperchio sulla cerniera; la pralina sotto il puntatore, o sotto il dito, si solleva dal suo pirottino girando, con uno sbuffo di cacao, e il suo nome compare sul cartoncino.
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 praline box to open</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/mona-sans@5.3.0/wdth.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="shop" data-shop>
<!-- the header of a made-up chocolatier, Maison Noix: a box of nine pralines in 3D that tilts with the pointer.
Click the box: the satin ribbon unties, the lid swings open on its hinge and the pralines show in their paper
cups. The praline under the pointer (or the finger) lifts out of its cup and its name appears on the card -->
<header class="shop__bar">
<span class="shop__brand" data-brand>Maison Noix</span>
<span class="shop__where">Chocolatier since 1931</span>
</header>
<section class="shop__copy">
<p class="shop__kicker">The Saturday box</p>
<h1 class="shop__title">Nine little <em>reasons.</em></h1>
<div class="shop__card" data-card aria-live="polite">
<span class="shop__card-name" data-name>Open the box</span>
<span class="shop__card-note" data-note>Click or tap the lid</span>
</div>
<button class="shop__button" type="button" data-order><span>Order the box</span></button>
</section>
<div class="stage" data-stage tabindex="0" role="button"
aria-label="A box of nine pralines. Click, tap or press Enter to open or close it; move over a praline, or use the arrow keys, to lift it and read its name.">
<div class="stage__shadow" data-shadow></div>
<div class="tilt" data-tilt>
<div class="spin" data-spin>
<!-- on the table, around the box -->
<div class="table-bits" aria-hidden="true">
<div class="crumb crumb--a"></div>
<div class="crumb crumb--b"></div>
<div class="crumb crumb--c"></div>
<div class="nib nib--a"></div>
<div class="nib nib--b"></div>
<div class="menu-card"><span>Nine pieces</span><i>made by hand this morning</i></div>
</div>
<!-- the box: base, walls with an outer and an inner side -->
<div class="box" aria-hidden="true">
<div class="box__floor"></div>
<div class="wall wall--front"><div class="wall__out"><span class="wall__label">Assortiment</span></div><div class="wall__in"></div></div>
<div class="wall wall--back"><div class="wall__out"></div><div class="wall__in"></div></div>
<div class="wall wall--left"><div class="wall__out"></div><div class="wall__in"></div></div>
<div class="wall wall--right"><div class="wall__out"></div><div class="wall__in"></div></div>
<div class="tray-pos">
<div class="tray">
<div class="tissue tissue--l"></div>
<div class="tissue tissue--r"></div>
<div class="tray__grid" data-grid></div>
</div>
</div>
<div class="lid-pos">
<div class="lid" data-lid>
<div class="lid__under"><span>Handmade in small batches</span></div>
<div class="lid__top">
<div class="foil" data-foil>
<svg viewBox="0 0 120 120" class="foil__mark">
<circle cx="60" cy="60" r="54" fill="none" stroke="currentColor" stroke-width="2"/>
<circle cx="60" cy="60" r="48" fill="none" stroke="currentColor" stroke-width="0.8" stroke-dasharray="2 3"/>
<path d="M60 30c-9 0-16 7-16 18 0 13 10 22 16 30 6-8 16-17 16-30 0-11-7-18-16-18z" fill="none" stroke="currentColor" stroke-width="2"/>
<path d="M60 34v40M52 46c3 3 13 3 16 0M50 56c4 3 16 3 20 0" fill="none" stroke="currentColor" stroke-width="1.4"/>
</svg>
<span class="foil__name" data-foil-name>Maison Noix</span>
<span class="foil__line">Pralines · Nine pieces</span>
</div>
<div class="ribbon ribbon--h" data-rib-h></div>
<div class="ribbon ribbon--v" data-rib-v></div>
</div>
<div class="skirt skirt--front"><div class="skirt__out"><div class="ribbon-drop"></div></div><div class="skirt__in"></div></div>
<div class="skirt skirt--back"><div class="skirt__out"><div class="ribbon-drop"></div></div><div class="skirt__in"></div></div>
<div class="skirt skirt--left"><div class="skirt__out"><div class="ribbon-drop ribbon-drop--side"></div></div><div class="skirt__in"></div></div>
<div class="skirt skirt--right"><div class="skirt__out"><div class="ribbon-drop ribbon-drop--side"></div></div><div class="skirt__in"></div></div>
<div class="bow" data-bow>
<svg viewBox="0 0 160 110" class="bow__svg">
<defs>
<linearGradient id="satin" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="var(--ribbon-light)"/>
<stop offset="0.45" stop-color="var(--ribbon)"/>
<stop offset="1" stop-color="var(--ribbon-dark)"/>
</linearGradient>
</defs>
<path class="bow__tail" d="M74 60 C66 78 58 92 44 106 L58 104 L64 110 C72 94 78 78 80 62z" fill="url(#satin)"/>
<path class="bow__tail" d="M86 60 C94 78 104 92 118 104 L104 104 L98 110 C90 94 84 78 80 62z" fill="url(#satin)"/>
<path d="M80 52 C60 22 26 14 14 30 C4 44 22 66 50 64 C62 63 72 60 80 56z" fill="url(#satin)"/>
<path d="M80 52 C100 22 134 14 146 30 C156 44 138 66 110 64 C98 63 88 60 80 56z" fill="url(#satin)"/>
<path d="M22 34 C34 26 58 30 74 50" fill="none" stroke="var(--ribbon-dark)" stroke-width="2" opacity="0.5"/>
<path d="M138 34 C126 26 102 30 86 50" fill="none" stroke="var(--ribbon-dark)" stroke-width="2" opacity="0.5"/>
<path d="M28 40 C40 34 54 38 66 50" fill="none" stroke="#fff" stroke-width="2.4" opacity="0.45" stroke-linecap="round"/>
<path d="M132 40 C120 34 106 38 94 50" fill="none" stroke="#fff" stroke-width="2.4" opacity="0.35" stroke-linecap="round"/>
<rect x="70" y="44" width="20" height="20" rx="7" fill="url(#satin)"/>
<path d="M74 48 C78 46 84 46 86 48" fill="none" stroke="#fff" stroke-width="1.6" opacity="0.5" stroke-linecap="round"/>
</svg>
</div>
</div>
</div>
</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.
63 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 «La scatola di praline da aprire» da Animorio e adattala al mio sitoTutto sta in un contenitore con transform-style: preserve-3d, inclinato con rotateX da un elemento e girato con rotateZ dal suo figlio (in quest’ordine, se no la scatola gira attorno allo schermo e non attorno a sé). Le pareti sono div ruotati di 90 gradi attorno al loro bordo; ognuna ha due facce a 2 pixel di distanza, verde fuori e crema dentro, così si vede quella giusta da ogni parte. Le misure sono variabili CSS calcolate al resize, quindi la scatola si ridisegna anche a metà animazione.
Il coperchio è un gruppo sollevato all’altezza delle pareti, con transform-origin sul bordo di dietro: aprirlo è una rotazione di rotateX fino a 112 gradi, con un piccolo sorpasso a 116 e un ritorno a 108 prima di fermarsi. Sopra c’è il piano esterno con la stampa e il nastro, sotto il piano interno girato di 180 gradi; tutti e due hanno backface-visibility: hidden, così si vede solo quello rivolto a chi guarda.
Ogni pralina è una pila di sei fette rotonde, sempre più strette verso l’alto, spostate con translateZ: inclinando la scatola si vede il fianco arrotondato. In cima c’è la faccia con la decorazione in SVG, disegnata con un generatore di numeri a seme fisso perché sia uguale a ogni visita, e un riflesso che si sposta al contrario del puntatore.
Il punto sotto il puntatore si trova con elementFromPoint, che rispetta le trasformazioni 3D. La pralina sale con un tween di z e rotationZ con back.out, l’ombra nel pirottino si allarga e schiarisce, e sette granelli di cacao partono dal centro in cerchio sul piano del vassoio e salgono spegnendosi.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
PRALINES | script.js | nove praline | Le nove praline, in ordine di lettura: nome, note sul cartoncino e decorazione (drizzle, swirl, nuts, hazelnut, gold, bean, dust, petal, orange). |
BRAND | script.js | Maison Noix | Il nome nella barra e in oro sul coperchio. |
TILT | script.js | 1 | Quanto si inclina la scatola verso il puntatore: 0 per niente, 2 tanto. |
OPEN_TIME | script.js | 0.9 | I secondi che il coperchio impiega ad aprirsi. |
LIFT | script.js | 1 | Quanto sale una pralina dal suo pirottino. |
SPIN | script.js | 1 | Quanto gira una pralina sollevata. |
PAUSE | script.js | 1.4 | I secondi fra una mossa e l’altra quando la scatola gioca da sola. |
--box, --gold, --ribbon, --dark, --milk… | style.css | verde petrolio, oro, rosa | I colori in :root: la scatola, l’oro, il nastro e i tre cioccolati delle praline. |
Per l’intestazione di una cioccolateria, una pasticceria, un negozio di regali o di dolci, la pagina di un prodotto da regalare o una scatola in abbonamento. È una vetrina: i prezzi e il pulsante per comprare vanno anche in testo normale.
Stessa scatola e stesse animazioni, misure adattate: il titolo e il cartoncino in alto, la scatola sotto, grande quanto lo spazio che resta. Un tocco apre e chiude, un tocco su una pralina la solleva, e trascinando il dito la scatola si inclina; il palco ha touch-action none.
Niente movimento: la scatola è ferma e già aperta, senza nastro; la pralina scelta si riconosce perché le altre si attenuano in dissolvenza, e il cartoncino cambia con una dissolvenza.
GSAP 3.15.0, Fraunces (font variabile) 5.3.0, Mona Sans (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 13 KB; le librerie: GSAP 28 KB.
Provata il 23 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.