Vai al contenuto
animorio
EN
Tutti i componenti

Il pennino al guinzaglio

Disegno, Fisica, SVGGSAP, CanvasImpegnativaPeso compresso: Demo 15 KBGSAP 28 KBGratisScarica lo zip

Un riquadro per firmare o disegnare, nello stile minimal, col «pennello pigro»: l’inchiostro non esce dalla mano ma da un pennino vermiglio legato alla mano con un filo sottile. Finché il filo è lento il pennino resta fermo; teso, lo tira dietro di sé, e il tratto esce liscio anche se la mano trema. Undo fa riavvolgere al pennino l’ultimo tratto, Clear tira ogni tratto come un filo finché diventa dritto e scivola via, e un cursore cambia la lunghezza del filo.

Il codice

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 leashed nib</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/roboto-flex@5.3.0/full.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- a pad to sign or sketch on with a lazy brush: the ink does not come from the hand but from a nib tied to it by a
         thread of fixed length. While the thread is slack the nib stays put; pulled taut, it tows the nib, and the line
         comes out smooth however the hand shakes. Undo makes the nib reel its last line back in, Clear pulls every line
         tight like a thread until it lies straight and slips away, and the slider sets the length of the thread -->
    <section class="sheet" aria-labelledby="sheet-title" data-card data-autoclic>
      <header class="sheet__head">
        <h2 class="sheet__title" id="sheet-title">Sign for your parcel</h2>
        <div class="sheet__acts">
          <button class="act" type="button" data-undo disabled><span class="act__word">Undo</span></button>
          <button class="act" type="button" data-clear disabled><span class="act__word">Clear</span></button>
        </div>
      </header>

      <div class="pad" tabindex="0" role="application" aria-roledescription="signature pad" aria-label="Signature pad, empty" aria-describedby="pad-help" data-pad>
        <canvas class="pad__ink" aria-hidden="true" data-canvas></canvas>
        <svg class="pad__over" aria-hidden="true" focusable="false" data-over>
          <rect class="pad__frame" pathLength="1" data-frame></rect>
          <line class="pad__base" pathLength="1" data-base></line>
          <g class="dim" data-dim>
            <line class="dim__end" data-dim-a></line>
            <line class="dim__end" data-dim-b></line>
          </g>
          <path class="leash" data-leash></path>
          <g class="hand" data-hand>
            <line x1="-5.5" y1="0" x2="5.5" y2="0"></line>
            <line x1="0" y1="-5.5" x2="0" y2="5.5"></line>
          </g>
          <g class="nib" data-nib>
            <rect class="nib__shape" x="-3.6" y="-3.6" width="7.2" height="7.2" data-nib-shape></rect>
          </g>
        </svg>
        <span class="pad__hint" data-hint>Sign above the line</span>
      </div>

      <div class="sheet__foot">
        <label class="leash-word" for="leash-range"><span data-word>Leash</span></label>
        <div class="range-wrap">
          <input class="range" id="leash-range" type="range" min="0" max="60" step="1" value="22" data-range>
          <span class="range__ticks" aria-hidden="true" data-ticks></span>
        </div>
        <output class="leash-val" for="leash-range" data-val>22 px</output>
      </div>

      <p class="sr" id="pad-help">Draw with a mouse, a pen or a finger. With the keys, the arrows move the hand, Space puts the nib down and lifts it.</p>
      <p class="sr" 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>

Playground

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.

21 valori da cambiare

Oppure chiedila a Claude Code

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 pennino al guinzaglio» da Animorio e adattala al mio sito

Cosa fa

