Vai al contenuto
animorio
EN
Tutti i componenti

La barra laterale che si arriccia

Navigazione, SVG, Testo, Fisica, TransizioniGSAPImpegnativaPeso compresso: Demo 14 KBGSAP 28 KBGratisScarica lo zip

La barra laterale di un'app per un vivaio, dove niente scivola e niente svanisce: tutto si arrotola e si srotola come le foglie delle felci. I nomi si avvolgono lettera per lettera in una spirale sempre più stretta, l'evidenziazione si srotola fuori dall'icona della pagina scelta con la punta ancora arricciata, la riga delle serre scende srotolandosi e ogni serra srotola il suo nome quando la riga ci arriva; piegando la barra ogni nome si arrotola dentro la sua icona.

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 curling sidebar</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/commissioner@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the sidebar of a plant nursery's desktop app. Nothing in it slides or fades: the names, the highlight under
         the page chosen and the line of the greenhouses roll up and unroll like the fronds of a fern. The script
         draws the moving parts (the letters, the highlight, the line) on the two layers of the body; the names in the
         rows stay for screen readers -->
    <div class="fr-wrap" data-wrap>
      <nav class="fr" aria-label="Nursery" data-nav data-autoclic>
        <div class="fr__head">
          <button class="fr__toggle" type="button" aria-expanded="true" aria-controls="fr-list" aria-label="Collapse sidebar" data-toggle>
            <svg viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="4.5" width="18" height="15" rx="3.2"/><path d="M9 4.5V19.5"/><path class="fr__toggle-chev" d="M15.6 9.6L13.2 12L15.6 14.4"/></svg>
          </button>
        </div>
        <div class="fr__body" data-body>
          <!-- under the rows: the highlights and the line of the greenhouses -->
          <svg class="fr__ground" aria-hidden="true" data-ground>
            <defs>
              <linearGradient id="fr-frond" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="236" y2="0">
                <stop class="fr__stop-base" offset="0"/>
                <stop class="fr__stop-tip" offset="1"/>
              </linearGradient>
              <clipPath id="fr-clip-ground"><rect data-clip/></clipPath>
            </defs>
            <g data-ribbons></g>
            <g clip-path="url(#fr-clip-ground)" data-ribbons-sub></g>
            <path class="fr__guide" d="M0 0" data-guide/>
          </svg>

          <ul class="fr__list" id="fr-list">
            <li><a class="fr__item" href="#" data-item>
              <svg class="fr__icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="3.9"/><path d="M12 2.8V4.9M12 19.1V21.2M2.8 12H4.9M19.1 12H21.2M5.5 5.5L7 7M17 17L18.5 18.5M5.5 18.5L7 17M17 7L18.5 5.5"/></svg>
              <span class="fr__label" data-label>Today</span></a></li>
            <li><a class="fr__item" href="#" aria-current="page" data-item>
              <svg class="fr__icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M6.8 14.2H17.2L16 20.2C15.9 20.7 15.5 21 15 21H9C8.5 21 8.1 20.7 8 20.2Z"/><path d="M12 14.2V9.6"/><path d="M12 11.2C12 7.9 9.9 5.9 6.4 5.9C6.4 9.2 8.5 11.2 12 11.2Z"/><path d="M12 9.6C12 6.6 13.9 4.5 17.4 4.5C17.4 7.6 15.4 9.6 12 9.6Z"/></svg>
              <span class="fr__label" data-label>Plants</span></a></li>
            <li class="fr__group">
              <button class="fr__item fr__item--parent" type="button" aria-expanded="true" aria-controls="fr-houses" data-item data-parent>
                <svg class="fr__icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M3.6 20.4V10.8L12 4.2L20.4 10.8V20.4Z"/><path d="M12 4.2V20.4M3.6 14.8H20.4M7.8 7.5V20.4M16.2 7.5V20.4"/></svg>
                <span class="fr__label" data-label>Greenhouses</span>
              </button>
              <ul class="fr__sub" id="fr-houses" data-sub>
                <li><a class="fr__item fr__item--child" href="#" data-item><span class="fr__label" data-label>North house</span></a></li>
                <li><a class="fr__item fr__item--child" href="#" data-item><span class="fr__label" data-label>Propagation</span></a></li>
                <li><a class="fr__item fr__item--child" href="#" data-item><span class="fr__label" data-label>Shade tunnel</span></a></li>
              </ul>
            </li>
            <li><a class="fr__item" href="#" data-item>
              <svg class="fr__icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M4.4 10.2H12.8V18.4C12.8 19.6 11.8 20.6 10.6 20.6H6.6C5.4 20.6 4.4 19.6 4.4 18.4Z"/><path d="M5.8 10.2C5.8 5.4 11.4 5.4 11.4 10.2"/><path d="M12.8 15.6L19 10"/><path d="M17.8 8.6L20.4 11.4"/></svg>
              <span class="fr__label" data-label>Watering</span>
              <span class="fr__count" data-count>3<span> plants to water</span></span></a></li>
            <li><a class="fr__item" href="#" data-item>
              <svg class="fr__icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 3.6L20 7.6V16.4L12 20.4L4 16.4V7.6Z"/><path d="M4 7.6L12 11.6L20 7.6M12 11.6V20.4M8 5.6L16 9.6"/></svg>
              <span class="fr__label" data-label>Orders</span></a></li>
            <li><a class="fr__item" href="#" data-item>
              <svg class="fr__icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M6.6 3.6H17.4C18.4 3.6 19.2 4.4 19.2 5.4V18.6C19.2 19.6 18.4 20.4 17.4 20.4H6.6C5.6 20.4 4.8 19.6 4.8 18.6V5.4C4.8 4.4 5.6 3.6 6.6 3.6Z"/><path d="M8.6 3.6V20.4"/><path d="M12.4 8.2H16M12.4 11.4H15"/></svg>
              <span class="fr__label" data-label>Journal</span></a></li>
          </ul>

          <ul class="fr__list fr__list--foot">
            <li><a class="fr__item" href="#" data-item>
              <svg class="fr__icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M4 7.5H8.2M13 7.5H20M4 16.5H11M15.8 16.5H20"/><path d="M10.6 5.2C11.9 5.2 13 6.2 13 7.5S11.9 9.8 10.6 9.8 8.2 8.8 8.2 7.5 9.3 5.2 10.6 5.2Z"/><path d="M13.4 14.2C14.7 14.2 15.8 15.2 15.8 16.5S14.7 18.8 13.4 18.8 11 17.8 11 16.5 12.1 14.2 13.4 14.2Z"/></svg>
              <span class="fr__label" data-label>Settings</span></a></li>
          </ul>

          <!-- over the rows: the letters, the count and the arrow of the greenhouses -->
          <svg class="fr__ink" aria-hidden="true" data-ink>
            <defs><clipPath id="fr-clip-ink"><rect data-clip/></clipPath></defs>
            <g data-words></g>
            <g clip-path="url(#fr-clip-ink)" data-words-sub></g>
          </svg>
        </div>
      </nav>
      <!-- the name of an icon, beside the folded bar -->
      <svg class="fr__tags" aria-hidden="true" data-tags></svg>
    </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.

