Vai al contenuto
animorio
EN
Tutti i componenti

La tendina a maglia

Menu, Transizioni, HoverCanvas, GSAPImpegnativaPeso compresso: Demo 17 KBGSAP 28 KBGratisScarica lo zip

La tendina della taglia di un maglione di merino, fatta a maglia: il campo è il collo a coste, con l'etichetta della taglia cucita sopra e un gomitolo in fondo. Aprendola, la lista viene lavorata verso il basso un ferro dopo l'altro, col filo che scende dal gomitolo; scegliendo una taglia, la sua etichetta vola nel collo e la lista si disfa dal basso, mentre il filo, ancora increspato dalle maglie, torna sul gomitolo.

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 knitted select</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/commissioner@5.3.0/index.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/brygada-1918@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the size of a merino jumper, chosen on a select that is knitted. The field is the jumper's ribbed collar, with
         the size's woven label sewn on and a ball of the same yarn at its end. Opening, the list is knitted downwards
         out of the collar; choosing, the label flies up into the collar and the list unravels back onto the ball -->
    <div class="size" data-select data-autoclic>
      <span class="size__label" id="size-label" data-label>Size</span>
      <div class="size__box" data-box>
        <div class="field" role="combobox" tabindex="0" aria-labelledby="size-label" aria-haspopup="listbox" aria-expanded="false" aria-controls="size-list" data-field>
          <canvas class="field__rib" aria-hidden="true" data-rib></canvas>
          <span class="sr" data-field-sr>M, chest 96 to 101 cm</span>
          <span class="tag field__tag" aria-hidden="true" data-field-tag><span class="tag__text" data-tag-text>M</span></span>
          <span class="field__text" aria-hidden="true" data-field-slot><span class="field__words" data-field-text>Chest 96–101 cm</span></span>
        </div>
        <!-- the knitting and the yarn, drawn by the script -->
        <canvas class="knit" aria-hidden="true" data-knit></canvas>
        <!-- the ball of yarn: the strands turn under a light that stays still -->
        <span class="ball" aria-hidden="true" data-ball>
          <svg viewBox="-18 -18 36 36">
            <defs>
              <clipPath id="knit-ball-clip"><circle r="15.2"/></clipPath>
              <radialGradient id="knit-ball-light" cx="0.36" cy="0.3" r="0.78">
                <stop offset="0" stop-color="#fff" stop-opacity="0.34"/>
                <stop offset="0.4" stop-color="#fff" stop-opacity="0"/>
                <stop offset="0.7" stop-color="#000" stop-opacity="0.08"/>
                <stop offset="1" stop-color="#000" stop-opacity="0.6"/>
              </radialGradient>
            </defs>
            <circle class="ball__core" r="15.2"/>
            <g clip-path="url(#knit-ball-clip)">
              <g class="ball__turn" data-ball-turn></g>
            </g>
            <circle r="15.2" fill="url(#knit-ball-light)"/>
            <circle class="ball__rim" r="15.2"/>
            <path class="ball__tail" d="M8.6 12.4c2.8 2.6 1.4 4.6 3.8 5.6" data-ball-tail/>
          </svg>
        </span>
        <ul class="list" role="listbox" id="size-list" aria-labelledby="size-label" tabindex="-1" data-list>
          <li class="opt" role="option" id="size-xs" aria-selected="false" aria-disabled="true" aria-label="XS, chest 86 to 91 cm, sold out" data-say="XS, chest 86 to 91 cm">
            <span class="tag" data-tag><span class="tag__text" data-tag-text>XS</span></span>
            <span class="opt__text"><span class="opt__chest" data-chest>Chest 86–91 cm</span><span class="opt__note">Sold out</span></span>
            <svg class="opt__check" viewBox="0 0 16 16" aria-hidden="true"><path d="M3.2 8.7l3.1 3 6.5-7.2"/></svg>
          </li>
          <li class="opt" role="option" id="size-s" aria-selected="false" aria-label="S, chest 91 to 96 cm" data-say="S, chest 91 to 96 cm">
            <span class="tag" data-tag><span class="tag__text" data-tag-text>S</span></span>
            <span class="opt__text"><span class="opt__chest" data-chest>Chest 91–96 cm</span></span>
            <svg class="opt__check" viewBox="0 0 16 16" aria-hidden="true"><path d="M3.2 8.7l3.1 3 6.5-7.2"/></svg>
          </li>
          <li class="opt" role="option" id="size-m" aria-selected="true" aria-label="M, chest 96 to 101 cm" data-say="M, chest 96 to 101 cm">
            <span class="tag" data-tag><span class="tag__text" data-tag-text>M</span></span>
            <span class="opt__text"><span class="opt__chest" data-chest>Chest 96–101 cm</span></span>
            <svg class="opt__check" viewBox="0 0 16 16" aria-hidden="true"><path d="M3.2 8.7l3.1 3 6.5-7.2"/></svg>
          </li>
          <li class="opt" role="option" id="size-l" aria-selected="false" aria-label="L, chest 101 to 106 cm, only 2 left" data-say="L, chest 101 to 106 cm">
            <span class="tag" data-tag><span class="tag__text" data-tag-text>L</span></span>
            <span class="opt__text"><span class="opt__chest" data-chest>Chest 101–106 cm</span><span class="opt__note opt__note--low">Only 2 left</span></span>
            <svg class="opt__check" viewBox="0 0 16 16" aria-hidden="true"><path d="M3.2 8.7l3.1 3 6.5-7.2"/></svg>
          </li>
          <li class="opt" role="option" id="size-xl" aria-selected="false" aria-disabled="true" aria-label="XL, chest 106 to 111 cm, sold out" data-say="XL, chest 106 to 111 cm">
            <span class="tag" data-tag><span class="tag__text" data-tag-text>XL</span></span>
            <span class="opt__text"><span class="opt__chest" data-chest>Chest 106–111 cm</span><span class="opt__note">Sold out</span></span>
            <svg class="opt__check" viewBox="0 0 16 16" aria-hidden="true"><path d="M3.2 8.7l3.1 3 6.5-7.2"/></svg>
          </li>
          <li class="opt" role="option" id="size-xxl" aria-selected="false" aria-label="XXL, chest 111 to 116 cm, made to order in 2 weeks" data-say="XXL, chest 111 to 116 cm">
            <span class="tag" data-tag><span class="tag__text" data-tag-text>XXL</span></span>
            <span class="opt__text"><span class="opt__chest" data-chest>Chest 111–116 cm</span><span class="opt__note">Made to order, 2 weeks</span></span>
            <svg class="opt__check" viewBox="0 0 16 16" aria-hidden="true"><path d="M3.2 8.7l3.1 3 6.5-7.2"/></svg>
          </li>
        </ul>
      </div>
    </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>

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.

