
Il pavimento che si alza
SVG, Hover, Fisica
NuovaGratis
Un castello di carte da gioco si costruisce da solo, carta per carta, con le carte che arrivano planando e si appoggiano a coppie tremando; un clic o un soffio del puntatore lo fa crollare con la fisica vera, le carte si ammucchiano e poi il castello si rifà.
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 house of cards</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/bodoni-moda@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="scena" data-stage data-autoclic tabindex="0" role="button" aria-label="A house of cards: click to knock it down">
<!-- the drawings every card uses: the back of the deck and four fronts, drawn upright and turned to fit the card -->
<svg class="disegni" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="lattice" patternUnits="userSpaceOnUse" width="8" height="8" patternTransform="rotate(45)">
<path class="dorso-rete" d="M0 0V8M0 0H8" />
</pattern>
<path id="pip-heart" d="M0 8C-9 1-11-4-11-7C-11-11-8-13-5.5-13C-3-13-1-11.5 0-9.5C1-11.5 3-13 5.5-13C8-13 11-11 11-7C11-4 9 1 0 8Z" />
<path id="pip-diamond" d="M0-12C2.6-7 5.6-3 8.4 0C5.6 3 2.6 7 0 12C-2.6 7-5.6 3-8.4 0C-5.6-3-2.6-7 0-12Z" />
<path id="pip-spade" d="M0-13C-9-5-11 0-11 3C-11 7-8 9-5.5 9C-3.6 9-2 8-1.2 6.6C-1.4 9-2.6 11.2-4.6 12.6H4.6C2.6 11.2 1.4 9 1.2 6.6C2 8 3.6 9 5.5 9C8 9 11 7 11 3C11 0 9-5 0-13Z" />
<path id="pip-club" d="M0-13C3.4-13 5.8-10.4 5.8-7.2C5.8-5.8 5.4-4.6 4.6-3.6C5.2-3.8 5.8-3.9 6.4-3.9C9.6-3.9 12-1.4 12 1.8C12 5 9.6 7.6 6.4 7.6C4.4 7.6 2.6 6.6 1.6 5C1.8 8.2 2.8 10.8 4.6 12.6H-4.6C-2.8 10.8-1.8 8.2-1.6 5C-2.6 6.6-4.4 7.6-6.4 7.6C-9.6 7.6-12 5-12 1.8C-12-1.4-9.6-3.9-6.4-3.9C-5.8-3.9-5.2-3.8-4.6-3.6C-5.4-4.6-5.8-5.8-5.8-7.2C-5.8-10.4-3.4-13 0-13Z" />
<path id="star" d="M0-6C.8-1.6 1.6-.8 6 0C1.6.8.8 1.6 0 6C-.8 1.6-1.6.8-6 0C-1.6-.8-.8-1.6 0-6Z" />
<!-- the back of the deck: a lattice, a frame, and a moon with a star in an oval -->
<symbol id="back" viewBox="0 0 100 70">
<g transform="translate(100 0) rotate(90)">
<rect class="dorso-carta" width="70" height="100" rx="5" />
<rect class="dorso" x="4" y="4" width="62" height="92" rx="3" />
<rect fill="url(#lattice)" x="7" y="7" width="56" height="86" rx="2" />
<rect class="dorso-filo" x="7" y="7" width="56" height="86" rx="2" />
<rect class="dorso-filo dorso-filo--fine" x="9.5" y="9.5" width="51" height="81" rx="1.5" />
<ellipse class="dorso dorso-filo" cx="35" cy="50" rx="17" ry="23" />
<ellipse class="dorso-filo dorso-filo--fine" cx="35" cy="50" rx="14" ry="20" />
<path class="dorso-oro" d="M39.5 37.5C33 37.5 28.5 43 28.5 49.5C28.5 56 33 61.5 39.5 61.5C36.6 62.8 33.4 63.2 30.2 62C25.4 60 22.6 55 22.6 49.5C22.6 44 25.4 39 30.2 37C33.4 35.8 36.6 36.2 39.5 37.5Z" />
<use class="dorso-oro" href="#star" transform="translate(41 47) scale(.9)" />
<use class="dorso-oro" href="#star" transform="translate(44.5 57) scale(.45)" />
<use class="dorso-oro" href="#star" transform="translate(14 14) scale(.55)" />
<use class="dorso-oro" href="#star" transform="translate(56 14) scale(.55)" />
<use class="dorso-oro" href="#star" transform="translate(14 86) scale(.55)" />
<use class="dorso-oro" href="#star" transform="translate(56 86) scale(.55)" />
</g>
</symbol>
<!-- four fronts: an ace and three court letters, each with one big pip -->
<symbol id="front-a" viewBox="0 0 100 70">
<g transform="translate(100 0) rotate(90)">
<rect class="fronte" width="70" height="100" rx="5" />
<rect class="fronte-filo" x="3.5" y="3.5" width="63" height="93" rx="3" />
<use class="seme-nero" href="#pip-spade" transform="translate(35 50) scale(1.55)" />
<text class="indice seme-nero" x="9" y="16">A</text>
<use class="seme-nero" href="#pip-spade" transform="translate(10.5 24) scale(.32)" />
<g transform="rotate(180 35 50)">
<text class="indice seme-nero" x="9" y="16">A</text>
<use class="seme-nero" href="#pip-spade" transform="translate(10.5 24) scale(.32)" />
</g>
</g>
</symbol>
<symbol id="front-k" viewBox="0 0 100 70">
<g transform="translate(100 0) rotate(90)">
<rect class="fronte" width="70" height="100" rx="5" />
<rect class="fronte-filo" x="3.5" y="3.5" width="63" height="93" rx="3" />
<use class="seme-rosso" href="#pip-heart" transform="translate(35 51) scale(1.5)" />
<text class="indice seme-rosso" x="9" y="16">K</text>
<use class="seme-rosso" href="#pip-heart" transform="translate(10.5 24) scale(.32)" />
<g transform="rotate(180 35 50)">
<text class="indice seme-rosso" x="9" y="16">K</text>
<use class="seme-rosso" href="#pip-heart" transform="translate(10.5 24) scale(.32)" />
</g>
</g>
</symbol>
<symbol id="front-q" viewBox="0 0 100 70">
<g transform="translate(100 0) rotate(90)">
<rect class="fronte" width="70" height="100" rx="5" />
<rect class="fronte-filo" x="3.5" y="3.5" width="63" height="93" rx="3" />
<use class="seme-rosso" href="#pip-diamond" transform="translate(35 50) scale(1.6)" />
<text class="indice seme-rosso" x="9" y="16">Q</text>
<use class="seme-rosso" href="#pip-diamond" transform="translate(10.5 24) scale(.32)" />
<g transform="rotate(180 35 50)">
<text class="indice seme-rosso" x="9" y="16">Q</text>
<use class="seme-rosso" href="#pip-diamond" transform="translate(10.5 24) scale(.32)" />
</g>
</g>
</symbol>
<symbol id="front-j" viewBox="0 0 100 70">
<g transform="translate(100 0) rotate(90)">
<rect class="fronte" width="70" height="100" rx="5" />
<rect class="fronte-filo" x="3.5" y="3.5" width="63" height="93" rx="3" />
<use class="seme-nero" href="#pip-club" transform="translate(35 50) scale(1.45)" />
<text class="indice seme-nero" x="9" y="16">J</text>
<use class="seme-nero" href="#pip-club" transform="translate(10.5 24) scale(.32)" />
<g transform="rotate(180 35 50)">
<text class="indice seme-nero" x="9" y="16">J</text>
<use class="seme-nero" href="#pip-club" transform="translate(10.5 24) scale(.32)" />
</g>
</g>
</symbol>
</defs>
</svg>
<header class="testa">
<p class="sopra" data-head>Ottoline Vane presents</p>
<h1 class="titolo" data-head>The House of Cards</h1>
</header>
<!-- the table, turned a little so the backs of the cards show; the script deals the cards onto it -->
<div class="palco" data-view>
<div class="mondo" data-world>
<div class="tavolo" data-table></div>
</div>
</div>
<!-- the puff of air that knocks it down -->
<svg class="soffio" data-gusts aria-hidden="true" xmlns="http://www.w3.org/2000/svg"></svg>
<p class="nota" aria-live="polite"><span data-hint>Dealing the house</span></p>
</main>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/matter-js@0.20.0/build/matter.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.
25 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 castello di carte» da Animorio e adattala al mio sitoIl tavolo e le carte stanno in un mondo CSS 3D: un contenitore con transform-style preserve-3d, girato con rotateX e rotateY dentro un palco con la prospettiva. Ogni carta è un div lungo quanto la carta e profondo quanto è larga, con due facce schiena contro schiena (backface-visibility hidden): rotate porta l’inclinazione della carta, rotateX(90deg) la mette di taglio, così il dorso si vede di tre quarti. I disegni (dorso, assi e figure, semi) sono simboli SVG fatti da noi, usati con use.
Ogni carta è un oggetto con x, y, z, inclinazione e opacità: GSAP muove quei numeri, la fisica li riscrive, e a ogni giro del ticker una sola funzione li copia nei transform. Sotto ogni carta c’è un’ombra sul panno, larga quanto la carta vista dall’alto e più chiara quanto più la carta è in alto; e una carta in piedi è più scura di una sdraiata, che prende la luce della lampada.
Le posizioni del castello si calcolano in lunghezze di carta: l’inclinazione decide quanto si allargano i piedi di una coppia, la carta piatta sta sulle due punte vicine, il piano dopo poggia su di lei. Ogni carta arriva con una timeline: x con dei keyframe che oscillano di lato, y che rallenta, l’inclinazione che dondola e si smorza. Le due carte di una coppia si fermano un attimo sopra il loro posto, scendono insieme e tremano con dei keyframe piccoli intorno alla posizione giusta.
Al clic ogni carta diventa un rettangolo sottile in Matter.js, fermo (static) dove si trova. Le carte si liberano a onda, prima le più vicine al colpo, con una spinta che cala con la distanza ma non è mai zero, così crolla tutto. Il panno all’inizio è scivoloso, poi fa presa e il mucchio si ferma. Per ogni passo la velocità perpendicolare alla carta viene frenata, quella lungo la carta no: una carta di piatto cade piano e plana di lato, come quelle vere.
Una passata veloce del mouse sopra il castello (più di 2,6 pixel al millisecondo) fa lo stesso del clic, nella direzione del movimento; una lenta lo fa solo inclinare. La fisica avanza a passi fissi di 1/120 di secondo, e quando le carte sono ferme (o dopo pochi secondi) il mondo di Matter si svuota. Dopo un attimo una timeline nuova solleva ogni carta dal mucchio verso di noi e la riporta al suo posto con lo stesso volo della prima volta, più veloce.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
LEVELS | script.js | 4 | I piani del castello, da 2 a 5: con quattro piani le carte sono ventisei. |
LEAN | script.js | 18 | Di quanti gradi ogni carta pende dalla verticale. |
DEAL_SPEED / FLUTTER | script.js | 1 / 1 | La velocità della costruzione e quanto le carte dondolano planando. |
BLOW / SLIDE | script.js | 1 / 0.03 | La forza del colpo e quanto è scivoloso il panno mentre crolla. |
REST | script.js | 1.6 | I secondi in cui il mucchio resta lì prima che il castello si rifaccia. |
TURN | script.js | 28 | Di quanti gradi è girato il tavolo, per vedere i dorsi delle carte. |
--back, --gold, --felt | style.css | #8f1f2c, #e7c47a, #1d5446 | Il dorso delle carte, l’oro dei disegni e il panno del tavolo. |
Per la pagina di un mago, di un club di giochi da tavolo o di una sala da gioco, per un 404 («qui è crollato tutto») o per una pagina che parla di fragilità e di rischio. È un gioco da guardare: il contenuto vero va accanto.
Stesse animazioni e stessa fisica: le carte si misurano sullo schermo, quindi sul telefono il castello sta in larghezza e in altezza. Il soffio è solo del mouse; col dito basta un tocco.
Il castello è già costruito. Un clic lo fa sparire in dissolvenza e al suo posto compare il mucchio già fermo (la fisica si calcola tutta in un colpo); il clic dopo, sempre in dissolvenza, rimette il castello.
GSAP 3.15.0, Matter.js 0.20.0, Bodoni Moda (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 11 KB; le librerie: GSAP 28 KB, Matter.js 25 KB.
Provata il 10 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.