34 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 barra laterale che si arriccia» da Animorio e adattala al mio sito

Cosa fa

Su un fondo bianco, da sola al centro, la barra laterale chiara di un'app per un vivaio, alta 520 pixel e larga 256, color vetro appannato con un bordo verde grigio e un'ombra morbida. In cima il pulsante per stringerla, poi Today, Plants, Greenhouses con le sue tre serre (North house, Propagation, Shade tunnel) appese a una riga sottile, Watering con un 3 blu (le piante da annaffiare), Orders e Journal; in fondo Settings. Ogni voce ha la sua icona disegnata: un sole, una piantina nel vaso, una serra, un annaffiatoio, una cassa, un quaderno, dei cursori. Sotto la pagina scelta c'è una pillola verde che schiarisce verso destra, come la crescita nuova di una foglia. All'arrivo i nomi si srotolano uno dopo l'altro dall'alto: ognuno parte avvolto in una piccola spirale accanto alla sua icona, si distende lettera per lettera e alla fine la punta scatta un poco oltre il dritto prima di fermarsi; la riga delle serre scende srotolandosi come il germoglio di una felce, e ogni serra srotola il suo nome quando la riga arriva alla sua altezza. Scegliendo un'altra pagina la pillola verde si arrotola all'indietro dentro la sua icona, con la punta che si assottiglia in un gambo e si avvolge, mentre una pillola nuova si srotola fuori dall'icona della pagina scelta, con la punta ancora arricciata che si apre per ultima; l'icona fa un piccolo salto. Col mouse sopra una voce si srotola una pillola grigia fino a poco oltre il nome e resta lì con la punta arricciata, come una felce che non si è ancora aperta del tutto; scegliendo quella voce, la pillola grigia si srotola fino in fondo e diventa verde. Greenhouses apre e chiude le sue serre: chiudendo, i nomi delle serre si arrotolano dal basso e la riga risale avvolgendosi nella sua icona, mentre le voci sotto risalgono; se la pagina scelta era una serra, la pillola passa su Greenhouses. Il pulsante in cima piega la barra: ogni nome si arrotola nella sua icona, una riga dopo l'altra, il 3 e la freccia di Greenhouses entrano per primi nella spirale, la barra si stringe insieme alle spirali fino alle sole icone e la pillola verde resta come un bocciolo intorno all'icona della pagina scelta; il 3 salta sull'angolo dell'annaffiatoio. Da piegata, puntando un'icona (o arrivandoci col Tab) il suo nome si srotola accanto alla barra in un'etichetta scura; riaperta, i nomi si srotolano di nuovo dall'alto.

