Vai al contenuto
animorio
EN
Tutti i componenti

I filtri che salgono in riga

Etichette, Transizioni, TestoGSAP, Solo CSSImpegnativaPeso compresso: Demo 12 KBGSAP 28 KBGratisScarica lo zip

Nello stile minimal: i filtri di un ricettario scritti come parole leggere su righe sottili. Scegliendone una, la parola sale lungo una curva fino alla riga in alto, sopra un filetto nero, prende peso e si disegna una piccola croce vermiglia; le altre chiudono il vuoto una dopo l'altra, e quelle che cambiano riga escono da un capo della loro e rientrano dall'altro capo della successiva, come un testo che si ricompone. Sotto, il numero delle ricette che restano cambia cifra per cifra.

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 filters that rise into line</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/bricolage-grotesque@5.3.0/standard.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the filters of a recipe book, set as words on ruled lines. Choosing one, it rises into the top line, takes
         weight and gets a small cross to take it away; the words after it close the gap, and the ones that change
         line run out at one end of their line and come in at the other end of the next, like type reflowing. The
         buttons are real and stay in the layout; the words you see are drawn over them by the script, so they can
         travel. The filters are made by the script from its list -->
    <div class="pantry" data-pantry data-autoclic>
      <div class="sheet" data-sheet>
        <div class="rules" aria-hidden="true" data-rules></div>
        <span class="rule-ink" aria-hidden="true" data-rule-ink></span>
        <p class="hint" aria-hidden="true" data-hint>Pick what you fancy</p>
        <div class="picked" role="group" aria-label="Chosen filters" data-picked></div>
        <div class="rest" role="group" aria-label="Filter the recipes" data-rest></div>
        <div class="ink" aria-hidden="true" data-ink></div>
      </div>
      <div class="foot">
        <button class="clear" type="button" aria-disabled="true" data-clear>Clear</button>
        <p class="count" aria-hidden="true"><span class="count__n" data-count></span> <span class="count__noun" data-noun>recipes</span></p>
        <p class="sr" aria-live="polite" data-live></p>
      </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.

32 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 «I filtri che salgono in riga» da Animorio e adattala al mio sito

Cosa fa

Su un fondo bianco, nove parole su righe sottili color sabbia, sottili e un poco strette: Vegan, Gluten-free, One pot, Spicy, Vegetarian, Dairy-free, No oven, Batch cook, High protein. In alto, sopra un filetto nero, la riga delle scelte, dove all'apertura c'è già Weeknight, nera e piena, con la sua croce vermiglia; in fondo Clear a sinistra e, a destra, 83 recipes. All'apertura le righe si disegnano da sinistra una dopo l'altra e le parole salgono sulle loro righe. Scegliendo una parola, questa si alza dritta fino al filetto nero, ci corre sopra fino al suo posto nella riga in alto e ci sale, mentre prende peso e larghezza con un piccolo eccesso che si assesta; correndo si stringe un poco sull'asse della larghezza. Appena arriva, dietro di lei si disegna la croce, un tratto dopo l'altro. Le parole che venivano dopo di lei chiudono il vuoto una dopo l'altra, partendo dalla più vicina; quelle che devono cambiare riga escono dal capo della loro riga, sfumando oltre la fine del filetto, ed entrano dall'altro capo della riga accanto. Se la riga delle scelte si riempie ne apre un'altra: il filetto nero scende di una riga e le parole sotto scendono tutte insieme. Toccando di nuovo una parola scelta, la croce si ritira e la parola torna al suo posto fra le altre per la stessa strada, perdendo peso, mentre le righe le fanno spazio partendo dalla fine. Il numero delle ricette cambia cifra per cifra, da destra: le cifre nuove cadono dall'alto se le ricette diminuiscono e salgono dal basso se aumentano, arrivano color vermiglio e diventano nere. Con nessuna scelta la riga in alto dice Pick what you fancy e Clear si spegne; Clear rimanda tutte le scelte al loro posto, l'ultima per prima. Col puntatore sopra una parola delle righe, questa si alza di due pixel e prende un po' di peso; sopra una scelta perde un po' di peso, come per lasciarla andare.

Come funziona

Pulsanti veri, parole disegnate sopra

Ogni filtro è un button con aria-pressed, in due role="group": le scelte in alto, nell'ordine in cui sono state fatte, e le altre nell'ordine della lista. Scegliendo, il pulsante passa davvero da un gruppo all'altro (e il fuoco gli viene rimesso), con lo stile del suo posto: così il layout, con flex-wrap, dice dove deve stare ogni parola. I pulsanti hanno il testo trasparente; quello che si vede è una copia di ogni parola in uno strato sopra, mossa dallo script, con l'anello della tastiera che viaggia con lei.

Molle verso il posto del layout

A ogni cambio lo script misura dove sono finiti i pulsanti (getBoundingClientRect, una volta sola) e ogni parola disegnata raggiunge il suo posto su una molla smorzata (SPRING), integrata sul ticker di GSAP a passi di un quarto di fotogramma, con il passo limitato a 1/30 di secondo. Peso e larghezza seguono un'altra molla più morbida, da WEIGHT[0] a WEIGHT[1] e da WIDTH[0] a WIDTH[1], che va oltre di poco e si assesta; la velocità toglie larghezza (SQUEEZE). Un cambio a metà è solo un posto nuovo da raggiungere. Quando niente si muove il ticker si ferma.

Il volo lungo il filetto

Una parola che cambia gruppo vola su una curva di Bézier cubica: i due punti di controllo stanno sulla verticale di partenza e su quella d'arrivo, all'altezza del filetto nero. Così parte dritta in su (o in giù), corre lungo il filetto con il testo appoggiato sopra, senza passare sulle parole della riga in alto, e arriva dritta al suo posto. Quanto è avanti sulla curva lo dice una molla (FLIGHT); oltre la fine la curva prosegue lungo la tangente, quindi l'eccesso è di un pixel, in verticale.