36 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 «La tendina a maglia» da Animorio e adattala al mio sito

Cosa fa

Su una pagina bianca, sotto la scritta Size, c'è il campo di una tendina alto 60 pixel: è il collo a coste di un maglione di merino verde loden, con le coste in rilievo, cucito sopra un'etichetta tessuta color crema con la taglia (M) e accanto, stampata sulla lana, la misura del torace (Chest 96–101 cm); in fondo a destra c'è un gomitolo dello stesso filato. Premendo il campo, sotto il collo viene lavorata la lista: un ferro dopo l'altro, avanti e indietro, la maglia rasata cresce verso il basso, il filo scende dal gomitolo lungo il bordo destro fino al ferro in lavorazione e il gomitolo gira e si assottiglia un poco. Ogni riga della lista, con la sua etichetta e le sue parole, compare quando la maglia è arrivata sotto di lei: sei taglie, da XS a XXL, con la misura del torace e, dove serve, una nota (Sold out, Only 2 left, Made to order, 2 weeks); in fondo la lista si chiude con il bordo della chiusura. La riga sotto il puntatore o i tasti prende la luce, come se la maglia si sollevasse, e la sua etichetta si stacca un poco dalla lana; la luce va da una riga all'altra su una molla. La taglia scelta ha la sua spunta. Le taglie esaurite hanno l'etichetta sbiadita, non si possono scegliere e toccate scuotono l'etichetta. Scegliendo una taglia, le altre etichette vengono scucite all'istante e quella scelta vola nella loro colonna fino al collo, ondeggiando e alzandosi un poco, mentre la vecchia viene staccata; arrivata, si posa con un piccolo rimbalzo e le sue cuciture compaiono, e la misura del torace scorre nella sua fessura. Intanto la lista si disfa dal basso, un ferro dopo l'altro: il filo esce dalle maglie ancora increspato, pende un poco sotto il bordo, risale lungo il lato e torna sul gomitolo, che gira all'indietro e si rifà grosso; le parole di ogni riga svaniscono man mano che il bordo arriva. Si apre e si chiude anche con la tastiera e scrivendo le prime lettere di una taglia.

Come funziona

Il punto disegnato

Ogni maglia è una V di due gambe di filato. Una gamba è un fagiolo inclinato di circa 26 gradi, sfumato come un cilindro: per undici punti lungo la sua larghezza si calcola quanto la superficie guarda la luce, che viene dall'alto a sinistra, e ne esce un gradiente; poi le estremità scure dove entra nel tessuto, i solchi diagonali dei capi ritorti, qualche fibra più chiara o più scura e due peli. Quattordici maglie diverse si disegnano una volta sola e si stampano a caso in una striscia per ogni ferro (un canvas fuori schermo); il collo a coste è fatto allo stesso modo, con colonne più strette e quelle a rovescio incassate fra loro.

Un numero per lavorare e disfare

Tutta la lista dipende da un numero, i ferri lavorati. A ogni fotogramma si disegnano le strisce dei ferri finiti, poi quello sui ferri tagliato fino alla maglia raggiunta (avanti nei ferri pari, indietro nei dispari) e alla fine il bordo della chiusura. GSAP porta il numero su e giù: lavorando parte subito e rallenta sull'ultimo ferro (KNIT), disfacendo parte con un tiro costante e accelera (UNRAVEL); riaprendo mentre si disfa, la maglia riprende a crescere da dove è arrivata.