Come funziona

Una striscia con la spirale in punta

Ogni parte che si muove (un nome, la pillola, la riga delle serre, l'etichetta) è una striscia lunga L con un fronte f. Lungo la striscia u è una lunghezza di nome: fino al fronte è dritta e a grandezza piena; oltre il fronte gira di 1/COIL radianti per ogni pixel di nome mentre la grandezza cala come 2^(−(u − f)/TIGHT), e il passo lungo la curva è la grandezza per du. Così il raggio cala insieme alle lettere e la punta è una spirale logaritmica, il germoglio di una felce, con le lettere strette fino in fondo. I punti si sommano dall'inizio, a passi di 2 pixel col giro e la grandezza presi a metà passo, solo nei fotogrammi in cui la striscia si muove.

Il fronte su una molla

Il fronte si muove con c, da 0 (dritta) a 1 (tutta nella spirale): f = L·(1 − c). Srotolando, c segue una molla smorzata in modo che superi lo zero di FLICK (lo smorzamento viene da −ln FLICK / √(π² + ln² FLICK)) e mentre c è sotto zero l'ultimo tratto si piega dall'altra parte: la punta scatta. Arrotolando la molla è smorzata del tutto e si ferma sulla spirale; negli ultimi centesimi la spirale si stringe nel fronte e sparisce. La molla fa quattro passi per fotogramma, col fotogramma limitato a 1/30 di secondo, e si ferma quando il fronte è a meno di un ventesimo di pixel.

Le lettere sulla curva

Ogni nome viene diviso in lettere SVG misurate con un canvas sullo stesso carattere (la larghezza di ogni prefisso, così la crenatura resta), e ogni lettera sta sulla striscia dove cade il suo centro: traslata nel punto, girata con la curva e grande quanto la spirale lì. Il 3 e la freccia di Greenhouses sono le ultime lettere della loro striscia, che corre fino in fondo alla riga: entrano per primi nella spirale e svaniscono presto, prima di diventare puntini. I nomi veri restano nelle righe, nascosti alla vista, per i lettori di schermo.

La pillola e il bocciolo

L'evidenziazione è una striscia larga disegnata come una fascia: piena fino al fronte, poi si arrotonda come la testa di una pillola fino a un gambo sottile che si arrotola e si stringe con la spirale; il gambo comincia a girare solo alla fine della testa. Una ne serve per la pagina scelta e una per la voce sotto il mouse, che si ferma a PEEK pixel oltre il nome; quelle lasciate si arrotolano, rimpiccioliscono dalla radice e vengono buttate. Da piegata, il fronte si ferma a 4 pixel: resta la testa tonda, un bocciolo intorno all'icona.

Le serre e la barra che si stringe

La riga delle serre è una striscia che scende dall'icona e si arrotola verso destra; la sezione è alta quanto la riga è srotolata, e un nome di serra si srotola quando il fronte della riga passa la sua altezza. Le serre nascoste sono inert. Piegando, i nomi si arrotolano dall'alto con STAGGER secondi fra uno e l'altro (quelli col 3 o la freccia un poco prima, perché hanno il tratto vuoto da attraversare) e a ogni fotogramma la barra è larga quanto il punto più a destra ancora srotolato; riaprendo, la larghezza torna su una molla e i nomi si srotolano dietro.

Tasti, etichette e anteprima

Le pagine sono link con aria-current, Greenhouses è un pulsante con aria-expanded e aria-controls, il pulsante in cima ha aria-expanded e dice Collapse o Expand sidebar; tutto va col Tab e ha l'anello verde del fuoco. Da piegata, il mouse o il Tab su un'icona srotolano il suo nome in un'etichetta scura accanto alla barra (con un tocco resta 1,3 secondi), Esc la richiude. Un clic da script sulla barra (l'anteprima della libreria) fa il passo dopo di un giro: Watering, Propagation, chiude le serre, piega, Journal col suo nome, riapre, riapre le serre, Plants.

