
Il pulsante da far scorrere
Pulsanti, Fisica, Transizioni
NuovaGratis
Il download per ascoltare offline di un’app di audiolibri, fatto come uno scaffale fra due reggilibri d’ottone: ogni audiolibro è un libro. Quello che si scarica compare di vetro, si inclina, cade e si appoggia alla fila, e la sua tela sale dal basso con i byte; scaricato, si raddrizza scivolando al suo posto con un piccolo colpo. Se la connessione cade il libro scivola giù come una scala lungo un muro; alla fine un dito corre sulle coste, una luce passa sull’oro e la libreria si accende.
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, viewport-fit=cover">
<title>The filling shelf</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/bricolage-grotesque@5.3.0/standard.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the offline downloads of an audiobook app, as a shelf between two brass bookends: every audiobook is a book.
The one downloading appears as a glass ghost, tips over and leans on the row, and fills with its cloth from
the bottom as its bytes arrive; done, it stands up and slides into the row. The books are built by script.js
from the list at the top of it -->
<section class="shelf" aria-labelledby="shelf-title" data-shelf>
<div class="shelf__head">
<div class="shelf__status">
<p class="shelf__phase"><span class="shelf__swap" data-phase>Not on this phone yet</span></p>
<p class="shelf__note"><span class="shelf__swap" data-note>About 10 s on this Wi-Fi</span></p>
</div>
<p class="shelf__big" aria-hidden="true">
<span class="shelf__swap" data-big>1.4 GB</span>
<svg class="shelf__tick" viewBox="0 0 28 28" data-tick><path d="M6.5 14.8l5 5 10-11.4" pathLength="1"/></svg>
</p>
</div>
<div class="shelf__case" role="progressbar" aria-labelledby="shelf-title" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0" aria-valuetext="Not downloaded" data-bar>
<div class="shelf__light" aria-hidden="true" data-light></div>
<div class="shelf__row" aria-hidden="true" data-row>
<span class="bookend bookend--start"></span>
<span class="bookend bookend--end" data-end></span>
</div>
<div class="shelf__board" aria-hidden="true"></div>
</div>
<div class="shelf__foot">
<div class="shelf__list">
<h2 class="shelf__title" id="shelf-title">For the flight</h2>
<p class="shelf__meta" data-meta>10 audiobooks · 22 h</p>
</div>
<div class="shelf__buttons">
<button class="pill pill--icon" type="button" aria-label="Cancel download" data-cancel hidden>
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M7.5 7.5l9 9M16.5 7.5l-9 9"/></svg>
</button>
<button class="pill" type="button" data-action data-autoclic><span class="pill__label" data-label>Download</span></button>
</div>
</div>
<p class="sr" role="status" aria-live="polite" data-live></p>
</section>
</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.
67 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 «Lo scaffale che si riempie» da Animorio e adattala al mio sitoUn libro è un rettangolo rigido spesso t e alto h che gira attorno allo spigolo su cui poggia. Il suo peso gli dà un’accelerazione angolare θ'' = 3g(h·sin θ − t·cos θ) ÷ 2(t² + h²), negativa sotto l’angolo di bilico atan(t/h) (il libro torna dritto) e positiva sopra (cade). Per questo il libro viene posato mezzo grado oltre il bilico, con una spinta minima: esita, accelera e batte. Il conto si fa sul ticker di GSAP in quattro sottopassi, col fotogramma limitato a 1/30 di secondo; all’urto la velocità si capovolge e si riduce di BOUNCE.
Col piede a una distanza g dalla fila, l’angolo a cui il libro si appoggia viene dal contatto: o la sua faccia tocca lo spigolo in cima al libro prima (tan θ = g ÷ H, se il libro è abbastanza alto da arrivarci), o il suo spigolo in cima tocca il fianco di quel libro (sin θ = g ÷ h). Vale il primo dei due. La stessa funzione serve quando è appoggiato, quando si raddrizza scivolando verso la fila (g va a zero e l’angolo con lui) e quando scivola via nell’errore: il piede va a destra finché il libro è a 64 gradi o tocca il reggilibri, proprio come una scala che scivola lungo un muro. Così un libro non passa mai dentro un altro.
Il libro che si scarica si appoggia a LEAN gradi, ma sempre almeno 7 gradi oltre il suo bilico (un libro spesso deve inclinarsi di più per non tornare dritto); se fra la fila e il reggilibri non c’è spazio per inclinarsi così, sta dritto accanto alla fila, e l’ultimo scende dritto nel suo posto. Raddrizzandosi batte contro il vicino con la velocità che aveva e dondola sull’altro spigolo: il perno cambia, la gravità lo riporta indietro, il vicino lo ferma e gli toglie un po’ di slancio a ogni colpo, e oltre 0,6 del bilico viene trattenuto.
Il download finto è una timeline di arrivi di grandezza e intervallo casuali con un paio di soste; i libri seguono i byte con un ritardo di FOLLOW secondi, ma chiudono l’ultimo pezzo a passo costante, altrimenti una rincorsa esponenziale resterebbe al 99%. La tela è un livello sopra il vetro tagliato dal basso con clip-path: inset(), il cui ritaglio si allarga di 12 pixel ai lati per lasciar passare la sua ombra. Se i libri restano indietro (ognuno ha quasi un secondo di movimento suo) si affrettano di 1,6 o 2,2 volte, e un errore si mostra solo quando il libro che non è arrivato è giù sullo scaffale.
Le coste sono div con writing-mode vertical-rl; un titolo troppo lungo per la sua costa prima si stringe un poco (sui caratteri bastoni sull’asse wdth di Bricolage Grotesque), poi, su un libro spesso, va su due righe tagliate allo spazio più vicino al mezzo se le due metà sono equilibrate, e solo alla fine rimpicciolisce. L’oro è un gradiente con background-clip: text. Alla fine la stessa fascia di luce attraversa tutti i libri: ogni costa ha la sua copia del gradiente spostata di dove sta il libro (--bx), così si legge come una luce sola; poi la parete dietro i libri si accende con un gradiente caldo che si allarga dal mezzo.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
SECONDS | script.js | 8 | Quanto dura il download nella demo, in secondi (uno vero segue i suoi byte). |
BOOKS | script.js | [['Salt Road', 142], ['Night Ferry', 96], …] | Gli audiolibri da sinistra: il titolo sulla costa e la grandezza in megabyte, che fa anche lo spessore del libro. Da 2 a 14. |
FAIL_EVERY | script.js | 2 | Nella demo, un download ogni quanti perde la connessione (0 mai). |
FAIL_AT | script.js | 0.58 | Fin dove arriva il download che va storto, da 0 a 1. |
STALLS | script.js | 1 | Quanto spesso la connessione si ferma un attimo: 0 mai, 1 ogni tanto, 2 spesso. |
LEAN | script.js | 30 | Quanto si inclina sulla fila il libro che si scarica, in gradi (sempre almeno 7 oltre il punto in cui tornerebbe dritto). |
GRAVITY | script.js | 3400 | Quanto forte cadono i libri, in pixel al secondo al quadrato. |
BOUNCE | script.js | 0.32 | Quanto rimbalza un libro sul libro su cui cade: 0 niente, 0,6 molto. |
FOLLOW | script.js | 0.25 | Quanto ci mettono i libri a raggiungere i byte, in secondi. |
Per un’app di audiolibri, di ebook, di podcast o di musica che scarica una lista per ascoltarla o leggerla senza rete, per una biblioteca digitale o un’app di fumetti, e in generale per un download in coda di più elementi che hanno un nome, dove vale la pena vedere quali sono già arrivati.
La scheda è larga 400 pixel e sul telefono prende la larghezza dello schermo meno 16 pixel per lato (358 a 390): i libri si fanno più sottili per riempire la mensola e i titoli si riadattano alle coste. I pulsanti sono alti 44 e si usano col tocco; la pillola che si gonfia sotto il puntatore c’è solo col mouse. Sotto i 390 pixel un messaggio d’errore molto lungo finisce coi puntini.
I libri compaiono già dritti al loro posto e la tela entra con una dissolvenza man mano che arrivano i byte: niente caduta, niente dondolio, niente scivolata nell’errore (il vetro del libro si tinge di rosso). Alla fine niente dito sulle coste né fascia di luce: la luce della libreria si accende con una dissolvenza e compare la spunta. Le parole cambiano con una dissolvenza.
GSAP 3.15.0, Bricolage Grotesque (font variabile) 5.3.0, Fraunces (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 17 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.