
Il menu che si apre dal pulsante
Menu, Transizioni, Testo
Gratis
Un campo per le etichette fatto con una vecchia etichettatrice a rilievo: scrivendo, la ruota delle lettere gira, il pomello scende e ogni lettera viene goffrata su un nastro di plastica lucida che esce dalla macchina, bianca dove la plastica si stira. Invio fa scattare la lama: l'etichetta tagliata vola sulla scatola di cartone e gli angoli le si arricciano un poco. Toccata, un'etichetta si stacca da un angolo e si accartoccia via. Tre nastri da scegliere: rosso, blu e nero.
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 label maker tags</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/archivo@5.3.0/wdth.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the tags of a box, made with an old embossing label maker: typing turns the wheel and presses every letter
into a strip of glossy plastic tape that comes out of the machine, the letters white where the plastic is
stretched. Enter (or the red lever) cuts the tape and the label flies onto the box, its corners curling a
little; a label tapped is peeled off and crumpled away. The labels and the tape are painted by the script -->
<div class="maker" data-maker data-autoclic>
<p class="maker__ask" id="maker-ask">Label this box</p>
<ul class="board" aria-labelledby="maker-ask" data-board></ul>
<div class="bench" data-bench>
<div class="bench__track" aria-hidden="true" data-track><span class="bench__ruler"></span></div>
<span class="bench__ghost" aria-hidden="true" data-ghost>Type a label</span>
<span class="bench__caret" aria-hidden="true" data-caret></span>
<canvas class="bench__tape" aria-hidden="true" data-tape></canvas>
<!-- the label maker, seen from above: the wheel of letters with its press knob, the pointer, the snout the
tape comes out of, the red cutter lever, the window on the tape cartridge -->
<svg class="machine" viewBox="0 0 200 124" aria-hidden="true" focusable="false" data-machine>
<defs>
<filter id="mk-soft" x="-20%" y="-200%" width="140%" height="500%"><feGaussianBlur stdDeviation="4.5"/></filter>
<filter id="mk-softer" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="1.6"/></filter>
<linearGradient id="mk-body" x1="0" y1="0" x2="0" y2="1">
<stop class="st-body-hi" offset="0"/>
<stop class="st-body" offset="0.42"/>
<stop class="st-body-deep" offset="1"/>
</linearGradient>
<linearGradient id="mk-rim" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#ffffff" stop-opacity="0.34"/>
<stop offset="0.35" stop-color="#ffffff" stop-opacity="0.04"/>
<stop offset="1" stop-color="#ffffff" stop-opacity="0"/>
</linearGradient>
<linearGradient id="mk-chrome" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#fbfcfd"/>
<stop offset="0.28" stop-color="#a6acb4"/>
<stop offset="0.5" stop-color="#eef0f2"/>
<stop offset="0.74" stop-color="#7b818a"/>
<stop offset="1" stop-color="#d6dade"/>
</linearGradient>
<linearGradient id="mk-chrome-v" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#f4f6f8"/>
<stop offset="0.5" stop-color="#9aa0a8"/>
<stop offset="1" stop-color="#d9dde1"/>
</linearGradient>
<radialGradient id="mk-disc" cx="0.42" cy="0.36" r="0.7">
<stop offset="0" stop-color="#34353a"/>
<stop offset="1" stop-color="#101113"/>
</radialGradient>
<radialGradient id="mk-knob" cx="0.36" cy="0.3" r="0.78">
<stop offset="0" stop-color="#ffffff"/>
<stop offset="0.22" stop-color="#e3e6e9"/>
<stop offset="0.62" stop-color="#9ba2aa"/>
<stop offset="1" stop-color="#5a6068"/>
</radialGradient>
<linearGradient id="mk-red" x1="0" y1="0" x2="0" y2="1">
<stop class="st-red-hi" offset="0"/>
<stop class="st-red" offset="0.55"/>
<stop class="st-red-deep" offset="1"/>
</linearGradient>
<radialGradient id="mk-glare" cx="0.3" cy="0.25" r="0.8">
<stop offset="0" stop-color="#ffffff" stop-opacity="0.55"/>
<stop offset="0.45" stop-color="#ffffff" stop-opacity="0.06"/>
<stop offset="1" stop-color="#ffffff" stop-opacity="0"/>
</radialGradient>
<clipPath id="mk-window"><circle r="17.6"/></clipPath>
</defs>
<ellipse class="mk-shadow" cx="104" cy="114" rx="90" ry="7" filter="url(#mk-soft)"/>
<g data-jolt>
<!-- the snout: the tape comes out of its left end, between two chrome jaws -->
<path class="mk-snout" d="M46 44H14C8.5 44 6 47 6 52V72C6 77 8.5 80 14 80H46Z"/>
<path class="mk-snout-rim" d="M46 44.6H14C9 44.6 6.6 47.4 6.6 52"/>
<rect class="mk-jaw" x="5" y="44.5" width="5.4" height="7" rx="1.6"/>
<rect class="mk-jaw" x="5" y="72.5" width="5.4" height="7" rx="1.6"/>
<rect class="mk-slot" x="4.4" y="50.6" width="2.2" height="22.8" rx="1"/>
<!-- the cutter lever, turning round its pin -->
<g transform="translate(42 93)">
<g data-lever>
<path class="mk-arm" d="M2 -3.2L-26 -2.4C-28.4 -2.3 -29 -1 -29 0.6V1.6C-29 3 -28.4 4 -26 4L2 3.6Z"/>
<rect x="-38.5" y="-6.5" width="14" height="13.5" rx="3.4" fill="url(#mk-red)"/>
<path class="mk-paddle-shine" d="M-36.4 -4.4H-27"/>
</g>
<circle class="mk-pin" r="3.6"/>
</g>
<!-- the body -->
<path class="mk-body" d="M62 10H160C182 10 196 30 196 62C196 94 182 114 160 114H62C44 114 32 99 32 82V42C32 25 44 10 62 10Z"/>
<path class="mk-body-rim" d="M62 10H160C182 10 196 30 196 62C196 94 182 114 160 114H62C44 114 32 99 32 82V42C32 25 44 10 62 10Z"/>
<path class="mk-body-edge" d="M196 62C196 94 182 114 160 114H62C44 114 32 99 32 82"/>
<!-- ribs of the grip -->
<g class="mk-ribs">
<path d="M184.5 46V78"/>
<path d="M188.5 48V76"/>
<path d="M192.2 51V73"/>
</g>
<!-- the window on the cartridge: the roll of tape turns as the tape is fed -->
<g transform="translate(160 62)">
<circle class="mk-recess" r="19.5"/>
<g clip-path="url(#mk-window)">
<g data-coil>
<g data-coil-spin>
<circle class="mk-coil" r="15.4" data-coil-fill/>
<circle class="mk-wrap" r="13.6"/>
<circle class="mk-wrap" r="11.8"/>
<circle class="mk-wrap" r="10"/>
<circle class="mk-hub" r="7.4"/>
<path class="mk-spoke" d="M0 -7V-3M6.06 3.5L2.6 1.5M-6.06 3.5L-2.6 1.5"/>
<circle class="mk-hole" r="2.6"/>
</g>
</g>
<g data-coil>
<g data-coil-spin>
<circle class="mk-coil" r="15.4" data-coil-fill/>
<circle class="mk-wrap" r="13.6"/>
<circle class="mk-wrap" r="11.8"/>
<circle class="mk-wrap" r="10"/>
<circle class="mk-hub" r="7.4"/>
<path class="mk-spoke" d="M0 -7V-3M6.06 3.5L2.6 1.5M-6.06 3.5L-2.6 1.5"/>
<circle class="mk-hole" r="2.6"/>
</g>
</g>
<circle r="17.6" fill="url(#mk-glare)"/>
</g>
<circle class="mk-bezel" r="18.8"/>
</g>
<!-- the wheel of letters, its chrome ring and the press knob in the middle -->
<g transform="translate(88 62)">
<circle class="mk-ring-shadow" r="51" cy="1.6" filter="url(#mk-softer)"/>
<circle r="50" fill="url(#mk-chrome)"/>
<g class="mk-knurl" data-knurl></g>
<circle class="mk-disc" r="45.4" fill="url(#mk-disc)"/>
<g data-wheel></g>
<circle class="mk-groove" r="29.6"/>
<circle class="mk-groove-hi" r="30.6"/>
<g data-knob>
<circle class="mk-knob-shadow" r="26" cy="2.2" filter="url(#mk-softer)"/>
<circle r="25" fill="url(#mk-knob)"/>
<circle class="mk-knob-line" r="21.5"/>
<circle class="mk-knob-line mk-knob-line--dark" r="17"/>
<circle class="mk-knob-line" r="12.5"/>
<path class="mk-knob-shine" d="M-15 -12A19 19 0 0 1 4 -18.6"/>
</g>
</g>
<!-- the pointer over the wheel: the letter under it is the one pressed -->
<path class="mk-pointer-base" d="M81.2 3.2H94.8L92.4 9.4H83.6Z"/>
<path d="M83.4 4.6H92.6L88 16.6Z" fill="url(#mk-red)"/>
</g>
</svg>
<input class="bench__input" id="maker-input" type="text" aria-label="New label" aria-describedby="maker-hint" autocomplete="off" autocapitalize="characters" autocorrect="off" spellcheck="false" enterkeyhint="done" data-input>
<button class="bench__cut" type="button" aria-label="Cut the label" data-cut></button>
</div>
<div class="maker__foot">
<p class="maker__hint" id="maker-hint" data-hint></p>
<fieldset class="tapes" data-tapes>
<legend class="sr">Tape colour</legend>
<span class="tapes__name" aria-hidden="true">Tape</span>
<label class="pick" style="--t: var(--red)"><input type="radio" name="maker-tape" value="red" checked><span class="pick__tape">RED</span></label>
<label class="pick" style="--t: var(--blue)"><input type="radio" name="maker-tape" value="blue"><span class="pick__tape">BLUE</span></label>
<label class="pick" style="--t: var(--black)"><input type="radio" name="maker-tape" value="black"><span class="pick__tape">BLACK</span></label>
</fieldset>
</div>
<p class="sr" aria-live="polite" data-live></p>
</div>
</main>
<!-- where a label peeled off is crumpled and thrown away -->
<canvas class="wads" aria-hidden="true" data-wads></canvas>
<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.
34 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 etichette dell'etichettatrice» da Animorio e adattala al mio sitoSopra tutto il banco c'è un input vero, trasparente, a 16 pixel: lo tocca il dito, lo legge lo screen reader. Il testo viene ripulito a ogni tasto (maiuscole, niente accenti, solo i caratteri della ruota) e resta la verità: la macchina lo insegue una lettera alla volta, con un lavoro alla volta in una timeline GSAP, più veloce quando è indietro (timeScale secondo le lettere che aspettano). Le etichette sono pulsanti Peel off, i nastri radio, e una regione aria-live dice cosa succede.
La ruota è un SVG con quaranta caratteri in cerchio, le teste verso fuori. Per ogni lettera gira della differenza più corta (normalizzata fra -180 e 180 gradi) con back.out, così si sente lo scatto; la lettera sotto la freccia si accende. Poi il nastro avanza di PITCH pixel, il rotolo gira di quanto nastro è uscito, il pomello scala a 0,88 e la macchina sobbalza di un pixel.
Nastro ed etichette sono dipinti su canvas dalla stessa funzione: la plastica con un gradiente, la lucentezza sopra e un filo di luce in alto. Ogni lettera è tre passate: un'ombra sfocata in basso a destra, un bordo di luce in alto a sinistra e la lettera schiarita verso il bianco quanto è stata premuta (p da 0 a 1), con l'ammaccatura della matrice mentre scende. Le lettere stanno a passo fisso come sul nastro vero, e nel canvas usano l'asse di larghezza di Archivo (fontStretch), o se manca un restringimento.
Ogni angolo ha una misura c e un angolo a: il nastro perde il triangolo fino alla piega e la punta, vista dall'alto, torna verso la piega di cos(a). Fino a 90 gradi si vede il davanti, che prende luce, oltre si vede il retro; sotto, l'ombra dell'angolo sollevato. Atterrata un'etichetta, gli angoli passano da 0 al loro valore a riposo; il puntatore ne solleva uno un po' di più, pronto da staccare.
Tagliata, l'etichetta entra subito nella fila (le altre fanno posto con FLIP) e parte dal punto del nastro: sale nello spazio fra macchina e scatola, va di lato e sale al suo posto da sotto, così non passa mai sopra un'altra etichetta. Staccata, diventa una griglia di triangoli su un canvas sopra la pagina: ogni punto va dalla sua posizione sull'etichetta piatta a un punto di una sfera stropicciata da un rumore continuo, prima l'angolo preso; ogni triangolo è disegnato con il suo pezzo d'etichetta (una trasformazione affine per triangolo), ombreggiato secondo la sua normale e, se si è girato, con il colore del retro.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
START | script.js | [['FRAGILE', 'red'], ['KITCHEN', 'blue'], ['BOOKS', 'black']] | Le etichette sulla scatola all'apertura della pagina, ognuna col suo nastro: red, blue o black. |
MAX | script.js | 6 | Quante etichette stanno sulla scatola. |
LONGEST | script.js | 12 | Quante lettere può avere al massimo un'etichetta (la scanalatura è lunga così). |
PITCH | script.js | 11.5 | Lo spazio di ogni lettera sul nastro, in pixel. |
PRESS | script.js | 0.42 | I secondi che la macchina impiega per una lettera: la ruota gira, il nastro avanza, il pomello scende. |
CURL | script.js | 6 | Quanto si arricciano gli angoli di un'etichetta, in pixel. |
FLIGHT | script.js | 0.8 | I secondi del volo di un'etichetta dalla macchina alla scatola. |
TOSS | script.js | 1 | Quanto forte viene buttata via un'etichetta accartocciata (0 la lascia cadere). |
Per le etichette di un'app di traslochi o di magazzino, le categorie di un archivio, le parole chiave di un portfolio o di un blog fatto a mano, le etichette di un negozio di oggetti vintage o di cancelleria: dove il campo delle etichette può essere il pezzo che si ricorda.
La macchina si rimpicciolisce all'82% e la scanalatura le sta accanto; la scatola ha due righe di posto, così la quarta etichetta non spinge giù la macchina. Toccando il banco si apre la tastiera (la casella è a 16 pixel, così Safari su iPhone non ingrandisce, le maiuscole sono accese e la correzione spenta); il tasto della tastiera o la leva rossa tagliano. Un tocco su un'etichetta la stacca: al posto del passaggio del puntatore, l'angolo si solleva quando la si tocca.
La ruota va subito alla lettera e il nastro esce senza scivolare; le lettere compaiono in dissolvenza, l'etichetta tagliata compare in dissolvenza al suo posto sulla scatola e quella staccata svanisce, senza volo né pallina; il rotolo si cambia in dissolvenza e niente trema. La macchina resta tutta da usare.
GSAP 3.15.0, Archivo (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 20 KB; le librerie: GSAP 28 KB.
Provata il 17 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.