Su un fondo bianco, in alto a sinistra Sign for your parcel e a destra due pulsanti a pillola con un bordo sottile, Undo e Clear; sotto, un riquadro disegnato con una linea sottile, con una riga di base grigia e sotto la riga Sign above the line. All’inizio della riga c’è il pennino, un piccolo rombo vermiglio vuoto. In fondo la parola Leash, un cursore sottile con una tacca ogni dieci pixel e la lunghezza del filo, 22 px. Quando la pagina si apre il riquadro si disegna dall’angolo, la riga di base corre da sinistra a destra e il pennino cade sulla riga, va oltre di un pixel e si posa. Col mouse sul riquadro il puntatore diventa una crocetta sottile, legata al pennino da un filo grigio lungo 22 pixel: finché il filo è lento il pennino non si muove e il filo pende un poco; quando la mano si allontana il filo si tende, diventa dritto e nero e tira il pennino, che si gira verso la mano. Premendo il pennino si riempie e scrive: l’inchiostro, quasi nero, è di uno o due pixel e si assottiglia quando il pennino va veloce; un tremolio della mano più corto del filo non arriva al foglio, e gli angoli diventano curve. Uscendo dal riquadro il filo si riavvolge dentro il pennino. Undo fa correre il pennino all’indietro sul suo ultimo tratto, tirato dal filo che gli corre davanti, e il tratto sparisce dietro di lui. Clear tira ogni tratto come un filo, dall’ultimo al primo: prima spariscono i riccioli piccoli, poi le curve grandi, finché il tratto è una linea dritta fra i suoi due capi, che vibra una volta come un filo pizzicato e scivola via verso la fine; il pennino torna a casa. Spostando il cursore la parola Leash si allarga o si stringe con la lunghezza, e sul foglio il filo si stende dritto dal pennino, lungo quanto dice il cursore, con una tacca ai due capi come una quota.

Come funziona

Il pennello pigro

La mano (il mouse, la penna, il dito, i tasti) e il pennino sono due punti diversi. A ogni movimento si misura la distanza fra loro: se è meno della lunghezza del filo il pennino resta dov’è; se è di più, il pennino viene portato sulla retta verso la mano, esattamente a un filo di distanza. È tutto qui il trucco: il pennino percorre solo la parte lunga del movimento, e i tremolii più corti del filo si perdono. Per un tratto veloce si usano anche i punti che il browser raccoglie fra due fotogrammi (getCoalescedEvents).

Il filo è una catena

Il filo che si vede è una catena di 16 anelli mossa con Verlet (ogni anello ricorda dov’era, e la differenza è la sua velocità) con una piccola gravità, SAG, e poi tenuta alla sua lunghezza: un filo non si allunga, quindi ogni anello troppo lontano dal vicino viene riavvicinato, 14 volte a passo, mai allontanato. I capi sono la mano e il pennino. Teso, il filo viene disegnato perfettamente dritto e il suo colore va dal grigio al nero dell’inchiostro; il pennino, un rombo, si gira verso dove il filo lo tira.

L’inchiostro

Ogni tratto è un elenco di punti del pennino con la loro larghezza: la velocità del pennino fra due punti porta la larghezza da WIDTH[1] verso WIDTH[0] man mano che si avvicina a SPEED, un poco alla volta. Si disegna su un canvas alla densità dello schermo, con curve che passano per i punti di mezzo, ogni pezzo largo quanto i suoi capi; ogni tratto ricorda quale parte si vede (da a a b, anche a metà fra due punti), e così Undo e Clear possono accorciarlo da un lato o dall’altro.

Undo riavvolge

Undo porta la fine visibile dell’ultimo tratto fino al suo inizio con power2.inOut, in un tempo che cresce con la lunghezza; il pennino sta sempre su quella fine, e il capo lontano del filo viene messo sul tratto stesso, più indietro di una lunghezza di filo, misurata lungo la curva: sembra una mano che tira il pennino all’indietro sulla sua strada. Oltre l’inizio il filo continua dritto nella direzione del primo pezzo.

Clear tira i fili

Ogni tratto viene ricampionato in punti a passo uguale, e quanto ogni punto si allontana dalla retta fra i due capi viene scomposto in onde (una trasformata seno discreta). Poi ogni onda k si spegne come exp(−k² τ), con τ che cresce col tempo: è l’equazione del calore, quella che liscia una curva, e per questo i riccioli piccoli spariscono subito e le curve grandi per ultime. Dritto, il tratto vibra una volta (un seno smorzato di un paio di pixel) e scivola via verso la fine, dall’ultimo tratto al primo, sfalsati.

Tasti, cursore e anteprima

