Vai al contenuto
animorio
EN
Torna alla libreria

Le immagini a fisarmonica al passaggio

Hover, ImmaginiGSAP, Solo CSSMediaPeso compresso: Demo 6,6 KBGSAP 28 KBGratisScarica lo zip

Galleria hover in stile minimal per le stampe di uno studio inventato: sei pannelli stretti fra fili sottili; quello sotto il puntatore si allarga su una molla e gli altri gli fanno posto, la stampa dentro scorre più lenta del bordo e il nome in piedi si corica in un titolo che prende larghezza e peso.

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>Sallow, landscape prints</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" data-stage>
    <header class="top" data-enter>
      <span class="top__name">Sallow</span>
      <span class="top__note">Landscape prints, autumn edition</span>
    </header>

    <!-- the gallery: narrow panels side by side between hairlines; the panel under the pointer opens wide on a spring,
         the others make room, the print inside slides slower than the edge and the name turns from upright to level -->
    <section class="gallery" data-gallery aria-label="Prints">
      <button class="panel" type="button" data-panel style="--paper: #d8d1c2">
        <span class="panel__art" data-art>
          <svg viewBox="0 140 600 660" preserveAspectRatio="xMidYMid slice" aria-hidden="true">
            <rect width="600" height="800" class="paper" />
            <circle class="accent" cx="380" cy="300" r="46" />
            <path d="M0 420H600" class="ink" />
            <path d="M0 470H600M0 515H600M0 556H600M0 592H600M0 624H600M0 652H600M0 676H600M0 697H600M0 715H600" class="fine" />
            <path d="M0 420C120 404 210 402 300 412S470 426 600 404V420H0Z" class="fill" />
          </svg>
        </span>
        <span class="panel__upright" data-upright>Tidewater</span>
        <span class="panel__title" data-title>Tidewater</span>
        <span class="panel__line" data-line>Low sun on a flat sea, nine lines of water.</span>
      </button>

      <button class="panel" type="button" data-panel style="--paper: #cdd1c9">
        <span class="panel__art" data-art>
          <svg viewBox="0 140 600 660" preserveAspectRatio="xMidYMid slice" aria-hidden="true">
            <rect width="600" height="800" class="paper" />
            <path d="M0 800V560H120V500H230V430H340V360H450V300H600V800Z" class="fill" />
            <path d="M0 560H120V500H230V430H340V360H450V300H600" class="ink" />
            <path d="M60 560V800M175 500V800M285 430V800M395 360V800M525 300V800" class="fine" />
            <rect class="accent" x="438" y="262" width="24" height="38" />
          </svg>
        </span>
        <span class="panel__upright" data-upright>Quarry</span>
        <span class="panel__title" data-title>Quarry</span>
        <span class="panel__line" data-line>Steps of cut stone climbing to one red marker.</span>
      </button>

      <button class="panel" type="button" data-panel style="--paper: #ddd3c1">
        <span class="panel__art" data-art>
          <svg viewBox="0 140 600 660" preserveAspectRatio="xMidYMid slice" aria-hidden="true">
            <rect width="600" height="800" class="paper" />
            <path d="M0 470H600M0 560H600M0 650H600M0 740H600" class="fine" />
            <g class="fill">
              <circle cx="60" cy="440" r="26" /><circle cx="160" cy="440" r="26" /><circle cx="260" cy="440" r="26" /><circle cx="360" cy="440" r="26" /><circle cx="460" cy="440" r="26" /><circle cx="560" cy="440" r="26" />
              <circle cx="110" cy="528" r="30" /><circle cx="210" cy="528" r="30" /><circle cx="310" cy="528" r="30" /><circle cx="410" cy="528" r="30" /><circle cx="510" cy="528" r="30" />
              <circle cx="60" cy="616" r="34" /><circle cx="160" cy="616" r="34" /><circle cx="360" cy="616" r="34" /><circle cx="460" cy="616" r="34" /><circle cx="560" cy="616" r="34" />
            </g>
            <circle class="accent" cx="260" cy="616" r="34" />
          </svg>
        </span>
        <span class="panel__upright" data-upright>Orchard</span>
        <span class="panel__title" data-title>Orchard</span>
        <span class="panel__line" data-line>Rows of apple trees, and the one that ripened first.</span>
      </button>

      <button class="panel" type="button" data-panel style="--paper: #d4cdd3">
        <span class="panel__art" data-art>
          <svg viewBox="0 140 600 660" preserveAspectRatio="xMidYMid slice" aria-hidden="true">
            <rect width="600" height="800" class="paper" />
            <path d="M0 520C140 440 260 470 360 430S520 360 600 380V800H0Z" class="fill" />
            <path d="M0 600C120 560 250 590 380 540S540 500 600 510" class="ink" />
            <path d="M0 660C150 630 280 650 400 610S560 580 600 590M0 720C130 700 260 712 420 680S560 660 600 664" class="fine" />
            <circle class="accent" cx="150" cy="250" r="22" />
          </svg>
        </span>
        <span class="panel__upright" data-upright>Dunes</span>
        <span class="panel__title" data-title>Dunes</span>
        <span class="panel__line" data-line>Wind-drawn ridges under a small evening moon.</span>
      </button>

      <button class="panel" type="button" data-panel style="--paper: #d9cebd">
        <span class="panel__art" data-art>
          <svg viewBox="0 140 600 660" preserveAspectRatio="xMidYMid slice" aria-hidden="true">
            <rect width="600" height="800" class="paper" />
            <path d="M170 800V420A130 130 0 0 1 430 420V800Z" class="fill" />
            <path d="M170 800V420A130 130 0 0 1 430 420V800" class="ink" />
            <path d="M230 800V430A70 70 0 0 1 370 430V800" class="fine" />
            <path d="M0 800H600" class="ink" />
            <rect class="accent" x="284" y="560" width="32" height="240" />
          </svg>
        </span>
        <span class="panel__upright" data-upright>Kiln</span>
        <span class="panel__title" data-title>Kiln</span>
        <span class="panel__line" data-line>A brick arch with the fire still glowing inside.</span>
      </button>

      <button class="panel" type="button" data-panel style="--paper: #c9d1ce">
        <span class="panel__art" data-art>
          <svg viewBox="0 140 600 660" preserveAspectRatio="xMidYMid slice" aria-hidden="true">
            <rect width="600" height="800" class="paper" />
            <path d="M120 800V460L300 330L480 460V800" class="ink" />
            <path d="M180 800V417M240 800V374M300 800V330M360 800V374M420 800V417M120 540H480M120 620H480M120 700H480" class="fine" />
            <path d="M120 460L300 330L480 460" class="ink" />
            <circle class="accent" cx="300" cy="470" r="20" />
          </svg>
        </span>
        <span class="panel__upright" data-upright>Glasshouse</span>
        <span class="panel__title" data-title>Glasshouse</span>
        <span class="panel__line" data-line>Iron ribs, thin panes, one bloom under the roof.</span>
      </button>
    </section>

    <footer class="bottom" data-enter>
      <span>Six prints on cotton paper</span>
      <span class="bottom__hint" data-hint>Pass over a print</span>
    </footer>
  </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.

