
Il pulsante a strati
Pulsanti, Hover, Fisica
Gratis
Il piè di pagina di un rifugio di montagna, blu notte, col nome scritto in grandi lettere rosse lungo il fondo: la neve cade sul piè di pagina e si posa sul bordo alto di ogni lettera, del campo dell'email e dei pulsanti tondi, con la forma che prende la neve vera. Una mano passata sulle lettere spazza via la neve, che vola in polvere, e i cappucci si riempiono di nuovo; puntando un link la neve si posa anche sulle sue lettere, e l'iscrizione al bollettino porta una nevicata fresca.
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 snowy footer</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/archivo@5.3.0/wdth.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the footer of a mountain hut: its name stands in giant red letters along the bottom, and snow falls over the
footer and settles on them, in caps that keep their angle of repose. A hand sweeps a letter clean and the
powder flies, the caps fill up again; signing up to the snow report brings a fresh fall -->
<footer class="ft" data-footer data-autoclic>
<canvas class="ft__snow" aria-hidden="true" data-snow></canvas>
<div class="ft__top">
<form class="ft__form" action="#" novalidate aria-labelledby="ft-news" data-form>
<h2 class="ft__title" id="ft-news">The Monday snow report</h2>
<p class="ft__lede">Snow depth, open routes and free bunks, every Monday.</p>
<label class="sr" for="ft-email">Email address</label>
<div class="ft__field" data-field>
<input class="ft__input" id="ft-email" name="email" type="email" inputmode="email" autocomplete="email" autocapitalize="off" spellcheck="false" enterkeyhint="send" placeholder="you@example.com" aria-describedby="ft-note" aria-invalid="false" data-input>
<button class="ft__send" type="submit" data-send>
<span class="ft__send-bg"></span>
<span class="ft__send-label" data-send-label>Sign up</span>
<svg class="ft__spin" viewBox="0 0 24 24" aria-hidden="true" data-spin><circle cx="12" cy="12" r="8"/></svg>
<svg class="ft__done" viewBox="0 0 24 24" aria-hidden="true" data-done><path d="M6.4 12.6l3.7 3.7 7.6-8.6"/></svg>
</button>
</div>
<p class="ft__note" id="ft-note" aria-live="polite" data-note><span class="ft__line">One email a week. Leave whenever you like.</span></p>
</form>
<nav class="ft__cols" aria-label="Footer">
<div class="ft__col">
<h2 class="ft__head"><span class="ft__head-text">Stay</span><button class="ft__toggle" type="button" aria-expanded="false" aria-controls="ft-stay" data-toggle>Stay<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M3.5 6l4.5 4.5L12.5 6"/></svg></button></h2>
<ul class="ft__list" id="ft-stay" data-list>
<li><a class="ft__link" href="#" data-link>Book a bunk</a></li>
<li><a class="ft__link" href="#" data-link>Prices</a></li>
<li><a class="ft__link" href="#" data-link>Half board</a></li>
<li><a class="ft__link" href="#" data-link>Groups</a></li>
</ul>
</div>
<div class="ft__col">
<h2 class="ft__head"><span class="ft__head-text">Routes</span><button class="ft__toggle" type="button" aria-expanded="false" aria-controls="ft-routes" data-toggle>Routes<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M3.5 6l4.5 4.5L12.5 6"/></svg></button></h2>
<ul class="ft__list" id="ft-routes" data-list>
<li><a class="ft__link" href="#" data-link>Hut to hut</a></li>
<li><a class="ft__link" href="#" data-link>Ski tours</a></li>
<li><a class="ft__link" href="#" data-link>Conditions</a></li>
<li><a class="ft__link" href="#" data-link>Guides</a></li>
</ul>
</div>
<div class="ft__col">
<h2 class="ft__head"><span class="ft__head-text">The hut</span><button class="ft__toggle" type="button" aria-expanded="false" aria-controls="ft-hut" data-toggle>The hut<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M3.5 6l4.5 4.5L12.5 6"/></svg></button></h2>
<ul class="ft__list" id="ft-hut" data-list>
<li><a class="ft__link" href="#" data-link>Our story</a></li>
<li><a class="ft__link" href="#" data-link>Getting here</a></li>
<li><a class="ft__link" href="#" data-link>Kit list</a></li>
<li><a class="ft__link" href="#" data-link>Contact</a></li>
</ul>
</div>
</nav>
</div>
<div class="ft__base">
<p class="ft__brand">
<svg class="ft__mark" viewBox="0 0 32 32" aria-hidden="true"><path class="m-hill" d="M1.5 28L11.2 11.6l4.4 7.1 4.6-7.8L30.5 28"/><path class="m-hut" d="M9.2 28v-8.6l6.8-5.8 6.8 5.8V28z"/><path class="m-door" d="M14.3 28v-4.4h3.4V28z"/><path class="m-snow" d="M7.4 19.8l8.6-7.6 8.6 7.6-1.4 1.1L16 15l-7.2 5.9z"/></svg>
<span class="ft__name">Rimefell Hut</span>
<span class="ft__copy"><svg viewBox="0 0 12 12" aria-hidden="true"><circle cx="6" cy="6" r="5.1"/><path d="M7.9 4.5a2.3 2.3 0 1 0 0 3"/></svg><span class="sr">Copyright</span> 2026 Rimefell Hut Trust</span>
</p>
<div class="ft__social">
<a class="ft__icon" href="#" data-icon><span class="sr">Hut webcam</span><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="7" width="13" height="10.5" rx="2.4"/><circle cx="9.5" cy="12.25" r="2.6"/><path d="M16 10.6l4.6-2.4v8.6L16 14.4"/></svg></a>
<a class="ft__icon" href="#" data-icon><span class="sr">Trip journal</span><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 7.2c-2.4-1.6-5.2-2-8-1.4v12.4c2.8-.6 5.6-.2 8 1.4 2.4-1.6 5.2-2 8-1.4V5.8c-2.8-.6-5.6-.2-8 1.4z"/><path d="M12 7.2v12.4"/></svg></a>
<a class="ft__icon" href="#" data-icon><span class="sr">Route maps</span><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M3.5 6.4l5.4-2 6.2 2 5.4-2v13.2l-5.4 2-6.2-2-5.4 2z"/><path d="M8.9 4.4v13.2M15.1 6.4v13.2"/></svg></a>
</div>
<nav class="ft__legal" aria-label="Legal">
<a class="ft__link ft__link--small" href="#" data-link>Privacy</a>
<a class="ft__link ft__link--small" href="#" data-link>Terms</a>
<a class="ft__link ft__link--small" href="#" data-link>Cookies</a>
</nav>
</div>
<!-- the hut's name, drawn: each letter is a path, and the snow settles on its top edge -->
<svg class="ft__giant" viewBox="0 -2 1077.5 102" aria-hidden="true" data-giant>
<defs>
<clipPath id="ft-line1" clipPathUnits="userSpaceOnUse"><rect x="-20" y="-60" width="582" height="160"/></clipPath>
<clipPath id="ft-line2" clipPathUnits="userSpaceOnUse"><rect x="562" y="-60" width="536" height="160"/></clipPath>
</defs>
<g clip-path="url(#ft-line1)">
<path data-letter d="M0 100H37V66.4H87.7Q109 66.4 121.4 58.5Q133.7 50.5 133.7 33.2Q133.7 15.8 122 7.9Q110.3 0 90.3 0H0ZM95.2 100H137.1L91.6 53H53.8ZM37 44.1V23.8H79.8Q88.6 23.8 92.6 26.2Q96.7 28.7 96.7 34Q96.7 39.2 92.7 41.6Q88.8 44.1 79.8 44.1Z"/>
<path data-letter d="M162.6 100H199.2V0H162.6Z"/>
<path data-letter d="M229 100H265.6V24.5H265.9L295.9 98.3H340.6L370.6 24.5H370.8V100H407.5V0H347.4L318.3 73.2H318.1L289.1 0H229Z"/>
<path data-letter d="M431.8 100H552.8V76.2H468.8V60.7H545.6V38.6H468.8V23.8H552.8V0H431.8Z"/>
</g>
<g data-line2>
<g clip-path="url(#ft-line2)">
<path data-letter d="M572.4 100H609.5V67.2H677.6V45.2H609.5V23.8H684.8V0H572.4Z"/>
<path data-letter d="M703.2 100H824.2V76.2H740.2V60.7H817V38.6H740.2V23.8H824.2V0H703.2Z"/>
<path data-letter d="M846.2 100H952.1V76.2H883.2V0H846.2Z"/>
<path data-letter d="M971.6 100H1077.5V76.2H1008.6V0H971.6Z"/>
</g>
</g>
</svg>
</footer>
</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.
56 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 piè di pagina con la neve» da Animorio e adattala al mio sitoOgni lettera del nome è un tracciato SVG. Per sapere dove si posa la neve la lettera si disegna una volta su un canvas nascosto, a grandezza doppia, e per ogni colonna di pixel si cerca il primo pixel pieno dall'alto: quello è il suo bordo. Il campo dell'email (una pillola) e i pulsanti tondi hanno il bordo calcolato col cerchio; la parola di un link puntato si disegna col suo carattere, sulla linea di base presa da fontBoundingBoxAscent e fontBoundingBoxDescent.
Per ogni colonna si calcola il massimo di neve, come la neve vera: dove il bordo è più ripido dell'angolo di riposo (STEEP pixel in su per pixel di lato) non resta niente, su un pendio dolce ne resta meno quanto più è ripido, su uno spigolo resta un labbro sottile e da lì il cappuccio sale con una spalla a quarto di cerchio fino alla profondità piena (DEPTH, mai tanto da arrivare alla riga sopra), e contro un muro che sale accanto la neve si ammucchia. Due passate, avanti e indietro, tengono la superficie mai più ripida di STEEP; i tratti larghi meno di sette pixel non trattengono niente.
I fiocchi sono su tre profondità con la loro misura, velocità e trasparenza; scendono, ondeggiano e vanno col vento (WIND, che cresce e cala piano). Quelli dei due piani davanti che attraversano la superficie della neve si posano lì e la ingrossano a campana su nove colonne; intanto ogni cappuccio cresce verso il suo massimo in REFILL secondi, più in fretta in una nevicata fitta. A ogni passo la neve si pareggia lungo il bordo, misurata contro il suo massimo, così non spuntano punte e le pareti di un solco si ammorbidiscono. Quando la nevicata si calma i fiocchi in più svaniscono dove sono, sparsi.
Fra due posizioni del puntatore la mano si muove a piccoli passi, così una passata veloce non salta niente. Dentro la sua larghezza (BRUSH) la neve si toglie fino all'altezza delle dita, e verso i lati della mano ne resta di più, con un bordo morbido; quello che si toglie diventa polvere lanciata nella direzione del gesto, che resta nell'aria e svanisce, e qualche zolla che cade con la gravità e si posa sul bordo più in basso. Un clic su una lettera le toglie tutta la neve, mentre GSAP la fa cedere e tornare con un elastic.out.
Ogni tratto di neve è una forma sola: la superficie con curve quadratiche, un labbro che sporge dallo spigolo con una curva di Bézier, e il fondo un pixel dentro la cosa su cui sta, con un gradiente dal bianco all'azzurro dell'ombra. Il canvas sta dietro a tutto il piè di pagina: le lettere, il campo e i pulsanti coprono il piede della neve, così niente è mai coperto. A ogni fotogramma la posizione di ogni bordo si rilegge dalla sua scatola, quindi la neve segue la lettera che sale o cede, il campo che trema, il pulsante che salta e la colonna che si apre al telefono.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
SNOWFALL | script.js | 1 | Quanto nevica: a 0 i fiocchi si fermano, i cappucci ci sono già e una lettera spazzata resta pulita. |
WIND | script.js | 16 | Quanto il vento spinge i fiocchi di lato, in pixel al secondo (sotto zero soffia verso sinistra). |
DEPTH | script.js | 16 | Quanto è alta al massimo la neve sulle lettere grandi, in pixel (meno al telefono, e mai fino alla riga sopra). |
STEEP | script.js | 1.6 | Quanto può stare ripida la neve, in pixel in su per ogni pixel di lato: di più fa cappucci più squadrati, di meno cupole a punta. |
REFILL | script.js | 6 | Più o meno quanti secondi ci mette una lettera spazzata a riempirsi di nuovo. |
BRUSH | script.js | 26 | Quanto è larga la mano che spazza via la neve, in pixel. |
POWDER | script.js | 1 | Quanta polvere vola quando la neve viene tolta: a 0 la neve sparisce e basta. |
WAIT | script.js | 1.1 | Quanto dura l'iscrizione nella demo, in secondi. |
Per il piè di pagina di un rifugio, di una scuola di sci, di un negozio di sport invernali, di una località di montagna, di un mercatino o di un festival d'inverno: ovunque il fondo della pagina possa avere la sua stagione, con un nome grande su cui la neve abbia dove posarsi.
Il piè di pagina prende la larghezza dello schermo: la newsletter va sopra e le tre colonne si chiudono dietro i loro titoli, righe alte 52 pixel con la freccia che gira: un tocco apre la colonna, che si allunga con i link (righe da 44 pixel) che scendono uno dopo l'altro. Il marchio, i pulsanti tondi e i link legali vanno a capo. Il nome si divide in due righe, RIME e FELL, così le lettere restano grandi, e ogni riga ha la sua neve, un po' meno alta. Un dito trascinato di lato sulle lettere spazza la neve (su e giù scorre la pagina), un tocco su una lettera la scrolla tutta, e toccando un link la neve si posa sulle sue lettere per un momento.
Non cade niente: i cappucci sono già al loro posto, fermi, e il canvas si disegna solo quando qualcosa cambia. Il nome non sale, compare in dissolvenza insieme alla sua neve; la mano non spazza e un clic non scrolla le lettere. Puntando un link la parola diventa rossa e la neve compare sulle sue lettere in dissolvenza, senza che la parola si abbassi; i pulsanti tondi non saltano, il campo sbagliato non trema, il pulsante non si stringe e l'arco sta fermo, e all'iscrizione non arriva la nevicata. Le colonne al telefono si aprono senza scorrere, coi link in dissolvenza.
GSAP 3.15.0, Archivo (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 21 KB; le librerie: GSAP 28 KB.
Provata il 7 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.