Il riquadro è focalizzabile: le frecce muovono la mano di 8 pixel (24 con Maiuscole), Spazio o Invio abbassano e alzano il pennino, Esc lo alza; la scala dei tasti diventa una curva da sola, grazie al filo. Il cursore è un input range vero: la parola Leash prende la larghezza (asse wdth di Roboto Flex, da 40 a 151) dalla lunghezza, con back.out. Un clic da script (l’anteprima della libreria) firma con una mano finta che trema, allunga il filo e sottolinea a zigzag, poi fa Undo, rimette il filo e fa Clear.

Valori da cambiare

NomeFileDi partenzaCosa cambia
LEASHscript.js22La lunghezza del filo fra la mano e il pennino, in pixel, quella con cui parte il cursore: 0 disegna dalla mano.
LEASH_MAXscript.js60Il filo più lungo che dà il cursore, in pixel.
WIDTHscript.js[0.9, 2]La larghezza più sottile e quella più grossa dell’inchiostro, in pixel: veloce è sottile.
SPEEDscript.js1.3La velocità del pennino, in pixel al millisecondo, alla quale l’inchiostro è più sottile.
SAGscript.js520Quanto pende il filo quando è lento: la sua gravità, in pixel al secondo al quadrato.
REWINDscript.js1Quanto è lento Undo a riavvolgere l’ultimo tratto (1 vuol dire da 0,4 a 1 secondo, secondo la lunghezza).
UNTANGLEscript.js0.85I secondi che Clear impiega a tirare dritto un tratto.

Provali nel Playground

Quando usarla

Per firmare una consegna, un contratto, un modulo di consenso o un preventivo accettato, soprattutto col dito o col mouse, che tremano; per un blocco per gli schizzi dentro un’app creativa o di appunti, dove un tratto calmo conta più di un tratto fedele.

Sul telefono

Si firma col dito senza far scorrere la pagina (touch-action none sul riquadro): dove il dito tocca arriva il pennino, e il filo si stende da lì mentre il dito si muove, così il pennino resta fuori da sotto il polpastrello e il tratto si vede mentre lo si fa. Alzando il dito il filo si riavvolge. A 390 pixel la firma dell’anteprima ha meno riccioli, per stare nel riquadro.

Con il movimento ridotto

Il pennino segue la mano col suo filo, perché è il modo di disegnare, ma il filo è sempre dritto, senza oscillare né pendere; Undo e Clear fanno sparire i tratti in dissolvenza invece di riavvolgerli e tirarli, il pennino torna a casa senza viaggiare, il riquadro compare senza disegnarsi e la parola Leash cambia larghezza senza rimbalzo.

Trappole

  • Un filo vero non si allunga ma si accorcia: i vincoli della catena riavvicinano due anelli troppo lontani e non allontanano mai due anelli vicini, o il filo lento sembrerebbe una molla.
  • Il solutore non arriva mai a un filo perfettamente dritto quando i capi sono proprio a una lunghezza di distanza: oltre il 90% di tensione il filo disegnato viene portato sulla retta, e dal 99,5% è la retta.
  • Il pennino sollevato non salta: entrando da fuori, la mano lo trascina con un piccolo ritardo (un avvicinamento esponenziale) invece di portarlo di colpo dall’altra parte del riquadro; col dito invece il pennino va subito dove il dito tocca.
  • Una firma fatta di riccioli più piccoli del filo esce con le punte: i riccioli della mano finta sono larghi più del doppio del filo, così restano riccioli anche con il filo lungo.
  • Coi tasti che arrivano più svelti della mano, i passi si sommano in una meta che si sposta, altrimenti ogni pressione ripartirebbe da metà strada e andrebbe persa.

Librerie

GSAP 3.15.0, Roboto Flex (font variabile) 5.3.0.

Compressi con gzip, i tre file della demo pesano 15 KB; le librerie: GSAP 28 KB.

Collaudo

Provata il 16 ottobre 2026

  • Computer: Fatto
  • Telefono: Fatto
  • Movimento ridotto: Fatto
  • Safari su iPhone: Da fare

Licenza d’uso

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.

Tutti i componenti