Vai al contenuto
animorio
EN
Torna alla libreria

L'elenco con l'anteprima che segue

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

Effetto hover in stile minimal per l'elenco dei lavori di un portfolio: sopra una riga si apre un'anteprima che segue il puntatore con un ritardo morbido e si inclina correndo; cambiando riga la tavola nuova entra nella cornice dal lato da cui arrivi, e il nome acceso prende peso e larghezza.

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>Orsk, selected work</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/roboto-flex@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">Orsk</span>
      <span class="top__note">Selected work</span>
    </header>

    <!-- the list: one project a row, between hairlines; the row under the pointer gains weight and width, the others
         fade back, and a preview follows the pointer -->
    <ul class="list" data-list>
      <li class="row" data-row tabindex="0">
        <span class="row__name" data-name>Halden Baths</span>
        <span class="row__meta"><span>Identity</span><span>2026</span></span>
      </li>
      <li class="row" data-row tabindex="0">
        <span class="row__name" data-name>Mirela Press</span>
        <span class="row__meta"><span>Books</span><span>2025</span></span>
      </li>
      <li class="row" data-row tabindex="0">
        <span class="row__name" data-name>Northfold</span>
        <span class="row__meta"><span>Signage</span><span>2024</span></span>
      </li>
      <li class="row" data-row tabindex="0">
        <span class="row__name" data-name>Arc &amp; Pine</span>
        <span class="row__meta"><span>Packaging</span><span>2023</span></span>
      </li>
      <li class="row" data-row tabindex="0">
        <span class="row__name" data-name>Lowe Observatory</span>
        <span class="row__meta"><span>Exhibition</span><span>2022</span></span>
      </li>
      <li class="row" data-row tabindex="0">
        <span class="row__name" data-name>Saltgrass</span>
        <span class="row__meta"><span>Website</span><span>2021</span></span>
      </li>
    </ul>

    <!-- the preview: a frame that follows the pointer (outer element for GSAP), with one plate per project inside;
         changing row, the new plate slides in from the side the pointer comes from -->
    <div class="preview" aria-hidden="true" data-preview>
      <div class="preview__frame" data-frame>
        <!-- Halden Baths: an arch and the sun -->
        <div class="plate" data-plate style="--plate: var(--sage)">
          <svg viewBox="0 0 400 300"><path class="ink-fill" d="M140 250V160a60 60 0 0 1 120 0v90z"/><line class="ink-line" x1="60" y1="250" x2="340" y2="250"/><circle class="sun" cx="300" cy="86" r="11"/></svg>
        </div>
        <!-- Mirela Press: lines of a page and a block of text -->
        <div class="plate" data-plate style="--plate: var(--sand)">
          <svg viewBox="0 0 400 300"><g class="ink-line"><line x1="70" y1="70" x2="330" y2="70"/><line x1="70" y1="96" x2="330" y2="96"/><line x1="70" y1="122" x2="330" y2="122"/><line x1="70" y1="148" x2="330" y2="148"/><line x1="70" y1="174" x2="250" y2="174"/></g><rect class="ink-fill" x="70" y="200" width="120" height="40"/><circle class="sun" cx="318" cy="220" r="9"/></svg>
        </div>
        <!-- Northfold: a ring over three bands -->
        <div class="plate" data-plate style="--plate: var(--slate)">
          <svg viewBox="0 0 400 300"><rect class="paper-fill" x="0" y="196" width="400" height="14"/><rect class="paper-fill" x="0" y="222" width="400" height="14"/><rect class="paper-fill" x="0" y="248" width="400" height="14"/><circle class="paper-line" cx="200" cy="120" r="64"/><circle class="sun" cx="200" cy="120" r="10"/></svg>
        </div>
        <!-- Arc & Pine: stacked boxes -->
        <div class="plate" data-plate style="--plate: var(--clay)">
          <svg viewBox="0 0 400 300"><rect class="ink-fill" x="150" y="190" width="100" height="60"/><rect class="paper-fill" x="164" y="136" width="72" height="54"/><rect class="ink-fill" x="178" y="96" width="44" height="40"/><line class="ink-line" x1="80" y1="250" x2="320" y2="250"/><circle class="sun" cx="200" cy="74" r="9"/></svg>
        </div>
        <!-- Lowe Observatory: thin arcs round a point -->
        <div class="plate" data-plate style="--plate: var(--night)">
          <svg viewBox="0 0 400 300"><g class="paper-line"><path d="M80 250a120 120 0 0 1 240 0"/><path d="M110 250a90 90 0 0 1 180 0"/><path d="M140 250a60 60 0 0 1 120 0"/><line x1="40" y1="250" x2="360" y2="250"/></g><circle class="sun" cx="200" cy="250" r="10"/></svg>
        </div>
        <!-- Saltgrass: three frames of a website -->
        <div class="plate" data-plate style="--plate: var(--stone)">
          <svg viewBox="0 0 400 300"><rect class="ink-line" x="60" y="70" width="80" height="160"/><rect class="ink-fill" x="160" y="70" width="80" height="100"/><rect class="ink-line" x="260" y="70" width="80" height="160"/><line class="ink-line" x1="160" y1="196" x2="240" y2="196"/><line class="ink-line" x1="160" y1="214" x2="220" y2="214"/><circle class="sun" cx="300" cy="110" r="9"/></svg>
        </div>
      </div>
    </div>

    <p class="hint" data-enter><span class="hint__hover">Hover a project</span><span class="hint__tap">Tap a project</span></p>
  </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 «L'elenco con l'anteprima che segue» da Animorio e adattala al mio sito

