
La maschera che si apre
Transizioni, Scroll, SVG
NuovaGratis
Un manifesto ambra: due righe sul battito, una cornice scura fra loro e un violino che ne esce, tagliato solo sotto. Il primo gesto di scorrimento allarga la cornice fino a farne la notte della pagina, il violino vola al suo posto e si inclina.
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 frame that becomes the page</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/big-shoulders@5.3.0/standard.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/newsreader@5.3.0/standard.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/mona-sans@5.3.0/standard.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main>
<section class="hero" data-hero>
<header class="top" data-bar>
<p class="brand">Lanterna Philharmonic</p>
<p class="top__line">Season tickets</p>
</header>
<!-- for the keyboard (and the catalogue's autopilot): opens the night, or goes back to the poster -->
<button class="toggle" type="button" data-toggle data-autoclic>
<span class="toggle__text" data-text="Open the night">Open the night</span>
</button>
<!-- the stage: the poster's two lines, the frame's place between them, and over them the portal -->
<div class="stage" data-stage>
<h1 class="title">
<span class="line line--top" data-line><span class="line__in">The <br class="line__break">city’s</span></span>
<span class="line line--bottom" data-line><span class="line__in">New <br class="line__break">sound</span></span>
</h1>
<span class="slot" data-slot aria-hidden="true"></span>
<!-- everything in the portal is cut along the frame's lower edge, and nowhere else -->
<div class="portal" data-portal>
<div class="rect" data-rect></div>
<p class="welcome fit" data-welcome aria-hidden="true">
<span class="fit__box"><span class="fit__display" data-welcome-text>Opening <br class="line__break">night</span></span>
<span class="fit__ref">Opening <br class="line__break">night</span>
</p>
<!-- the violin's box is its place in the night; in the poster a transform takes it into the frame -->
<div class="violin" data-violin>
<div class="violin__tilt" data-tilt>
<div class="violin__drift" data-drift>
<svg class="violin__art" viewBox="0 0 600 1100" aria-hidden="true">
<defs>
<linearGradient id="varnish" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#f3a04a" />
<stop offset="0.45" stop-color="#d6661f" />
<stop offset="1" stop-color="#9a3d0e" />
</linearGradient>
<radialGradient id="glow" cx="0.5" cy="0.5" r="0.5">
<stop offset="0" stop-color="#ffcf8c" stop-opacity="0.8" />
<stop offset="1" stop-color="#ffcf8c" stop-opacity="0" />
</radialGradient>
<radialGradient id="shade" cx="0.5" cy="0.5" r="0.5">
<stop offset="0" stop-color="#5a1f04" stop-opacity="0.55" />
<stop offset="1" stop-color="#5a1f04" stop-opacity="0" />
</radialGradient>
<linearGradient id="head" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" stop-color="#f09b48" />
<stop offset="1" stop-color="#a8440f" />
</linearGradient>
<clipPath id="outline"><path d="M300 420 C372 419 440 446 441 520 C442 568 424 592 412 604 C420 610 430 616 434 624 C414 624 396 636 391 656 C387 672 390 692 398 704 C408 712 424 714 436 716 C432 724 426 730 420 736 C458 760 478 808 478 872 C478 962 408 1018 300 1020 C192 1018 122 962 122 872 C122 808 142 760 180 736 C174 730 168 724 164 716 C176 714 192 712 202 704 C210 692 213 672 209 656 C204 636 186 624 166 624 C170 616 180 610 188 604 C176 592 158 568 159 520 C160 446 228 419 300 420 Z" /></clipPath>
</defs>
<!-- the bow, behind the violin: stick, hair, tip, frog and button -->
<g transform="translate(46 70) rotate(63.03)">
<path d="M16 15 L1000 22 L1000 28 L22 21 Z" fill="#f5ecd8" />
<path d="M0 -3 L1000 -6 L1000 6 L0 3 Z" fill="#7a3c16" />
<path d="M-7 -6 C -3 -13 13 -13 21 -4 L 24 27 L 11 27 C 4 20 -5 8 -7 -6 Z" fill="#f5ecd8" />
<path d="M994 -5 L1070 -5 L1080 26 L1060 44 L1002 44 Z" fill="#1c1512" />
<circle cx="1038" cy="19" r="7" fill="#dfe9f5" />
<path d="M1080 -6 L1128 -6 L1128 6 L1080 6 Z" fill="#1c1512" />
<path d="M1092 -7 L1102 -7 L1102 7 L1092 7 Z" fill="#d9d2c4" />
</g>
<!-- pegs, pegbox and scroll -->
<g fill="#1c1512">
<rect x="222" y="160" width="60" height="10" rx="5" /><ellipse cx="220" cy="165" rx="15" ry="11" />
<rect x="222" y="214" width="60" height="10" rx="5" /><ellipse cx="220" cy="219" rx="15" ry="11" />
<rect x="318" y="186" width="60" height="10" rx="5" /><ellipse cx="380" cy="191" rx="15" ry="11" />
<rect x="318" y="240" width="60" height="10" rx="5" /><ellipse cx="380" cy="245" rx="15" ry="11" />
</g>
<path d="M275 130 L325 130 L322 264 L278 264 Z" fill="url(#head)" />
<path d="M287 142 L313 142 L311 258 L289 258 Z" fill="#3b1606" />
<circle cx="300" cy="96" r="38" fill="url(#head)" />
<circle cx="300" cy="96" r="38" fill="none" stroke="#7a2f0b" stroke-width="3" />
<path d="M300.0 93.0 L300.5 92.7 L301.2 92.4 L301.9 92.3 L302.7 92.4 L303.6 92.6 L304.4 93.0 L305.2 93.6 L305.8 94.4 L306.4 95.3 L306.8 96.4 L307.1 97.5 L307.1 98.8 L306.9 100.1 L306.4 101.4 L305.7 102.7 L304.7 103.8 L303.5 104.8 L302.2 105.7 L300.6 106.3 L298.9 106.6 L297.1 106.7 L295.2 106.4 L293.4 105.8 L291.6 104.9 L290.0 103.7 L288.6 102.1 L287.4 100.3 L286.5 98.3 L285.9 96.1 L285.7 93.7 L285.9 91.3 L286.5 88.9 L287.5 86.6 L288.9 84.4 L290.7 82.5 L292.8 80.8 L295.3 79.5 L298.0 78.5 L300.8 78.1 L303.8 78.1 L306.8 78.6 L309.7 79.6 L312.5 81.1 L315.0 83.0 L317.3 85.4 L319.1 88.2 L320.5 91.3 L321.4 94.7 L321.7 98.2 L321.4 101.7 L320.6 105.3 L319.1 108.7 L317.1 111.9 L314.5 114.7 L311.5 117.2 L308.0 119.1 L304.3 120.5 L300.3 121.2 L296.1 121.3 L292.0 120.7" fill="none" stroke="#6e2a08" stroke-width="5" stroke-linecap="round" />
<path d="M276 72 C 284 62 296 58 306 60" fill="none" stroke="#ffd29a" stroke-width="3" stroke-linecap="round" opacity="0.7" />
<!-- neck under the fingerboard -->
<path d="M280 258 L320 258 L324 440 L276 440 Z" fill="#b24b14" />
<!-- body: a darker rim, the top, grain, light and shade, the purfling -->
<path d="M300 420 C372 419 440 446 441 520 C442 568 424 592 412 604 C420 610 430 616 434 624 C414 624 396 636 391 656 C387 672 390 692 398 704 C408 712 424 714 436 716 C432 724 426 730 420 736 C458 760 478 808 478 872 C478 962 408 1018 300 1020 C192 1018 122 962 122 872 C122 808 142 760 180 736 C174 730 168 724 164 716 C176 714 192 712 202 704 C210 692 213 672 209 656 C204 636 186 624 166 624 C170 616 180 610 188 604 C176 592 158 568 159 520 C160 446 228 419 300 420 Z" fill="#7a2f0b" stroke="#6e2a08" stroke-width="14" stroke-linejoin="round" />
<path d="M300 420 C372 419 440 446 441 520 C442 568 424 592 412 604 C420 610 430 616 434 624 C414 624 396 636 391 656 C387 672 390 692 398 704 C408 712 424 714 436 716 C432 724 426 730 420 736 C458 760 478 808 478 872 C478 962 408 1018 300 1020 C192 1018 122 962 122 872 C122 808 142 760 180 736 C174 730 168 724 164 716 C176 714 192 712 202 704 C210 692 213 672 209 656 C204 636 186 624 166 624 C170 616 180 610 188 604 C176 592 158 568 159 520 C160 446 228 419 300 420 Z" fill="url(#varnish)" />
<g clip-path="url(#outline)">
<path d="M140 400 C140.0 600 140.0 800 140.0 1040 M156 400 C161.9499888627148 600 150.0500111372852 800 158.9749944313574 1040 M172 400 C170.46675338783902 600 173.53324661216098 800 171.2333766939195 1040 M188 400 C182.44511190603362 600 193.55488809396638 800 185.2225559530168 1040 M204 400 C206.96468010683165 600 201.03531989316835 800 205.4823400534158 1040 M220 400 C224.79092267574094 600 215.20907732425906 800 222.39546133787047 1040 M236 400 C231.80075187443876 600 240.19924812556124 800 233.90037593721937 1040 M252 400 C248.2911773265778 600 255.7088226734222 800 250.1455886632889 1040 M268 400 C273.15497088913895 600 262.84502911086105 800 270.5774854445695 1040 M284 400 C286.3804434387837 600 281.6195565612163 800 285.19022171939184 1040 M300 400 C294.2316150487227 600 305.7683849512773 800 297.11580752436134 1040 M316 400 C315.1060058451148 600 316.8939941548852 800 315.5530029225574 1040 M332 400 C337.998757400856 600 326.001242599144 800 334.999378700428 1040 M348 400 C347.34818042745553 600 348.65181957254447 800 347.67409021372777 1040 M364 400 C358.1692093255368 600 369.8307906744632 800 361.0846046627684 1040 M380 400 C382.15435012413303 600 377.84564987586697 800 381.0771750620665 1040 M396 400 C401.27563836990436 600 390.72436163009564 800 398.63781918495215 1040 M412 400 C408.48617596015424 600 415.51382403984576 800 410.2430879800771 1040 M428 400 C423.6298353930104 600 432.3701646069896 800 425.81491769650523 1040 M444 400 C448.6399673373973 600 439.3600326626027 800 446.3199836686987 1040 M460 400 C463.17449611672015 600 456.82550388327985 800 461.58724805836005 1040 " fill="none" stroke="#ffd29a" stroke-width="1.6" opacity="0.18" />
<ellipse cx="228" cy="512" rx="130" ry="120" fill="url(#glow)" />
<ellipse cx="220" cy="860" rx="160" ry="150" fill="url(#glow)" />
<ellipse cx="470" cy="800" rx="90" ry="260" fill="url(#shade)" />
<ellipse cx="440" cy="520" rx="60" ry="110" fill="url(#shade)" />
</g>
<path d="M300 420 C372 419 440 446 441 520 C442 568 424 592 412 604 C420 610 430 616 434 624 C414 624 396 636 391 656 C387 672 390 692 398 704 C408 712 424 714 436 716 C432 724 426 730 420 736 C458 760 478 808 478 872 C478 962 408 1018 300 1020 C192 1018 122 962 122 872 C122 808 142 760 180 736 C174 730 168 724 164 716 C176 714 192 712 202 704 C210 692 213 672 209 656 C204 636 186 624 166 624 C170 616 180 610 188 604 C176 592 158 568 159 520 C160 446 228 419 300 420 Z" fill="none" stroke="#4a1a05" stroke-width="2.5" transform="translate(300 720) scale(0.955) translate(-300 -720)" />
<!-- f-holes, with their nicks -->
<g fill="none" stroke="#2b1206" stroke-width="6.5" stroke-linecap="round">
<path d="M227 650 C 247 670 245 702 233 730 C 221 758 215 790 233 816" />
<path d="M373 650 C 353 670 355 702 367 730 C 379 758 385 790 367 816" />
<path d="M226 734 L 242 740 M 374 734 L 358 740" stroke-width="4" />
</g>
<g fill="#2b1206">
<circle cx="225" cy="648" r="8.5" /><circle cx="235" cy="818" r="9.5" />
<circle cx="375" cy="648" r="8.5" /><circle cx="365" cy="818" r="9.5" />
</g>
<!-- fingerboard and nut -->
<path d="M278 256 L322 256 L336 660 C 328 670 272 670 264 660 Z" fill="#1c1512" />
<path d="M287 266 L296 266 L291 650 L280 650 Z" fill="#3a2d27" opacity="0.8" />
<rect x="276" y="252" width="48" height="8" rx="3" fill="#efe3c8" />
<!-- chinrest, tailpiece, saddle, end button -->
<path d="M236 990 C 198 1002 166 986 168 962 C 170 942 200 934 236 944 C 268 952 274 980 236 990 Z" fill="#1c1512" />
<path d="M200 956 C 212 948 234 948 250 956" fill="none" stroke="#4a3b33" stroke-width="4" stroke-linecap="round" />
<path d="M264 872 L336 872 C 336 930 326 986 314 1004 L286 1004 C 274 986 264 930 264 872 Z" fill="#1c1512" />
<path d="M272 880 L284 880 L292 994 L286 994 Z" fill="#3a2d27" opacity="0.8" />
<circle cx="324" cy="888" r="6" fill="#cfc8ba" />
<rect x="284" y="1010" width="32" height="8" rx="2" fill="#1c1512" />
<circle cx="300" cy="1027" r="9" fill="#1c1512" />
<!-- bridge -->
<path d="M246 782 L354 782 L348 770 C 342 756 332 748 300 746 C 268 748 258 756 252 770 Z" fill="#ecc98f" />
<path d="M284 767 C 289 760 311 760 316 767 C 310 773 290 773 284 767 Z" fill="#b98e55" />
<path d="M262 776 C 268 770 276 770 280 776 M 320 776 C 324 770 332 770 338 776" fill="none" stroke="#b98e55" stroke-width="3" />
<rect x="242" y="780" width="116" height="6" rx="2" fill="#d7ad6c" />
<!-- strings -->
<g stroke="#f3ead8" stroke-width="2.2" data-strings>
<line x1="291" y1="256" x2="282" y2="874" />
<line x1="297" y1="256" x2="294" y2="874" />
<line x1="303" y1="256" x2="306" y2="874" />
<line x1="309" y1="256" x2="318" y2="874" />
</g>
</svg>
</div>
</div>
</div>
</div>
<div class="fade" data-fade></div>
<div class="intro" data-intro>
<h2 class="visually-hidden">Opening night</h2>
<p>The Lanterna Philharmonic opens its first season in the new hall by the harbour, with the doors wide open and every seat under twenty euros.</p>
<p>Scroll on for the programme, or go back to the top and scroll up to see the poster again.</p>
</div>
<p class="hint" data-hint>
Scroll to open
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 4v15M6 13l6 6 6-6" /></svg>
</p>
</div>
</section>
<section class="programme">
<h2 class="programme__title">This season</h2>
<ul class="programme__list">
<li><span class="programme__date">Fri 2 October</span><span class="programme__name">Opening night</span><span class="programme__place">Harbour Hall</span></li>
<li><span class="programme__date">Fri 16 October</span><span class="programme__name">Ravel by the water</span><span class="programme__place">Harbour Hall</span></li>
<li><span class="programme__date">Sun 25 October</span><span class="programme__name">Brass on the morning ferries</span><span class="programme__place">Pier Four</span></li>
<li><span class="programme__date">Fri 6 November</span><span class="programme__name">Mahler in the shipyard</span><span class="programme__place">Old Shipyard</span></li>
</ul>
<p class="programme__end">Doors open at seven.</p>
</section>
</main>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/ScrollTrigger.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.
45 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 cornice che diventa la pagina» da Animorio e adattala al mio sitoLe due righe e il posto della cornice sono una griglia a tre righe dentro un contenitore, così il titolo si dimensiona anche sull’altezza (36cqh). Le righe compaiono a 0,63 e 1,26 secondi con un piccolo colpo di scala; a 1,89 la cornice si apre da scaleX 0 in 1,76 secondi expo.out e il violino sale dal 55% della sua altezza più in basso in 1,76 quint.out.
Cornice, violino e titolo della notte stanno in un livello grande quanto il palco, fra le due righe: la riga di sopra passa sotto, quella di sotto sopra. Il livello è tagliato con clip-path inset(0 0 X 0), dove X è la distanza fra il bordo basso della cornice e il fondo: il violino può uscire sopra e ai lati, mai sotto la cornice.
La cornice cresce dal suo centro fino a coprire il palco più 8 px (scala = due volte la distanza dal bordo più lontano, diviso la sua misura) in 1,2 secondi quint.inOut, e il taglio scende con lo stesso passo del suo bordo basso. Il violino, che nel CSS ha già il suo posto e la sua misura della notte, torna a scala 1 da quella del manifesto e si inclina di 20° in 1,4 secondi; per questo resta nitido. A 0,77 sale «Opening night», adattato alla larghezza col solo CSS, da 180 px più in basso e scala 0,8 in 1 secondo expo.out.
Finché c’è il manifesto l’html ha overflow: hidden e la rotella, il dito e i tasti non fanno scorrere (ascoltatori non passivi con preventDefault): il primo gesto verso il basso fa partire il volo. Dopo, la pagina scorre normale e una timeline legata allo scorrimento porta il testo su di 100 px e il violino di 10° in più. In cima, un gesto verso l’alto riavvolge il volo e ferma di nuovo la pagina.
Titolo della notte e testo hanno una timeline loro, che parte durante il volo e al ritorno va 2,2 volte più veloce: se fossero rimaste nel volo, riavvolgendolo dalla fine per quasi un secondo si sarebbe vista solo la coda delle scritte, quasi ferma.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
BEAT, OPEN | script.js | 0.63, 1.76 | I secondi fra una riga e l’altra (e prima della cornice), e quanto ci mettono cornice e violino ad aprirsi e salire. |
SIZE, SINK | script.js | 0.56, 0.75 | Quanto è largo il violino nel manifesto, rispetto alla cornice, e quanto scende il suo piede sotto il bordo basso, rispetto alla sua altezza. |
GROW, FLY, TILT | script.js | 1.2, 1.4, 20 | I secondi della cornice che copre la pagina e del violino che vola, e i gradi di cui si inclina. |
WELCOME_AT | script.js | 0.77 | Quando sale il titolo della notte, durante il volo. |
SWAY, RING | script.js | 1.5, 3 | I gradi di cui il violino ondeggia sempre, e di quanto vibrano le corde quando atterra. |
Per una prima pagina che si presenta come un manifesto e poi si apre: il lancio di una stagione, un nuovo direttore, un prodotto che esce da una scatola, un evento con una sola immagine forte.
Le righe vanno a capo e stanno sopra e sotto la cornice; lo stesso gesto, col dito, apre la notte. Nella notte il violino sta al centro e il testo in fondo, su una sfumatura scura.
Il manifesto è già disegnato e il violino è fermo; il primo gesto passa alla notte con un taglio netto, e in cima un gesto verso l’alto torna al manifesto allo stesso modo.
GSAP 3.15.0, ScrollTrigger (GSAP) 3.15.0, Big Shoulders (font variabile) 5.3.0, Newsreader (font variabile) 5.3.0, Mona Sans (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 12 KB; le librerie: GSAP + ScrollTrigger 45 KB.
Provata il 29 settembre 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.