
L’indicatore a lancetta
Contatori, Fisica, SVG
NuovaGratis
La riga Apply coupon di un carrello, con un buono di carta arancione nella pillola: il codice AUTUMN15, un talloncino con una foglia e una fila di fori fra i due. Al clic il buono si strappa lungo i fori: il bordo frastagliato si calcola di nuovo ogni volta, si vede l'anima bianca della carta, e la metà strappata gira intorno al punto dove tiene ancora, si stacca e cade ruotando come una carta, poi svanisce sotto la pillola. Il buono si può anche tirare con la mano. Dopo Checking… una penna barra €120.00, il prezzo vecchio si rimpicciolisce in alto e quello nuovo scende con le cifre che girano sulle loro ruote fino a €102.00, e arriva un distintivo −15%. Un altro clic toglie lo sconto: il tratto si cancella, le cifre risalgono e un buono nuovo sale al suo posto.
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 coupon button</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/mona-sans@5.3.0/wdth.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/jetbrains-mono@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the coupon button: the Apply coupon line of a cart, with a small paper coupon in the pill, perforated down its
stub. A click (or a pull on the coupon) tears it along the holes: the torn edge is worked out anew every time,
the torn half falls away spinning, and the price is struck through with a pen and rolls down to the new one.
Another click takes the discount off and a fresh coupon rises in its place -->
<div class="deal" data-deal>
<button class="deal__btn" type="button" data-btn data-autoclic>
<span class="deal__fill" aria-hidden="true"></span>
<svg class="deal__coupon" viewBox="0 0 104 42" aria-hidden="true" data-coupon>
<defs>
<linearGradient id="cp-paper" x1="0" y1="0" x2="0.35" y2="1">
<stop offset="0" class="cp-a"/>
<stop offset="1" class="cp-b"/>
</linearGradient>
<pattern id="cp-print" width="3.2" height="3.2" patternUnits="userSpaceOnUse" patternTransform="rotate(32)">
<path class="cp-print" d="M0 1.6h3.2"/>
</pattern>
<clipPath id="cp-cut-stub"><path data-cut="stub"/></clipPath>
<clipPath id="cp-cut-voucher"><path data-cut="voucher"/></clipPath>
<g id="cp-art">
<!-- the paper: a ticket with a notch top and bottom where the perforation runs -->
<path class="cp-paper" d="M3.5 0H18.6A3.4 3.4 0 0 0 25.4 0H100.5A3.5 3.5 0 0 1 104 3.5V38.5A3.5 3.5 0 0 1 100.5 42H25.4A3.4 3.4 0 0 0 18.6 42H3.5A3.5 3.5 0 0 1 0 38.5V3.5A3.5 3.5 0 0 1 3.5 0Z"/>
<path class="cp-printed" d="M3.5 0H18.6A3.4 3.4 0 0 0 25.4 0H100.5A3.5 3.5 0 0 1 104 3.5V38.5A3.5 3.5 0 0 1 100.5 42H25.4A3.4 3.4 0 0 0 18.6 42H3.5A3.5 3.5 0 0 1 0 38.5V3.5A3.5 3.5 0 0 1 3.5 0Z"/>
<rect class="cp-dash" x="28.5" y="4.5" width="71" height="33" rx="2.4"/>
<!-- a fallen leaf on the stub -->
<g class="cp-leaf" transform="translate(11 21) rotate(-28)">
<path d="M0 -8.2C3.6 -5.6 4.6 -1.6 3.4 2.2C2.6 4.6 1.2 6.2 0 7C-1.2 6.2 -2.6 4.6 -3.4 2.2C-4.6 -1.6 -3.6 -5.6 0 -8.2Z"/>
<path class="cp-vein" d="M0 -6.6V9.6M0 -2.6L2.4 -4.4M0 -2.6L-2.4 -4.4M0 0.9L2.8 -0.9M0 0.9L-2.8 -0.9M0 4.1L2.2 2.6M0 4.1L-2.2 2.6"/>
</g>
<text class="cp-off" x="34" y="16.2" data-off-text>15% OFF</text>
<text class="cp-code" x="33.6" y="30.4" data-code-text>AUTUMN15</text>
</g>
</defs>
<g class="cp-piece" data-piece="stub">
<g clip-path="url(#cp-cut-stub)"><use href="#cp-art"/></g>
<path class="cp-fiber" data-fiber="stub"/>
</g>
<g class="cp-piece" data-piece="voucher">
<g clip-path="url(#cp-cut-voucher)"><use href="#cp-art"/></g>
<path class="cp-fiber" data-fiber="voucher"/>
</g>
</svg>
<span class="deal__faces" data-faces>
<span class="deal__face" data-face="rest">
<span class="deal__word" data-wide="Apply coupon" data-rest-text>Apply coupon</span>
</span>
<span class="deal__face deal__face--busy" data-face="busy" aria-hidden="true">
<span class="deal__shine" data-busy-text>Checking…</span>
</span>
<span class="deal__face deal__face--done" data-face="done" aria-hidden="true">
<span class="deal__lines">
<span class="deal__applied" data-applied-text>Coupon applied</span>
<span class="deal__sub"><span class="deal__code" data-code-small>AUTUMN15</span> · <span data-remove-text>Remove</span></span>
</span>
</span>
</span>
<span class="deal__chip" aria-hidden="true" data-chip>−15%</span>
<span class="deal__price" data-price>
<span class="deal__was" aria-hidden="true" data-was>
<span data-was-text>€120.00</span>
<svg class="deal__strike" aria-hidden="true" data-strike-svg><path data-strike/></svg>
</span>
<span class="deal__now" data-now></span>
</span>
</button>
<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.
26 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 del buono sconto» da Animorio e adattala al mio sitoIl buono è un gruppo SVG in defs (la carta col suo gradiente, una stampa fine di righe oblique, la cornice tratteggiata, la foglia sul talloncino, 15% OFF e il codice in JetBrains Mono) usato due volte con use: una copia è il talloncino, l'altra il buono, e ognuna ha il suo clipPath. I due clipPath si toccano lungo la linea di strappo, quindi a riposo si vede un buono intero; i fori della perforazione non sono disegnati, sono i buchi che restano fuori da tutti e due i ritagli, e si vede la pillola attraverso.
A ogni buono nuovo un generatore casuale con un seme nuovo costruisce lo strappo: fra un foro e l'altro (ogni 3,1 unità, raggio 0,72) il ponticello di carta cede lungo tre o quattro punti spostati a caso di lato, di più a metà del ponticello (seno), quanto dice RAGGED; a ogni foro il talloncino tiene il suo mezzo cerchio di sinistra e il buono quello di destra. Così i due bordi combaciano, e il bordo non è mai uguale due volte. Lungo la parte già strappata si disegna un tratto avorio, l'anima bianca della carta sotto la stampa.
Mentre lo strappo scende (tear.t da 0 a 1 in TEAR secondi, oppure seguendo la mano) il buono gira intorno al punto dove tiene ancora, fino a 11 gradi. Arrivato in fondo diventa una carta libera: il centro e l'angolo si ricavano dalla rotazione intorno all'ultimo punto, la velocità da una piccola spinta (più quella della mano, se è stato tirato), e da lì gravità (GRAVITY), resistenza dell'aria più forte di traverso che in giù, una spinta di lato che segue sin 2a come una carta lasciata cadere piatta, e una rotazione che rallenta (SPIN). Passi di 1/240 di secondo, fotogramma limitato a 1/30; dopo venti pixel di caduta il buono svanisce in ottanta. Il talloncino riceve un colpo su una molla e trema.
Il tratto di penna è un path nuovo a ogni sconto (un poco in salita, curvo, con l'uncino dove la penna si alza), disegnato con stroke-dashoffset. Il prezzo è fatto di ruote: ogni cifra che cambia è una striscia con uno spazio vuoto e tre giri di cifre dietro una finestra alta una cifra, con una maschera che la sfuma in alto e in basso; il prezzo pieno usa il terzo giro e quello scontato il secondo, quindi scendendo ogni ruota gira in giù e tornando gira in su. Il prezzo vecchio è composto nelle stesse celle larghe uguali, così sta esattamente sopra le ruote quando la penna lo barra, e poi si rimpicciolisce in alto.
Il buono si può anche tirare: pointerdown sul buono (non sul talloncino) cattura il puntatore, e lo spostamento verso destra o in basso diventa lo strappo, (dx · 0,7 + dy · 0,7) / 70. Lasciato oltre metà finisce di strapparsi e la velocità della mano passa alla caduta; prima torna al suo posto con un elastico. Dopo un trascinamento il clic che segue viene ignorato. Il buono ha touch-action: none, così sul telefono il dito tira invece di far scorrere la pagina; un tocco semplice resta un clic.
Il pulsante è un button vero con un aria-label che dice tutto (Apply coupon AUTUMN15. Total €120.00; da applicato il codice, lo sconto, il totale nuovo e quello vecchio, e Remove coupon), una zona aria-live (Applying AUTUMN15…, AUTUMN15 applied: 15% off. New total €102.00., Coupon removed.) e aria-disabled mentre lavora. Il controllo del codice è simulato. Applicare dura circa tre secondi, più dei 2,8 fra un clic e l'altro dell'anteprima: il secondo clic cade nell'attesa e lo sconto resta in vista un giro intero.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
LABEL | script.js | Apply coupon | La scritta a riposo. Se è troppo lunga per lo spazio, il carattere si rimpicciolisce. |
CODE | script.js | AUTUMN15 | Il codice stampato sul buono, ripetuto sotto Coupon applied e nella zona aria-live. |
PERCENT | script.js | 15 | Lo sconto in percento: cambia il buono (15% OFF), il distintivo e il prezzo nuovo. |
PRICE | script.js | 120 | Il totale del carrello prima dello sconto; quello scontato si calcola. |
CURRENCY | script.js | € | Il simbolo scritto prima del prezzo. |
BUSY | script.js | Checking… | La scritta mentre il codice si controlla (simulato). |
APPLIED | script.js | Coupon applied | La scritta a sconto fatto. |
REMOVE | script.js | Remove | La parolina che dice che un altro clic toglie lo sconto. |
TEAR | script.js | 0.34 | I secondi che lo strappo ci mette a scendere lungo la perforazione. |
RAGGED | script.js | 1 | Quanto è frastagliato il bordo strappato: 0 pulito da foro a foro, 2 molto ruvido. |
GRAVITY | script.js | 1500 | Quanto forte cade la metà strappata, in pixel al secondo al quadrato. |
SPIN | script.js | 1 | Quanto gira la metà strappata cadendo: 0 cade diritta. |
ROLL | script.js | 0.9 | I secondi in cui le cifre girano fino al prezzo nuovo. |
Per il codice sconto di un carrello o di una cassa: il buono di una stagione, il codice di benvenuto, quello di un influencer, una carta regalo. Sta bene nei negozi di moda, di casa, di cosmetica e in ogni promozione stagionale. Il controllo del codice è simulato: in un negozio vero il clic manda il codice al server, e lo strappo può partire subito mentre la penna aspetta la risposta.
La pillola a riposo è larga circa 345 pixel e quella scontata circa 320: a 390 pixel ci stanno, e se la scritta è più lunga dello spazio il carattere si rimpicciolisce. Il tocco strappa il buono; il dito può anche tirarlo, e sopra il buono la pagina non scorre. Il buono che cade esce sotto la pillola e svanisce prima di arrivare in fondo allo schermo.
Niente strappo che scende, niente caduta e niente ruote che girano: al clic il buono svanisce lasciando il talloncino col bordo strappato, la pillola prende la nuova larghezza mentre le parole sono sparite, e prezzo barrato, prezzo nuovo e distintivo arrivano in dissolvenza. Il buono non dà lo strattone e la pillola non si gonfia (sotto il mouse il fondo si schiarisce appena). Un altro clic fa sparire tutto in dissolvenza e un buono nuovo appare in dissolvenza.
GSAP 3.15.0, Mona Sans (font variabile) 5.3.0, JetBrains Mono (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 14 KB; le librerie: GSAP 28 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.