
Parole che si fondono
Testo, Scroll, SVG
NuovaGratis
Scorri dentro l’anteprima
Una tenda colorata sale sulla pagina; fra due coppie di virgolette una cornice nera sottile come una riga si apre e le spinge via, un coro sale nella cornice e le virgolette di chiusura scivolano al loro posto scoprendo la citazione.
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 quote marks that make room</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>
<!-- the quote mark, drawn once and used four times -->
<svg width="0" height="0" style="position:absolute" aria-hidden="true">
<symbol id="mark" viewBox="0 0 100 190">
<path d="M50 90a50 50 0 1 1 0 100a50 50 0 1 1 0-100ZM0 140C0 72 22 24 64 0l12 14C50 38 40 72 44 104Z" />
</symbol>
</svg>
<header class="top">
<p class="brand">Lanterna Philharmonic</p>
<p class="top__line">The chorus</p>
</header>
<main>
<!-- one tall section with a stage that stays on screen: the page before, and the coloured wipe that rises over it -->
<section class="quote" data-quote>
<div class="quote__stage">
<div class="before" data-before>
<h1 class="before__title"><span>Sing</span> <span>along</span></h1>
<p class="before__text">Every Thursday the chorus rehearses with the doors open. Bring your voice, or just come and listen.</p>
<p class="before__hint">Scroll</p>
</div>
<div class="wipe" data-wipe>
<div class="row" data-row>
<div class="marks" data-open aria-hidden="true">
<svg class="mark" viewBox="0 0 100 190"><use href="#mark" /></svg>
<svg class="mark" viewBox="0 0 100 190"><use href="#mark" /></svg>
</div>
<div class="cutout" aria-hidden="true">
<div class="cutout__frame" data-frame></div>
<div class="cutout__choir" data-choir>
<svg viewBox="0 0 1100 540" aria-hidden="true">
<g transform="translate(34 0)">
<!-- back row -->
<g class="singer">
<path d="M58 540c4-128 52-196 132-204 80 8 128 76 132 204Z" fill="#9ad6ff" />
<path d="M150 342l40 50 40-50Z" fill="#fff3da" />
<rect x="172" y="282" width="36" height="64" rx="14" fill="#8a5a3c" />
<ellipse cx="190" cy="232" rx="66" ry="74" fill="#a86c46" />
<path d="M120 236c-10-76 36-122 88-116 50 6 80 50 66 118-10-40-40-62-80-60-36 2-62 22-74 58Z" fill="#20160f" />
<path d="M160 238q10 8 20 0M202 238q10 8 20 0" fill="none" stroke="#20160f" stroke-width="5" stroke-linecap="round" />
<ellipse class="mouth" cx="191" cy="272" rx="11" ry="14" fill="#3b1a12" />
</g>
<g class="singer">
<path d="M318 540c4-136 54-208 138-216 84 8 134 80 138 216Z" fill="#ff5a36" />
<path d="M414 330l42 46 42-46Z" fill="#fff3da" />
<rect x="437" y="268" width="38" height="64" rx="14" fill="#e3a47c" />
<ellipse cx="456" cy="214" rx="68" ry="76" fill="#f2bb93" />
<circle cx="456" cy="118" r="34" fill="#6b3b1f" />
<path d="M386 222c-8-70 30-104 70-104s80 34 70 104c-8-34-34-52-70-52s-62 18-70 52Z" fill="#6b3b1f" />
<path d="M424 222q10 8 20 0M468 222q10 8 20 0" fill="none" stroke="#3a2012" stroke-width="5" stroke-linecap="round" />
<ellipse class="mouth" cx="457" cy="256" rx="12" ry="15" fill="#5a2418" />
</g>
<g class="singer">
<path d="M584 540c4-130 52-198 132-206 80 8 128 76 132 206Z" fill="#fff3da" />
<path d="M676 340l40 48 40-48Z" fill="#10132e" />
<rect x="698" y="280" width="36" height="64" rx="14" fill="#5e3a26" />
<ellipse cx="716" cy="228" rx="64" ry="74" fill="#704630" />
<path d="M646 244c-18-44-8-104 36-122 22-8 50-8 70 2 44 20 50 80 30 120 2-38-22-66-66-66s-70 28-70 66Z" fill="#161616" />
<circle cx="662" cy="160" r="22" fill="#161616" /><circle cx="702" cy="132" r="24" fill="#161616" /><circle cx="746" cy="140" r="24" fill="#161616" /><circle cx="776" cy="176" r="20" fill="#161616" />
<path d="M688 236q10 8 20 0M728 236q10 8 20 0" fill="none" stroke="#161616" stroke-width="5" stroke-linecap="round" />
<ellipse class="mouth" cx="717" cy="270" rx="11" ry="14" fill="#2e130c" />
</g>
<!-- front row -->
<g class="singer">
<path d="M196 540c4-104 44-160 110-166 66 6 106 62 110 166Z" fill="#ffb81c" />
<path d="M274 380l32 40 32-40Z" fill="#10132e" />
<rect x="290" y="330" width="32" height="56" rx="12" fill="#9c6340" />
<ellipse cx="306" cy="286" rx="58" ry="64" fill="#b87650" />
<path d="M246 296c-10-60 22-94 62-94 36 0 66 26 60 86-14-26-34-40-62-40-28 0-48 18-60 48Z" fill="#2a1a12" />
<path d="M278 292q9 7 18 0M316 292q9 7 18 0" fill="none" stroke="#2a1a12" stroke-width="5" stroke-linecap="round" />
<ellipse class="mouth" cx="307" cy="322" rx="10" ry="12" fill="#3b1a12" />
</g>
<g class="singer">
<path d="M466 540c4-108 46-166 114-172 68 6 110 64 114 172Z" fill="#10132e" />
<path d="M546 372l34 42 34-42Z" fill="#ffb81c" />
<rect x="562" y="322" width="36" height="58" rx="12" fill="#f0c6a2" />
<ellipse cx="580" cy="276" rx="60" ry="66" fill="#fbd6b4" />
<path d="M516 300c-18-72 18-110 64-110 50 0 82 40 64 110-4-40-26-66-64-66s-60 26-64 66Z" fill="#d9772e" />
<path d="M552 282q9 7 18 0M590 282q9 7 18 0" fill="none" stroke="#6b3a1c" stroke-width="5" stroke-linecap="round" />
<ellipse class="mouth" cx="581" cy="312" rx="10" ry="13" fill="#7a2c1c" />
</g>
<g class="singer">
<path d="M740 540c4-102 44-158 110-164 66 6 106 62 110 164Z" fill="#ff5a36" />
<path d="M818 382l32 40 32-40Z" fill="#fff3da" />
<rect x="834" y="330" width="32" height="56" rx="12" fill="#4f301f" />
<ellipse cx="850" cy="286" rx="58" ry="64" fill="#5f3a27" />
<path d="M790 280c0-48 26-76 60-76s60 28 60 76c-12-18-32-28-60-28s-48 10-60 28Z" fill="#101010" />
<path d="M822 292q9 7 18 0M860 292q9 7 18 0" fill="none" stroke="#101010" stroke-width="5" stroke-linecap="round" />
<ellipse class="mouth" cx="851" cy="322" rx="10" ry="12" fill="#2a0f0a" />
</g>
</g>
</svg>
</div>
</div>
<blockquote class="copy" data-copy>
<p>A city sounds best when everyone gets to sing along, even the ones who never learned the words.</p>
<footer>The Lanterna Chorus, rehearsal notes</footer>
</blockquote>
<div class="marks marks--close" data-close aria-hidden="true">
<svg class="mark" viewBox="0 0 100 190"><use href="#mark" /></svg>
<svg class="mark" viewBox="0 0 100 190"><use href="#mark" /></svg>
</div>
</div>
</div>
</div>
</section>
<section class="outro">
<p class="outro__text">Thursdays at seven, in the small hall.</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.
23 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 «Le virgolette che fanno posto» da Animorio e adattala al mio sitoLa sezione è alta 4,6 schermi e il suo palco resta fermo con position: sticky. Dentro ci sono la pagina di prima e la tenda, che la copre del tutto. Una sola timeline, legata allo scorrimento fino a quando l’85% della sezione arriva al fondo dello schermo, fa salire la tenda con clip-path da inset(100% 0 0 0) a inset(0) e intanto porta la pagina di sotto su del 12%.
Virgolette aperte, cornice, citazione e virgolette chiuse sono una griglia di quattro colonne. Le virgolette sono un solo simbolo SVG, un tondo con la coda, usato quattro volte; le chiuse sono le stesse girate di 180°. Tutto misura in larghezza dello schermo: virgolette e cornice sono alte 11vw, la cornice larga due volte e mezza.
Le distanze si prendono con la cornice larga, poi la si stringe al 10% e le due coppie di virgolette si mettono appoggiate a lei. A metà della tenda la cornice torna larga in 0,7: le aperte tornano al loro posto, le chiuse vanno subito dopo la cornice. Le chiuse portano un blocco ambra lungo quanto lo schermo, che resta sopra la citazione e la nasconde; alla fine scivolano al loro posto e la scoprono da sinistra a destra.
Un disegno SVG di sei cantanti, più largo della cornice, sale da sotto (yPercent da 100 a 0). La cornice lo taglia con un poligono: alla sua altezza taglia sui bordi, sopra lascia uscire le teste e anche un poco di lato. Le bocche si aprono e chiudono con GSAP, ognuna col suo passo, così seguono anche il rallentatore.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
START | script.js | 0.1 | Quanto è larga la cornice all’inizio, rispetto alla sua larghezza. |
OPEN_AT, OPEN | script.js | 0.5, 0.7 | Quando comincia ad aprirsi la cornice e quanto ci mette (la tenda dura 1). |
CHOIR_AT, REVEAL_AT | script.js | 0.82, 1.13 | Quando sale il coro e quando le virgolette di chiusura scoprono la citazione. |
DRIFT | script.js | -12 | Di quanto sale la pagina di prima mentre la tenda la copre, in percento della sua altezza. |
--bar, --quote-gap | style.css | 11vw, 0.9vw | L’altezza di virgolette e cornice, e lo spazio fra le due virgolette di ogni coppia. |
Per una citazione che deve pesare: la frase di un fondatore, una recensione, la voce di chi usa un prodotto, con una foto scontornata o un disegno al posto del coro.
Una colonna: virgolette aperte sopra, cornice larga quanto lo schermo, citazione, virgolette chiuse in fondo a destra. La cornice si apre dal centro, il coro sale e le virgolette e la citazione compaiono in dissolvenza.
Niente tenda e niente spinte: la pagina di prima e poi la citazione, già aperta, con il coro fermo.
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 5,9 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.