Il filo

Il filo è un percorso: dal ferro lungo il bordo, una curva sull'angolo, su per il lato fino al gomitolo, campionato ogni pixel e mezzo. Ogni punto viene spinto di lato dalle increspature, una sinusoide con un'ampiezza irregolare che viaggia col filo; disfacendo sono grandi vicino al bordo e si spianano salendo, dove il filo è tirato, e il tratto sotto il bordo pende un poco. Sopra si disegnano i solchi obliqui della torsione, che scorrono col filo; il gomitolo gira con i ferri e si assottiglia mentre si svolge.

L'etichetta che vola

Scegliendo, una copia dell'etichetta parte dalla sua riga e arriva al collo su una curva, con un'oscillazione e un'ombra che cresce mentre si alza; la vecchia viene staccata prima che arrivi. Le altre etichette spariscono subito, così quella che vola non copre niente; le parole delle righe invece restano finché il bordo non le raggiunge, con un'opacità che dipende da quanto è ancora lontano. La misura sul collo cambia in una fessura alta una riga: la vecchia esce in alto mentre la nuova entra dal basso, sempre una riga più in là.

Una tendina vera

Il campo è un combobox con aria-expanded, aria-controls e aria-activedescendant, la lista un listbox di option con aria-selected e aria-disabled per le taglie esaurite. Frecce, Home, End, Pagina su e giù muovono la riga attiva saltando le esaurite; Invio, Spazio e Alt + freccia su scelgono, Tab sceglie e passa oltre, Esc chiude; le lettere scritte di seguito cercano la taglia che comincia così. Un mousedown fermato sulla lista lascia il focus al campo; un tocco fuori, o il focus che se ne va, chiude.

Valori da cambiare

NomeFileDi partenzaCosa cambia
KNITscript.js0.5I secondi che la lista impiega a essere lavorata, dal collo al bordo in fondo.
UNRAVELscript.js0.75I secondi che impiega a disfarsi e a tornare sul gomitolo.
GAUGEscript.js[14, 10.5]La misura di una maglia in pixel: la sua larghezza e l'altezza di un ferro.
CRINKLEscript.js3.2Quanto resta ondulato il filo disfatto, in pixel: la memoria delle maglie.
LIGHTscript.js[420, 0.62]La luce sulla riga sotto il puntatore: la rigidezza della sua molla e quanto è frenata.
FLIGHTscript.js0.55I secondi del volo dell'etichetta scelta fino al collo.
TYPINGscript.js0.6I secondi che una ricerca scritta aspetta la lettera dopo.

Provali nel Playground

Quando usarla

Per scegliere un'opzione in un negozio di cose fatte a mano o di tessuti: le taglie di un maglione, il filato, il peso di una coperta. Va bene da quattro a otto opzioni brevi, che stanno tutte nella lista senza scorrere; con tante opzioni (un paese, un fuso orario) serve una tendina con la ricerca.

Sul telefono

A 390 pixel il campo è largo quanto lo schermo meno 32 pixel e la maglia si ridisegna sulla nuova misura, con le maglie della stessa grandezza. Col tocco si apre e si sceglie; senza puntatore la luce sta sulla taglia scelta e si sposta sulla riga appena toccata.

Con il movimento ridotto

Niente lavorazione, niente filo che corre ed etichetta che vola: la lista già lavorata compare e scompare in dissolvenza, l'etichetta e la misura del collo cambiano in dissolvenza, la luce va subito sulla riga, il gomitolo non gira e una taglia esaurita toccata sbiadisce un attimo invece di scuotersi.

Trappole

  • La V di una maglia è fatta di due gambe sovrapposte ai ferri vicini: per tagliare la lista a un ferro senza tagliare le maglie, ogni ferro sta in una striscia sua, alta due ferri, e si disegnano strisce intere.
  • I fromTo di GSAP disegnano subito il loro inizio: la misura del collo spariva per tutto il volo dell'etichetta e poi tornava quella vecchia. Il cambio si prepara in una call e i tween partono con to.
  • Con una dissolvenza a tempo le parole delle righe non stavano dietro al bordo che accelera disfacendosi, e un'etichetta restava a mezz'aria sotto la maglia: ora l'opacità di ogni riga dipende dalla distanza del bordo.
  • power2.in di GSAP è una cubica: il filo partiva così piano che per metà del tempo la lista sembrava ferma. Per disfare c'è una curva fatta apposta, un terzo lineare e due terzi quadratica.
  • Se le increspature del filo corrono più di mezza onda per fotogramma, sembrano andare all'indietro come le ruote nei film: il filo si sposta di pochi pixel per ferro, non della sua lunghezza vera.
  • La transizione della comparsa delle righe (opacity, translate) ha la stessa specificità di quella dell'etichetta (transform) e la cancellava: per l'etichetta di una riga le transizioni sono scritte tutte insieme.

Librerie

GSAP 3.15.0, Commissioner (font variabile) 5.3.0, Brygada 1918 (font variabile) 5.3.0.

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

Collaudo

Provata il 6 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