
Parole che si fondono
Testo, Scroll, SVG
NuovaGratis
Scorri dentro l’anteprima
La pagina di un servizio postale inventato: in cima un foglio di carta per posta aerea si piega da solo in 3D in un aeroplanino. Scorrendo l’aeroplanino vola giù per la pagina su un percorso curvo, si piega nelle curve, sfiora i blocchi di testo che si scansano con un elastico, fa un giro della morte e lascia una scia tratteggiata rossa e blu; in fondo plana dentro una cassetta delle lettere che si chiude e alza la bandierina.
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>L'aeroplanino di carta</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/standard.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<header class="barra">
<a class="marchio" href="#" aria-label="Paperwing Post, home">
<svg class="marchio__segno" viewBox="0 0 40 40" aria-hidden="true">
<rect class="marchio__bordo" x="3" y="3" width="34" height="34" rx="3" />
<path class="marchio__ala" d="M9 21L31 11L22 30L19 23Z" />
<path class="marchio__piega" d="M19 23L31 11" />
</svg>
<span>Paperwing Post</span>
</a>
<nav class="voci" aria-label="Main">
<a class="voce" href="#rotta">Rates</a>
<a class="voce" href="#giro">Express</a>
<a class="voce" href="#arrivo">Track</a>
</nav>
</header>
<main>
<!-- the opening: the sheet of paper folds itself into a plane -->
<section class="apertura" data-apertura>
<div class="apertura__testo">
<p class="occhiello" data-entra>Airmail without the airport</p>
<h1 class="titolo">
<span class="riga"><span data-riga>Letters that</span></span>
<span class="riga"><span data-riga><em>fly themselves.</em></span></span>
</h1>
<p class="sotto" data-entra>Write it, fold it, let it go. Paperwing Post handles the wind, the weather and the last ten metres to the door.</p>
<div class="azioni" data-entra>
<a class="pillola" href="#arrivo"><span class="pillola__fondo"></span><span class="pillola__testo">Send a letter</span></a>
<p class="cenno" data-cenno><span>Scroll to launch</span>
<svg viewBox="0 0 24 32" aria-hidden="true"><path d="M12 4V27M5 20L12 27L19 20" /></svg>
</p>
</div>
</div>
<div class="apertura__foglio" data-posto-foglio aria-hidden="true"></div>
</section>
<!-- the route: the plane brushes past these blocks and they step aside -->
<section class="rotta" id="rotta" data-rotta>
<article class="blocco blocco--sx" data-blocco>
<div class="blocco__corpo" data-corpo>
<svg class="timbro" viewBox="0 0 80 80" aria-hidden="true" data-timbro>
<circle cx="40" cy="40" r="30" /><circle cx="40" cy="40" r="23" />
<text x="40" y="44">FOLDED</text>
</svg>
<h2 data-entra-blocco>Folded by hand</h2>
<p data-entra-blocco>Every letter leaves the counter as a paper plane: two creases, a sharp nose and a last look against the light.</p>
</div>
</article>
<article class="blocco blocco--dx" data-blocco>
<div class="blocco__corpo" data-corpo>
<svg class="timbro" viewBox="0 0 80 80" aria-hidden="true" data-timbro>
<circle cx="40" cy="40" r="30" /><circle cx="40" cy="40" r="23" />
<text x="40" y="44">ROUTED</text>
</svg>
<h2 data-entra-blocco>Routed by the wind</h2>
<p data-entra-blocco>Our planes read the breeze, not the map. Expect a few curves on the way: they still arrive before the bus.</p>
</div>
</article>
<article class="blocco blocco--sx" data-blocco>
<div class="blocco__corpo" data-corpo>
<svg class="timbro" viewBox="0 0 80 80" aria-hidden="true" data-timbro>
<circle cx="40" cy="40" r="30" /><circle cx="40" cy="40" r="23" />
<text x="40" y="44">WAXED</text>
</svg>
<h2 data-entra-blocco>Weatherproof wings</h2>
<p data-entra-blocco>Waxed paper, a rounded nose and a tail that forgives. Rain slows us down, but only a little.</p>
</div>
</article>
<article class="blocco blocco--dx" data-blocco>
<div class="blocco__corpo" data-corpo>
<svg class="timbro" viewBox="0 0 80 80" aria-hidden="true" data-timbro>
<circle cx="40" cy="40" r="30" /><circle cx="40" cy="40" r="23" />
<text x="40" y="44">TRACKED</text>
</svg>
<h2 data-entra-blocco>Tracked to the door</h2>
<p data-entra-blocco>Look up. If it is folded, striped and flying low over your street, it is probably yours.</p>
</div>
</article>
</section>
<!-- the express service: the plane loops the loop here -->
<section class="giro" id="giro" data-giro>
<div class="giro__testo" data-blocco>
<div class="blocco__corpo" data-corpo>
<p class="occhiello" data-entra-blocco>Express</p>
<h2 data-entra-blocco>One loop the loop, <em>on the house.</em></h2>
<p data-entra-blocco>Express letters take the scenic route for a second. Nobody has ever asked for a refund.</p>
</div>
</div>
<div class="giro__spazio" data-giro-spazio aria-hidden="true"></div>
</section>
<!-- the landing: a glide into the mailbox, the door shuts and the flag goes up -->
<section class="arrivo" id="arrivo" data-arrivo>
<div class="arrivo__testo" data-blocco>
<div class="blocco__corpo" data-corpo>
<p class="occhiello" data-entra-blocco>Last ten metres</p>
<h2 data-entra-blocco>Straight into <em>the box.</em></h2>
<p data-entra-blocco>No knocking, no missed deliveries. The plane glides in, the door shuts and the flag goes up.</p>
<svg class="bollo" data-bollo viewBox="0 0 150 80" aria-hidden="true">
<rect x="4" y="8" width="142" height="64" rx="8" />
<rect x="11" y="15" width="128" height="50" rx="5" />
<text x="75" y="48">DELIVERED</text>
</svg>
</div>
</div>
<div class="arrivo__cassetta" data-posto-cassetta aria-hidden="true"></div>
</section>
<footer class="piede">
<p><strong>Paperwing Post</strong> Letters by air, folded by hand.</p>
</footer>
</main>
<!-- the sky over the whole page: the trail, the plane and the mailbox are drawn here by the script -->
<svg class="cielo" data-cielo aria-hidden="true">
<defs>
<pattern id="ap-righe" width="22" height="22" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
<rect width="22" height="22" class="righe__carta" />
<rect width="6" height="22" class="righe__rosso" />
<rect x="11" width="6" height="22" class="righe__blu" />
</pattern>
<!-- the letter printed on the front of the sheet, in sheet units: 200 wide, 300 tall -->
<g id="ap-lettera">
<path class="lettera__bordo" fill-rule="evenodd" d="M-100 0H100V300H-100ZM-91 9V291H91V9Z" />
<rect class="lettera__etichetta" x="-80" y="24" width="62" height="20" rx="2" />
<text class="lettera__via" x="-49" y="38">BY AIR MAIL</text>
<g class="lettera__francobollo">
<rect x="44" y="20" width="38" height="46" />
<rect class="francobollo__dentro" x="49" y="25" width="28" height="36" />
<path class="francobollo__ala" d="M53 49L73 39L66 56L63 50Z" />
</g>
<text class="lettera__saluto" data-saluto x="-76" y="132">Dear Ada,</text>
<path class="lettera__righe" d="M-76 156c22-4 44 3 66-1s40 2 62-1M-76 176c26-3 50 3 76 0s34 2 52-1M-76 196c20-3 40 2 60 0s46 3 70-1M-76 216c30-3 58 2 86-1M-76 236c22-2 46 3 70-1s30 2 40 0" />
<text class="lettera__firma" x="70" y="272">June</text>
</g>
<!-- the back of the sheet: only the striped border -->
<g id="ap-retro"><path class="lettera__bordo" fill-rule="evenodd" d="M-100 0H100V300H-100ZM-91 9V291H91V9Z" /></g>
<clipPath id="ap-dentro" data-clip-dentro><rect data-clip-fuori x="0" y="0" width="0" height="0" /><path data-clip-bocca d="" /></clipPath>
<mask id="ap-maschera" maskUnits="userSpaceOnUse" x="0" y="0" width="100" height="100" data-maschera>
<path data-scia-maschera class="scia__maschera" d="" />
</mask>
</defs>
<g mask="url(#ap-maschera)" data-scia>
<path class="scia scia--rosso" data-scia-rosso d="" />
<path class="scia scia--blu" data-scia-blu d="" />
</g>
<g data-cassetta-dietro></g>
<g data-aereo-fuori><g data-aereo></g></g>
<g data-cassetta-davanti></g>
</svg>
<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="https://cdn.jsdelivr.net/npm/lenis@1.3.26/dist/lenis.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.
52 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 «L’aeroplanino di carta» da Animorio e adattala al mio sitoIl foglio è largo 200 unità e alto 300, con il muso in cima. Lo script piega sulla carta metà foglio: gli angoli verso il centro, i nuovi bordi verso il centro, e a ogni piega taglia i pezzi con la retta della piega e ribalta quelli che si spostano, ricordando la strada per tornare al foglio piatto e l’elenco delle pieghe che li muovono. Poi la piega dell’ala taglia tutto un’ultima volta. Escono sedici facce (otto per lato), ognuna disegnata nelle coordinate del foglio piatto.
Ogni piega è una rotazione intorno a una retta del foglio piatto (la formula di Rodrigues): angoli, secondi angoli, metà e ali. La posizione di una faccia è il prodotto delle rotazioni della sua catena, dalla più esterna alla più interna. L’aeroplanino è poi girato verso lo schermo: dal foglio dritto di fronte all’orientamento di volo con un’interpolazione sferica (quaternioni), e in volo con la direzione, il rollio e un poco di imbardata.
Vista di lato una faccia piana resta un parallelogramma, quindi basta un transform matrix(a b c d e f) su un gruppo SVG con il poligono nelle coordinate del foglio. Dentro c’è la lettera (un use ritagliato dal clipPath della faccia) se si vede il davanti, solo il bordo a righe se si vede il dietro, e un poligono scuro la cui opacità dipende da come la faccia prende la luce. L’ordine di disegno: prima i pannelli lontani, poi su ogni pannello la pila di carta dal lato nascosto a quello visto.
Il percorso è una curva morbida (Catmull-Rom trasformata in Bézier) che passa accanto a ogni blocco, misurato dalla pagina, poi un giro della morte e la planata nella cassetta. Lo script la campiona ogni 3 pixel e per ogni punto calcola lo scroll che lo porta al 60% dello schermo; nel giro lo scroll avanza in modo uniforme, così sullo schermo il giro è rotondo. Un solo tween con ScrollTrigger e scrub porta il valore dello scroll, e una ricerca binaria trova il punto.
La scia sono due tracciati tratteggiati (rosso e blu sfasati) visti attraverso una maschera con un solo trattino lungo quanto tutto il percorso: lo stroke-dashoffset la scopre fino alla coda. I blocchi misurano a ogni fotogramma la distanza dall’aeroplanino e si spostano con gsap.quickTo ed elastic.out. All’arrivo una timeline chiude lo sportello (scaleY da -0,52 a 1 con elastic.out), fa sobbalzare la cassetta, alza la bandierina con back.out e fa cadere il timbro; scorrendo indietro torna al contrario.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
FOLD_SPEED | script.js | 1 | Quanto in fretta il foglio si piega da solo: 0,5 piano, 2 di corsa. |
PLANE_SIZE | script.js | 1.2 | La grandezza dell’aeroplanino in volo. |
LOOP_SIZE | script.js | 1 | La grandezza del giro della morte. |
DODGE | script.js | 56 | Di quanti pixel si scansano i blocchi quando l’aeroplanino li sfiora. |
BANK | script.js | 0.6 | Quanto l’aeroplanino si inclina nelle curve: 0 resta dritto. |
DASH | script.js | 9 | La lunghezza di ogni trattino della scia, in pixel. |
SCRUB | script.js | 0.9 | Quanti secondi impiega l’aeroplanino a raggiungere lo scroll: 0 lo segue subito. |
--rosso | style.css | #d2412f | Il rosso della posta aerea: righe del foglio, scia, bandierina e timbri. |
Per una pagina che accompagna chi legge da un punto a un altro: un servizio di spedizioni o di consegne, una newsletter, un invito, un modulo di contatto che «parte», un’app di messaggi, una cartoleria, una pagina «come funziona» che finisce con la consegna.
La stessa animazione con misure adattate: il foglio si piega sotto il titolo, i blocchi sono più larghi e l’aeroplanino, più piccolo, vola nella striscia libera accanto a loro; il giro della morte è più piccolo, la cassetta sta sopra il testo finale, così la scia non passa sulle parole. I blocchi si scansano un po’ meno.
Niente piegatura, niente volo e niente scorrimento morbido: l’aeroplanino è già piegato in cima e compare in dissolvenza, la scia è già tutta disegnata fino alla cassetta, la cassetta è chiusa con la bandierina alzata e il timbro «Delivered» è già al suo posto. I testi compaiono solo in dissolvenza e i blocchi restano fermi.
GSAP 3.15.0, Lenis 1.3.26, Fraunces (font variabile) 5.3.0, Mona Sans (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 17 KB; le librerie: GSAP + ScrollTrigger 45 KB, Lenis 5,3 KB.
Provata il 11 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.