Le righe che si ricompongono

Una parola che resta nel suo gruppo ma cambia riga non attraversa le altre: la sua copia esce dal capo della riga in cui era (un fantasma clonato, che poi si toglie) e la parola rientra dall'altro capo della riga nuova. Una maschera a gradiente, calcolata in pixel nel sistema della parola, la fa sfumare nei 16 pixel oltre la fine del filetto. La riga conta dall'inizio del suo gruppo, quindi quando la riga delle scelte ne apre un'altra le parole sotto scendono tutte insieme, col filetto nero, invece di ricomporsi.

Una coreografia che non si scontra

Il ritardo di ogni parola (RIPPLE) dipende dalla direzione: chi chiude un vuoto parte dal vuoto in avanti, dopo un decimo di secondo che lascia andare via la parola scelta; chi fa spazio parte dalla fine all'indietro. Così nessuna parola raggiunge quella davanti. Con Clear le scelte tornano una dopo l'altra, l'ultima per prima. Il conteggio sta in finestrelle larghe una cifra tabellare: la cifra vecchia e quella nuova scorrono insieme sulla stessa molla, la nuova in vermiglio che sfuma nel nero; una cifra che manca chiude la sua finestrella.

Tastiera, movimento ridotto e anteprima

Tab, Invio e Spazio funzionano come sempre, e una regione aria-live dice cosa è cambiato e quante ricette restano. Col movimento ridotto le parole che cambiano posto si dissolvono e ricompaiono già al loro posto, le cifre in dissolvenza. Un clic da script sul componente (detail 0, l'anteprima della libreria) fa un giro: sceglie Vegetarian, Spicy e One pot, toglie Weeknight, svuota tutto con Clear e rimette Weeknight, tornando com'era.

Valori da cambiare

NomeFileDi partenzaCosa cambia
FILTERSscript.js['Vegan', 'Weeknight', 'Gluten-free', …]I filtri, nel loro ordine sulle righe (i nomi che il ricettario dell'esempio non conosce hanno ricette a caso).
STARTscript.js['Weeknight']I filtri già scelti all'apertura della pagina.
RECIPESscript.js186Quante ricette ha il ricettario dell'esempio.
NOUNscript.js['recipe', 'recipes']Che cosa si conta, al singolare e al plurale.
SPRINGscript.js[240, 0.8]Le molle su cui viaggiano le parole: quanto sono rigide e quanto sono frenate (1 arriva senza eccesso).
FLIGHTscript.js0.4Quanto è veloce il volo fra le righe e la riga in alto, rispetto alle altre molle.
RIPPLEscript.js0.035I secondi fra una parola che si muove e la successiva.
WEIGHTscript.js[330, 640]Il peso delle parole sulle righe e di quelle scelte (da 200 a 800).
WIDTHscript.js[90, 100]L'asse della larghezza delle parole sulle righe e di quelle scelte (da 75 a 100).
SQUEEZEscript.js12Quanto si stringe sull'asse della larghezza una parola che corre.

Provali nel Playground

Quando usarla

Per i filtri che si sommano sopra un elenco: le ricette di un blog di cucina, i prodotti di un negozio, gli alloggi di un sito di viaggi, i corsi di una scuola. Dove le scelte devono stare in vista tutte insieme, con il numero dei risultati che restano, e togliere una scelta deve essere facile come metterla.

Sul telefono

A 390 pixel le righe sono più alte (44 pixel, buone per il dito) e le parole vanno su tre righe; la riga delle scelte ne apre una seconda quando si riempie e le righe sotto scendono insieme, quindi il componente resta alto uguale. Un tocco sceglie e toglie, e premendo la parola si stringe appena; il passaggio del puntatore lì non c'è.

Con il movimento ridotto

Niente vola e niente scorre: le parole che cambiano posto si dissolvono e ricompaiono già al loro posto, col peso giusto e la croce già disegnata; il numero cambia in dissolvenza e le righe sono già disegnate all'apertura.

Trappole

  • Il primo volo era una molla dritta verso il posto nuovo: la y arrivava prima della x e la parola passava sopra la croce della scelta accanto. Ora vola su una curva di Bézier che sale dritta e corre lungo il filetto nero, sotto le parole della riga in alto.
  • Le parole che cambiavano riga facevano una diagonale sopra le altre: ora escono da un capo della riga e rientrano dall'altro, con una copia fantasma che esce e una maschera che le sfuma oltre la fine del filetto.
  • Quando la riga delle scelte apriva una seconda riga, tutte le parole sotto risultavano su una riga nuova e si ricomponevano tutte insieme in un groviglio: la riga ora si conta dall'inizio del suo gruppo, quindi scendono soltanto, tutte insieme, e il fantasma di chi cambia riga scende con loro.
  • Col ritardo a onda sempre dal punto del cambio, le parole che facevano spazio partivano prima di quella davanti e la raggiungevano: ora chi va avanti parte dalla fine.
  • Nel contatore la cifra vecchia e quella nuova avevano tempi diversi e per un attimo si sovrapponevano: ora scorrono sulla stessa molla, a una distanza più alta della finestrella, che è sfumata in alto e in basso.
  • La Q di Bricolage Grotesque, con la coda lunga sotto la riga, a questa misura sembrava una parola sottolineata: il filtro Quick è diventato Weeknight.

Librerie

GSAP 3.15.0, Bricolage Grotesque (font variabile, con gli assi del peso, della larghezza e della grandezza ottica) 5.3.0.

Compressi con gzip, i tre file della demo pesano 12 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