
Il pulsante da far scorrere
Pulsanti, Fisica, Transizioni
NuovaGratis
Il cambio fra tema chiaro e scuro fatto come la catenella di una lampada a sospensione: una catena di maglie allungate d’ottone, simulata maglia per maglia, con in fondo un pomolo a goccia. Si tira giù col mouse o col dito, la catenella esce un poco dal portalampada, scatta, e la lampada si accende o si spegne: la luce cade a cono sulla scritta Lights on e la stanzetta intorno passa dai colori chiari a quelli scuri. Lasciata, la catenella oscilla come un pendolo e si ferma.
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 pull chain button</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/instrument-sans@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the pull chain button: a pendant lamp with a chain of long metal links and a brass drop at the end. Pull the
chain (or press the drop, or Enter) and the lamp clicks on or off, and the little room it hangs in switches
between its light and its dark colours. Let go, and the chain swings like a pendulum and settles -->
<div class="room" data-room data-light="on">
<div class="room__scene" data-scene>
<!-- the light: a cone from the shade down to the floor, painted once on its own canvas and blended into the
room; it swings with the shade -->
<canvas class="room__light" aria-hidden="true" data-cone></canvas>
<!-- the lamp: the cord, the canopy, the enamel shade and the bulb, swinging round the top of the cord -->
<svg class="room__lamp" viewBox="0 0 360 500" aria-hidden="true" data-lamp>
<defs>
<linearGradient id="chain-enamel" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" style="stop-color: var(--enamel-dark)"/>
<stop offset="0.28" style="stop-color: var(--enamel)"/>
<stop offset="0.42" style="stop-color: var(--enamel-light)"/>
<stop offset="0.6" style="stop-color: var(--enamel)"/>
<stop offset="1" style="stop-color: var(--enamel-dark)"/>
</linearGradient>
<linearGradient id="chain-brass" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" style="stop-color: var(--brass-dark)"/>
<stop offset="0.38" style="stop-color: var(--brass-light)"/>
<stop offset="0.62" style="stop-color: var(--brass)"/>
<stop offset="1" style="stop-color: var(--brass-dark)"/>
</linearGradient>
<radialGradient id="chain-bulb" cx="0.5" cy="0.35" r="0.65">
<stop offset="0" style="stop-color: var(--bulb-core)"/>
<stop offset="1" style="stop-color: var(--bulb)"/>
</radialGradient>
</defs>
<g data-swing>
<path class="lamp__cord" d="M180 -4 V92"/>
<path d="M168 88 h24 l-3 10 h-18 z" fill="url(#chain-brass)"/>
<!-- the bulb, half out of the shade -->
<path class="lamp__bulb" d="M166 160 C164 176 170 192 180 192 C190 192 196 176 194 160 Z" fill="url(#chain-bulb)" data-bulb/>
<path class="lamp__filament" d="M174 170 q3 6 6 0 q3 6 6 0" data-filament/>
<!-- the shade: a dome of enamel with a rolled rim, and the inside showing under it -->
<ellipse class="lamp__inside" cx="180" cy="168" rx="74" ry="9" data-inside/>
<path d="M180 98 C150 98 140 112 132 132 C124 150 112 160 104 166 C108 172 252 172 256 166 C248 160 236 150 228 132 C220 112 210 98 180 98 Z" fill="url(#chain-enamel)"/>
<path class="lamp__sheen" d="M156 108 C146 118 140 134 132 150"/>
<path d="M104 166 C108 173 252 173 256 166" class="lamp__rim"/>
<!-- the socket the chain comes out of -->
<rect x="203" y="166" width="10" height="12" rx="2" fill="url(#chain-brass)"/>
</g>
</svg>
<!-- the chain and the drop are drawn link by link on the canvas -->
<canvas class="room__chain" aria-hidden="true" data-chain></canvas>
<!-- what the light falls on -->
<p class="room__label" aria-hidden="true">
<span class="room__word" data-word="on">Lights on</span>
<span class="room__word" data-word="off">Lights off</span>
</p>
<p class="room__hint" data-hint>Pull the chain to dim the room</p>
<!-- the real switch: a button over the brass drop, moved with it every frame -->
<button class="pull" type="button" role="switch" aria-checked="true" aria-label="Lights" data-pull data-autoclic></button>
</div>
<p class="sr" aria-live="polite" data-live></p>
</div>
</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.
29 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 pulsante a catenella» da Animorio e adattala al mio sitoLa catenella è una fila di punti: il primo è nel portalampada, poi un punto ogni LINK pixel, e gli ultimi due sono l’anello e la punta del pomolo, più pesanti delle maglie. A ogni passo di 1/120 di secondo ogni punto si sposta della sua velocità (la distanza da dove era prima, smorzata da DAMP) più la gravità; poi, quattordici volte, ogni coppia di punti vicini viene riportata alla sua distanza, spostando di più il punto più leggero. Il tempo si accumula e si consuma a passi fissi, mai più di 1/30 di secondo per fotogramma.
La mano tiene l’anello del pomolo, ma mai più lontano di quanto la catena arrivi. Quando il punto voluto è più lontano della lunghezza della catena, quello che avanza diventa la corsa nel portalampada, che cresce sempre più dura (TRAVEL per 1 meno e alla meno l’eccesso su TRAVEL): la catena è tesa e scivola fuori. A CLICK della corsa l’interruttore scatta una volta sola e si riarma quando la catena è rientrata per tre quarti; lasciata, una molla smorzata riporta la catena dentro e la catena, partita con la velocità della mano, oscilla.
Ogni maglia si disegna sul segmento fra due punti, ruotata lungo di esso e più lunga del passo, perché le maglie si agganciano l’una nell’altra: quelle pari di fronte, un anello di filo con il suo bordo scuro, il metallo e un filo di luce sul lato alto; quelle dispari di taglio, una barretta sottile. Sopra il primo punto si disegnano anche le maglie ancora nel portalampada, nascoste da un ritaglio finché non escono, così tirando la catena si vede uscire. Il pomolo è un tracciato a goccia con un gradiente d’ottone, una gola tornita e il riflesso.
Il cono, la luce intorno alla lampadina e la pozza sul pavimento si dipingono una volta sola su un canvas, con i bordi sfumati dall’ombra del canvas (la forma disegnata fuori vista e solo la sua ombra dentro), e il canvas è fuso nel muro con mix-blend-mode: screen: schiarisce quello che illumina invece di coprirlo. Accendendo il cono sfarfalla, spegnendo il filamento resta arancio un momento; i colori della stanza cambiano con una variabile di stato e una transizione, e la catena passa dai toni accesi a quelli spenti con un valore da 0 a 1.
Il paralume è un pendolo sul suo filo: la catena tesa lo tira di lato in proporzione a quanto è uscita, e lui ruota attorno alla cima del filo con il cono e il portalampada, così il primo punto della catena si sposta con lui. Quando niente si muove più per tre quarti di secondo la simulazione si ferma e il canvas non si ridisegna; la mano, il mouse vicino alla catena o un cambio di luce la svegliano.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
LINKS | script.js | 15 | Quante maglie ha la catenella. |
LINK | script.js | 9.6 | La lunghezza di una maglia, in pixel del disegno. |
GRAVITY | script.js | 2600 | Quanto forte la catenella è tirata in giù, in pixel al secondo al quadrato: di più, oscilla più in fretta. |
DAMP | script.js | 0.6 | Quanto presto l’oscillazione si spegne (0 = oscilla a lungo). |
TRAVEL | script.js | 18 | Di quanti pixel la catenella può uscire dal portalampada. |
CLICK | script.js | 0.72 | Quanta parte di quella corsa serve per far scattare l’interruttore. |
SWAY | script.js | 1 | Quanto oscilla il paralume quando si dà lo strattone (0 = sta fermo). |
START_ON | script.js | true | Se la lampada parte accesa (tema chiaro) o spenta (tema scuro). |
Per il cambio di tema di un sito con un po’ di carattere: un blog, un portfolio, la pagina di un caffè o di un negozio di lampade, una pagina di documentazione che vuole un tocco di gioco. Sta bene in un angolo dell’intestazione, ridotto, o grande in una pagina delle impostazioni. Qui cambia i colori solo dentro il suo riquadro: nel tuo sito basta che setLight cambi l’attributo sul documento invece che sulla stanza.
La stanzetta si stringe alla larghezza dello schermo e la catenella con lei. Il dito prende il pomolo e lo tira come il mouse; un tocco breve dà lo strattone da solo. Il pulsante vero sta fermo sopra il pomolo a riposo ed è largo abbastanza per il pollice, anche quando la catena oscilla.
Niente oscillazione: la catenella resta ferma e dritta, il paralume non dondola, e un tocco, Invio o Spazio accendono e spengono senza strattone, con la luce e i colori in dissolvenza e senza sfarfallio. Trascinata col dito o col mouse la catenella si tira lo stesso, e lasciata torna dritta senza oscillare.
GSAP 3.15.0, Fraunces (font variabile) 5.3.0, Instrument Sans (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 11 KB; le librerie: GSAP 28 KB.
Provata il 5 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.