Cosa fa

Una pagina bianco caldo con in alto il nome di uno studio inventato, Orsk, e sotto l'elenco di sei lavori su righe divise da filetti sottili: a sinistra il nome grande in Roboto Flex, leggero e un po' stretto, a destra in piccolo il tipo di lavoro e l'anno. All'apertura le righe salgono una dopo l'altra e i nomi passano da sottili e stretti al loro peso. Quando il puntatore entra su una riga, nel punto dove si trova si apre un'anteprima rettangolare, con un piccolo rimbalzo: una tavola piatta disegnata per quel lavoro (un arco per delle terme, le righe di una pagina per una casa editrice, un anello sopra tre fasce per un sistema di cartelli, scatole impilate, archi sottili per un osservatorio, tre pagine di un sito), ognuna nel suo colore sobrio e tutte con un piccolo sole vermiglio. L'anteprima segue il puntatore con un ritardo morbido, si inclina di qualche grado nella direzione in cui corre e, quando il puntatore si ferma, si raddrizza su una molla con un filo di troppo. Il nome della riga accesa prende peso e larghezza e fa un passo avanti di pochi pixel; le altre righe si fanno indietro, più chiare. Scendendo a una riga sotto, la tavola nuova entra nella cornice dal basso e quella vecchia sale un poco, come vista da un finestrino; salendo succede il contrario. Uscendo dall'elenco l'anteprima si chiude rimpicciolendo verso il puntatore e le righe tornano tutte uguali. Quando nessuno muove il puntatore, un puntatore finto scende lungo le righe fermandosi su ognuna e poi risale.

Come funziona

Una riga, un lavoro

L'elenco è un ul di righe in flex: il nome a sinistra, tipo e anno a destra, un bordo in basso di un pixel in un nero trasparente. I nomi sono in Roboto Flex variabile: GSAP anima fontWeight e fontStretch (l'asse della larghezza) e una piccola x, con back.out per il filo di troppo; le altre righe scendono di opacità. Quale riga è accesa non lo decidono mouseenter e mouseleave ma un controllo a ogni fotogramma: il punto del puntatore si confronta coi rettangoli delle righe, così puntatore vero, puntatore finto e tocco passano dalla stessa strada.

Il ritardo morbido

L'anteprima è un div assoluto nel palco, mosso solo da GSAP. La sua posizione è un oggetto di due numeri spinto da due gsap.quickTo con power3.out: ogni fotogramma riceve la meta nuova e ci arriva in FOLLOW secondi. Quando l'anteprima è chiusa la meta si passa anche come punto di partenza, così si apre sotto il puntatore senza attraversare la pagina.

L'inclinazione su una molla

Dalla posizione di un fotogramma e del precedente si ricava la velocità orizzontale; la rotazione voluta è proporzionale, limitata a più o meno TILT gradi. Una molla scritta a mano (rigidità e freno di TILT_SPRING) porta la rotazione vera verso quella voluta: quando il puntatore si ferma la velocità torna a zero e l'anteprima si raddrizza oscillando appena. Apertura e chiusura sono una scala da 0 a 1 col centro sul puntatore: back.out entrando, power3.in uscendo.

La tavola che entra dal lato giusto

Dentro la cornice, con overflow hidden, c'è una tavola per lavoro, una sopra l'altra, ognuna un SVG piatto. Cambiando riga la tavola nuova sale in cima (z-index), parte da yPercent 100 o -100 secondo se la riga nuova sta sotto o sopra e arriva a zero con expo.out; il suo disegno parte spostato al contrario e un po' più grande, e quello della tavola vecchia sale di un quarto: è il parallasse del finestrino. Si disegnano solo la tavola che entra e quella che esce, le altre restano nascoste.