Valori da cambiare

NomeFileDi partenzaCosa cambia
UNFURLscript.js0.6I secondi in cui un nome si srotola, fino allo scatto della punta.
CURLscript.js0.42I secondi in cui un nome si arrotola.
STAGGERscript.js0.04I secondi fra una riga e la successiva quando la barra si piega o si apre.
COILscript.js9Il raggio del giro esterno della spirale, in pixel.
TIGHTscript.js30In quanti pixel di nome la spirale diventa grande la metà: di meno, si chiude prima.
FLICKscript.js0.18Quanto la punta scatta oltre il dritto srotolandosi (0: si ferma e basta).
PEEKscript.js10Fin dove si srotola la pillola grigia di una voce sotto il mouse, in pixel oltre il nome (0: niente).

Provali nel Playground

Quando usarla

Per la barra di un'app da scrivania con un carattere: un vivaio o un'app per le piante, un diario, uno strumento creativo, un'app per la casa o per l'orto, il pannello di un negozio che vuole una firma riconoscibile.

Sul telefono

La barra è larga 256 pixel aperta e 64 piegata, alta 520: a 390 pixel sta intera nello schermo. Senza hover non c'è la pillola grigia; da piegata, un tocco su un'icona sceglie la pagina e srotola il suo nome per 1,3 secondi.

Con il movimento ridotto

Niente si arrotola: i nomi, la riga delle serre e le etichette compaiono e spariscono con una dissolvenza, la pillola passa da una voce all'altra dissolvendosi, la sezione delle serre si apre di colpo e la barra si stringe solo quando i nomi sono spariti, con la pillola che diventa il bocciolo; all'arrivo è tutto già al suo posto.

Trappole

  • Con la curvatura che cresceva lungo la curva ma le lettere al loro passo di sempre, nella spirale le lettere diventavano puntini staccati fra loro. La spirale giusta si fa nella lunghezza del nome: il giro per pixel di nome è costante e il passo lungo la curva cala con la grandezza, così le lettere restano strette e il raggio cala con loro.
  • Una fascia larga 36 pixel non può avvolgersi nel piano in una spirale più piccola di lei: la punta della pillola veniva un angolo tagliato. Ora la testa resta tonda e solo un gambo sottile, che parte dove la testa finisce, si arrotola.
  • Da piegata la pillola è un bocciolo con il fronte a 4 pixel: rimpicciolendo tutta la spirale nel fronte spariva anche la testa tonda e restava mezzo disco. La spirale si rimpicciolisce solo oltre la testa.
  • Il 3 dentro la spirale diventava un puntino blu: il conteggio e la freccia svaniscono appena diventano piccoli, prima che sembrino pallini.
  • Le liste sono posizionate, quindi offsetTop di una riga è relativo alla sua lista: Settings finiva sopra Today. Le righe si misurano risalendo gli offsetParent fino al corpo della barra.
  • Le lettere e le pillole delle serre non stanno dentro la sezione (che taglia con overflow hidden) ma nei due strati SVG: per non vederle sotto la sezione chiusa, un clipPath le taglia al rettangolo della sezione, aggiornato a ogni fotogramma.
  • Ridisegnare ogni lettera a ogni fotogramma voleva dire seimila setAttribute al secondo anche a cose ferme: ora si rifà solo la striscia che si è mossa o la riga che si è spostata, e a riposo la barra non tocca niente.

Librerie

GSAP 3.15.0, Commissioner (font variabile) 5.3.0.

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