
Attrezzi che cadono
Fisica, Hover
NuovaGratis
Una bacheca di cartoline. Basta sfiorarne una col puntatore e l’immagine viene lanciata dalla parte in cui andava il puntatore, veloce quanto lui, si torce un poco e torna al suo posto. Più veloce è il passaggio, più lontano vola; sul telefono un tocco la lancia in una direzione a caso.
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>Tossed cards</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/instrument-serif@5.3.0/index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/instrument-serif@5.3.0/400-italic.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/dm-sans@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<header class="bar">
<a class="brand" href="#">Wish You Were</a>
<nav class="bar__nav" aria-label="Sections">
<a href="#">Issues</a>
<a href="#">Shop</a>
<a href="#">About</a>
</nav>
</header>
<main class="board">
<div class="intro">
<h1 class="intro__title">Postcards from places <em>that don’t exist.</em></h1>
<p class="intro__hint" data-hint>Brush past a card: it flies off and comes back.</p>
</div>
<!-- each card: the figure keeps the place on the board, the inner part is what gets thrown -->
<div class="cards">
<figure class="card" data-card style="--r: -4deg; --y: 10px">
<div class="card__art" data-toss>
<svg viewBox="0 0 300 400" aria-hidden="true">
<rect width="300" height="400" fill="#1d2b4a"/>
<circle cx="205" cy="96" r="34" fill="#f3e7c9"/>
<path d="M0 250 70 170 120 215 175 140 240 220 300 180V280H0Z" fill="#121b30"/>
<rect y="276" width="300" height="124" fill="#1a3150"/>
<path d="M160 300h90M175 320h60M190 340h30" stroke="#f3e7c9" stroke-width="5" stroke-linecap="round" opacity="0.5"/>
</svg>
<figcaption>Greetings from <span>Lago Nero</span></figcaption>
</div>
</figure>
<figure class="card" data-card style="--r: 3deg; --y: -6px">
<div class="card__art" data-toss>
<svg viewBox="0 0 300 400" aria-hidden="true">
<rect width="300" height="400" fill="#ffd9a0"/>
<circle cx="150" cy="215" r="74" fill="#ff6b35"/>
<rect y="232" width="300" height="168" fill="#2a6f97"/>
<path d="M30 262h90M160 262h110M60 292h70M170 292h80M20 322h120M180 322h60M70 352h150" stroke="#7fb6d5" stroke-width="6" stroke-linecap="round"/>
</svg>
<figcaption>Greetings from <span>Saltmarsh</span></figcaption>
</div>
</figure>
<figure class="card" data-card style="--r: -2deg; --y: 18px">
<div class="card__art" data-toss>
<svg viewBox="0 0 300 400" aria-hidden="true">
<rect width="300" height="400" fill="#ffc2b4"/>
<circle cx="88" cy="108" r="30" fill="#fff1d6"/>
<path d="M0 250C70 190 130 200 180 240S270 260 300 230V400H0Z" fill="#f2937a"/>
<path d="M0 310C60 270 120 280 170 300S260 330 300 300V400H0Z" fill="#e86f51"/>
<path d="M0 360C80 330 150 350 210 370S280 380 300 360V400H0Z" fill="#c74b37"/>
</svg>
<figcaption>Greetings from <span>Dune Nine</span></figcaption>
</div>
</figure>
<figure class="card" data-card style="--r: 5deg; --y: 0px">
<div class="card__art" data-toss>
<svg viewBox="0 0 300 400" aria-hidden="true">
<rect width="300" height="400" fill="#dfe9d1"/>
<path d="M40 330V190a50 50 0 0 1 100 0v140M160 330V190a50 50 0 0 1 100 0v140" fill="none" stroke="#2f6b4f" stroke-width="10"/>
<path d="M90 330V230M210 330V230" stroke="#2f6b4f" stroke-width="6"/>
<path d="M60 330c10-40 40-50 50-80 10 30 0 60-10 80zM180 330c0-50 30-60 40-90 14 40 4 70-10 90z" fill="#3f8a5f"/>
<rect y="330" width="300" height="70" fill="#b9cfa4"/>
</svg>
<figcaption>Greetings from <span>Glasshouse</span></figcaption>
</div>
</figure>
<figure class="card" data-card style="--r: -5deg; --y: -8px">
<div class="card__art" data-toss>
<svg viewBox="0 0 300 400" aria-hidden="true">
<rect width="300" height="400" fill="#2a1f4d"/>
<path d="M60 70l4 10 10 4-10 4-4 10-4-10-10-4 10-4zM230 120l3 7 7 3-7 3-3 7-3-7-7-3 7-3zM170 55l2 5 5 2-5 2-2 5-2-5-5-2 5-2z" fill="#ffcf5c"/>
<rect x="20" y="210" width="260" height="80" rx="16" fill="#4b3a86"/>
<rect x="40" y="228" width="40" height="28" rx="5" fill="#ffcf5c"/>
<rect x="100" y="228" width="40" height="28" rx="5" fill="#ffcf5c"/>
<rect x="160" y="228" width="40" height="28" rx="5" fill="#ffcf5c"/>
<rect x="220" y="228" width="40" height="28" rx="5" fill="#ffcf5c"/>
<path d="M0 300h300M0 318h300" stroke="#8a78c9" stroke-width="5"/>
</svg>
<figcaption>Greetings from <span>Night Train</span></figcaption>
</div>
</figure>
<figure class="card" data-card style="--r: 2deg; --y: 14px">
<div class="card__art" data-toss>
<svg viewBox="0 0 300 400" aria-hidden="true">
<rect width="300" height="400" fill="#2f7fd1"/>
<path d="M20 330q30-16 60 0t60 0 60 0 60 0 40 0M20 360q30-16 60 0t60 0 60 0 60 0 40 0" fill="none" stroke="#bfe0ff" stroke-width="6" stroke-linecap="round"/>
<ellipse cx="110" cy="170" rx="58" ry="44" fill="#ffd23f" transform="rotate(-18 110 170)"/>
<ellipse cx="200" cy="230" rx="50" ry="38" fill="#ffd23f" transform="rotate(14 200 230)"/>
<path d="M150 120c20-30 50-30 70-20-20 20-45 26-70 20z" fill="#3a8c4a"/>
<path d="M236 190c16-24 40-26 56-18-16 18-36 22-56 18z" fill="#3a8c4a"/>
</svg>
<figcaption>Greetings from <span>Lemon Coast</span></figcaption>
</div>
</figure>
<figure class="card" data-card style="--r: -3deg; --y: 4px">
<div class="card__art" data-toss>
<svg viewBox="0 0 300 400" aria-hidden="true">
<rect width="300" height="400" fill="#cfe6f5"/>
<path d="M0 260 90 120 150 200 210 110 300 250V400H0Z" fill="#ffffff"/>
<path d="M90 120 120 260H0ZM210 110 240 250H300Z" fill="#a9c8e0" opacity="0.7"/>
<path d="M120 300l40-34 40 34v40h-80z" fill="#d9483b"/>
<rect x="148" y="312" width="22" height="28" fill="#7a2620"/>
<rect y="340" width="300" height="60" fill="#ffffff"/>
</svg>
<figcaption>Greetings from <span>Snow Hut</span></figcaption>
</div>
</figure>
</div>
</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/InertiaPlugin.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.
40 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 schede lanciate» da Animorio e adattala al mio sitoOgni cartolina è un figure, girato e spostato di poco con due variabili CSS: è il suo posto sulla bacheca e non si muove. Dentro c’è l’immagine con la cornice e la scritta, ed è lei che vola, così il posto resta quello anche a metà lancio.
Lo script tiene l’ultimo spostamento del puntatore fra un evento e il successivo. Quando il puntatore entra in una cartolina, quello spostamento moltiplicato per PUSH, e tenuto entro MAX pixel al secondo, diventa la velocità del lancio, moltiplicata ancora per il peso della cartolina (WEIGHTS).
Il lancio è un solo tween: inertia con una velocità per x e una per y e una fine a 0. Il plugin calcola da solo quanto dura e la curva: la cartolina parte alla velocità data, rallenta e atterra esattamente dov’era. RESISTANCE dice quanto in fretta frena, e la timeline gira PACE volte più veloce.
Nello stesso momento parte un secondo tween sulla rotazione: fino a metà di WOBBLE gradi a caso, in TWIST secondi, e indietro con yoyo. Tutti e due hanno overwrite auto, quindi un nuovo lancio prende il posto di quello in corso senza scatti.
Non si ascolta l’entrata in ogni cartolina: un solo ascoltatore di pointermove sulla finestra guarda in quale cartolina sta il puntatore e lancia quando cambia. Così un passaggio veloce su tre cartoline le lancia tutte e tre, una volta ciascuna.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
PUSH | script.js | 14 | Quanto dell’ultimo spostamento del puntatore va nel lancio: pixel al secondo per ogni pixel. |
MAX | script.js | 900 | Il lancio più veloce, in pixel al secondo. |
WOBBLE | script.js | 30 | La torsione più ampia, in gradi, metà per parte. |
TWIST | script.js | 0.4 | I secondi della torsione all’andata, e gli stessi al ritorno. |
PACE | script.js | 1.2 | Quanto più veloce dei suoi tempi gira il lancio. |
RESISTANCE | script.js | 100 | Quanto in fretta frena una cartolina lanciata: più alto, voli più corti. |
TAP | script.js | 650 | Sul telefono, quanto forte un tocco lancia una cartolina, in pixel al secondo. |
WEIGHTS | script.js | 1, 0.8, 1.25, 0.9, 1.15, 1, 0.85 | Il peso di ogni cartolina, in ordine: più pesante vola più lontano e si torce di più. |
--card | style.css | clamp(140px, 14vw, 214px) | La larghezza di una cartolina. |
Per qualunque griglia di schede, copertine, prodotti o foto che deve sembrare viva al passaggio del mouse: un portfolio, un negozio, una galleria. Funziona meglio con schede ben distanziate e un fondo pieno; su schede attaccate fra loro le lanciate coprono le vicine.
Le cartoline vanno su due colonne e la pagina scorre. Un tocco lancia la cartolina in una direzione a caso, quasi sempre verso l’alto, a 650 pixel al secondo; lo scorrimento col dito non lancia niente.
Le cartoline sono già al loro posto all’arrivo e non volano: il puntatore e il dito non le spostano.
GSAP 3.15.0, InertiaPlugin (GSAP) 3.15.0, Instrument Serif 5.3.0, DM Sans (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 5,2 KB; le librerie: GSAP + Inertia 31 KB.
Provata il 2 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.