45 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 «Le immagini a fisarmonica al passaggio» da Animorio e adattala al mio sito

Cosa fa

Una pagina bianco caldo con in cima il nome di uno studio di stampe inventato, Sallow, e sotto una fila di sei pannelli stretti divisi da fili sottili: sei stampe di paesaggio disegnate a linee e campiture tenui (il mare col sole basso, la cava a gradini, il frutteto, le dune con la luna, la fornace ad arco, la serra), ognuna col suo nome scritto in piedi in basso. All’apertura i pannelli salgono uno dopo l’altro come tende. Col puntatore sopra un pannello, quello si allarga fino a prendere più di metà della fila e gli altri si stringono per fargli posto: ogni pannello ha la sua molla, che arriva con un filo di troppo e si assesta, e i vicini partono un attimo dopo, i più lontani per ultimi. Mentre il pannello si allarga la stampa dentro scorre più lenta del bordo, così si scopre piano; il nome in piedi sparisce e al suo posto sale un titolo grande che si allarga e prende peso, su un velo del colore della carta, con sotto una riga che racconta la stampa; il dettaglio rosso della stampa (il sole, il segnale, la mela matura) si accende solo a pannello aperto. Passando a un altro pannello la fila si ridistribuisce a onda. Quando nessuno muove il puntatore, un puntatore invisibile apre le stampe una dopo l’altra.

Come funziona

Pesi invece di larghezze

Ogni pannello ha un peso: 1 da chiuso e, da aperto, quello che gli fa prendere OPEN_RATIO della fila. A ogni fotogramma la fila si divide in proporzione ai pesi e i pannelli prendono left e width in pixel (top e height sul telefono): la somma torna sempre la fila intera, anche mentre le molle oscillano.

Una molla per pannello, a onda