Il puntatore finto, il tocco e il movimento ridotto

Una timeline GSAP a repeat -1 porta un numero da 0 a 1 in venti secondi: la prima metà scende dalla cima dell'elenco alle righe una per una fino a sotto, la seconda risale, con una pausa su ogni riga; il giro finisce come comincia. Il puntatore vero lo sostituisce per 2,4 secondi dopo ogni movimento. Un tocco apre l'anteprima sopra la riga toccata e la tiene lì; col fuoco della tastiera si apre accanto alla riga. Con il movimento ridotto l'anteprima sta ferma accanto alla riga, compare e cambia in dissolvenza, e non c'è il puntatore finto.

Valori da cambiare

NomeFileDi partenzaCosa cambia
FOLLOWscript.js0.55In quanti secondi l'anteprima raggiunge il puntatore: più alto, più resta indietro.
TILTscript.js7Di quanti gradi al massimo si inclina l'anteprima quando corre di lato.
TILT_SPRINGscript.js[170, 13]La molla dell'inclinazione: quanto è rigida e quanto è frenata (meno freno, più dondola raddrizzandosi).
SWAPscript.js0.6In quanti secondi la tavola nuova entra nella cornice cambiando riga.
SIZEscript.js0.24La larghezza dell'anteprima, in frazioni della pagina (sul telefono è più grande).
WEIGHTscript.js[320, 620]Il peso dei nomi: a riposo e sulla riga accesa (da 100 a 1000).
WIDTHscript.js[96, 122]La larghezza dei nomi: a riposo e sulla riga accesa (da 25 a 151).
DIMscript.js0.26Quanto restano visibili le altre righe quando una è accesa (0 spariscono, 1 restano piene).
WANDERscript.jstrueIl puntatore finto che scende lungo le righe e risale quando nessuno le tocca.

Provali nel Playground

Quando usarla

Per l'elenco dei lavori di uno studio di grafica, di architettura o di fotografia, l'indice di una rivista, i progetti di un portfolio personale: righe di testo pulite che si accendono di un'immagine solo quando servono. Funziona bene con quattro-dieci righe.

Sul telefono

Le stesse animazioni a misure adattate: le righe vanno a capo con tipo e anno sotto il nome, l'anteprima è larga quasi due terzi dello schermo. Un tocco su una riga apre l'anteprima sopra la riga, un tocco su un'altra la fa scivolare lì cambiando tavola con lo stesso scorrimento, un tocco fuori dall'elenco la chiude. La scritta in fondo dice Tap invece di Hover.

Con il movimento ridotto

L'anteprima non segue il puntatore e non si inclina: sta ferma accanto alla riga accesa, compare in dissolvenza e cambia tavola in dissolvenza. Il nome acceso prende peso senza spostarsi. Niente puntatore finto; all'apertura tutto compare in dissolvenza già al suo posto.

Trappole

  • Toccando una riga sul telefono la riga prende anche il fuoco, e il gestore del fuoco (pensato per la tastiera) spostava l'anteprima accanto alla riga invece che sopra: ora il fuoco conta solo se è :focus-visible.
  • Le tavole erano tutte disegnate una sopra l'altra: durante lo scorrimento i disegni delle tavole vecchie, spostati dal parallasse, trasparivano sopra quella accesa. Ora si disegnano solo la tavola che entra e quella che esce.
  • Una tavola che rientrava senza scorrimento (all'apertura) teneva il disegno spostato dal parallasse di quando era uscita: va rimesso a zero.
  • quickTo, dopo un gsap.set sulla posizione, continua dal punto dove era rimasto il suo tween: per far aprire l'anteprima sotto il puntatore la meta si passa anche come partenza (moveX(x, x)).
  • Col cursore che apre l'anteprima su mouseenter, il puntatore finto e il tocco avrebbero avuto bisogno di eventi finti: confrontare a ogni fotogramma il punto coi rettangoli delle righe tiene una sola strada per tutti.
  • Un pointerleave mandato su una riga (lo fa il pilota delle anteprime, con bubbles) risaliva fino alla pagina e chiudeva l'anteprima a ogni cambio di elemento: si ascolta solo quello che riguarda la pagina intera.

Librerie

GSAP 3.15.0, Roboto Flex (font variabile) 5.3.0.

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