Quando cambia il pannello aperto, ognuno riceve il suo nuovo peso con un ritardo di STAGGER per ogni posto di distanza: i vicini partono prima. Il peso segue il traguardo con una molla integrata a passi di 1/240 di secondo nel ticker di GSAP (rigidezza e freno in SPRING), così arriva un filo oltre e si assesta.

La stampa più lenta del bordo

La stampa è un SVG grande quanto il pannello aperto, quindi non si deforma mai: il pannello ne mostra una finestra. La sua posizione è (larghezza del pannello meno larghezza della stampa) per PARALLAX: con 0.5 resta al centro, con meno si muove più lenta del bordo e si scopre a poco a poco.

Dal nome in piedi al titolo

Dall’apertura del pannello (da 0 a 1) dipendono: il nome in piedi, che sparisce presto; il titolo, che compare a metà salendo di 14 pixel e passa da TITLE_WIDTH e TITLE_WEIGHT di partenza a quelli di arrivo con gli assi di Archivo; la riga sotto, verso la fine; il velo color carta (una variabile CSS --o) e il dettaglio rosso della stampa.

Il puntatore finto e il tocco

Una timeline GSAP in ripetizione porta un numero da 0 a 1 in STEP secondi per stampa: ne esce il pannello da aprire, sempre nello stesso ordine, così il giro torna uguale. Il puntatore vero comanda per 2,4 secondi dall’ultimo movimento; sul telefono un tocco apre il pannello per 6 secondi, un altro tocco lo richiude. Col movimento ridotto i pesi saltano subito al traguardo e il titolo compare senza molla né parallasse.

Valori da cambiare

NomeFileDi partenzaCosa cambia
OPEN_RATIOscript.js0.56Quanta parte della fila prende il pannello aperto (da 0.3 a 0.8).
SPRINGscript.js[170, 17]La molla dei pannelli: quanto è rigida e quanto è frenata (meno freno, più rimbalzo).
STAGGERscript.js0.045Il ritardo fra un pannello e il vicino quando la fila cambia, in secondi.
PARALLAXscript.js0.36Quanto la stampa segue il bordo che si allarga: 0.5 la tiene al centro, meno la fa scorrere più lenta.
TITLE_WIDTHscript.js[72, 112]La larghezza del titolo mentre arriva e a pannello aperto (da 62 a 125).
TITLE_WEIGHTscript.js[300, 640]Il peso del titolo mentre arriva e a pannello aperto (da 100 a 900).
STEPscript.js1.6Quanti secondi il puntatore finto resta su ogni stampa.
WANDERscript.jstrueIl puntatore finto che apre le stampe una dopo l’altra quando nessuno tocca.

Provali nel Playground

Quando usarla

Per la galleria di un fotografo o di un illustratore, le stampe di un negozio d’arte, le collezioni di un marchio, le camere di un albergo, le sezioni di un progetto: poche immagini forti che si scoprono una alla volta senza lasciare la pagina.

Sul telefono

Le stesse animazioni, coi pannelli uno sopra l’altro: si apre quello toccato, che si allunga in altezza con la stessa molla e la stessa onda, e la stampa scorre in verticale. Un altro tocco sullo stesso pannello lo richiude; dopo 6 secondi torna il giro automatico.

Con il movimento ridotto

Niente molle, niente parallasse e niente giro automatico: un pannello è già aperto, e passando su un altro la fila cambia di colpo mentre il titolo compare in dissolvenza.

Trappole

  • Col movimento ridotto la fila restava tutta uguale: il pannello aperto di partenza era già scritto nello stato, e la funzione che lo apre lo scartava come «già aperto». Ora lo stato parte vuoto e il pannello si apre davvero.
  • Il titolo grande si sedeva sopra la stampa e non si leggeva: sotto c’è un velo del colore della carta del pannello, in un ::after che compare con l’apertura; titolo, riga e nome stanno sopra con z-index, perché lo pseudo-elemento viene disegnato dopo i figli.
  • Uno scale di GSAP sulla stampa all’apertura veniva cancellato a ogni fotogramma dal transform della parallasse: la stampa ha un solo padrone, il ciclo che la disegna.
  • Le stampe in un viewBox 600x800 lasciavano un gran vuoto in cima nel pannello aperto, quasi quadrato: il viewBox parte da 140, così la composizione sta nel mezzo.

Librerie

GSAP 3.15.0, Archivo (font variabile) 5.3.0.

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

Collaudo

Provata il 21 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.

Tutte le animazioni