Vai al contenuto
animorio
EN
Torna alla libreria

I progetti con le righe elastiche

Hover, Fisica, SVGSolo CSSMediaPeso compresso: Demo 5,6 KBsenza librerieGratisScarica lo zip

Un elenco di prodotti con un nome grande per riga. Passando sopra un nome la parola si apre in due e nello spazio compare un’immagine del prodotto; le righe fra un nome e l’altro si agganciano al puntatore, si piegano con lui e, quando lui tira troppo, scappano e tornano dritte vibrando.

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>Projects with elastic lines</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/dynapuff@5.3.0/index.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/dm-mono@5.3.0/500.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!-- the list of a small studio's products: over a name, the word parts in two and a little picture of the product
       slides into the gap; the lines between the names can be caught with the pointer, bent and let go -->
  <main class="pagina">
    <header class="testa">
      <span>Otter &amp; Oak</span>
      <span>Five things we built</span>
    </header>

    <ul class="elenco" data-elenco>
      <li class="voce">
        <a class="riga" href="#" data-riga aria-label="Tidepool, tide tables for surfers">
          <span class="anteprima" aria-hidden="true">
            <svg viewBox="0 0 300 150"><rect width="300" height="150" rx="22" fill="#2f7dd9"/><path d="M0 92C40 78 70 104 110 92S180 78 220 92S280 104 300 92V150H0Z" fill="#7fc4ff"/><circle cx="78" cy="58" r="18" fill="#ffe08a"/><path d="M212 40l7 15 16 2-12 11 3 16-14-8-14 8 3-16-12-11 16-2z" fill="#ff8a5c"/><text x="22" y="134" fill="#0d2a4d">tide tables for surfers</text></svg>
          </span>
          <span class="parola" aria-hidden="true"><span class="meta meta--sx" data-sx>TIDE</span><span class="meta meta--dx" data-dx>POOL</span></span>
        </a>
      </li>
      <li class="voce">
        <svg class="filo" data-filo aria-hidden="true" focusable="false"><path/></svg>
        <a class="riga" href="#" data-riga aria-label="Lantern, a night bus planner">
          <span class="anteprima" aria-hidden="true">
            <svg viewBox="0 0 300 150"><rect width="300" height="150" rx="22" fill="#1d1a3a"/><rect x="120" y="34" width="60" height="78" rx="16" fill="#ffb347"/><rect x="134" y="48" width="32" height="50" rx="9" fill="#ffe7b3"/><path d="M132 34c0-16 36-16 36 0" fill="none" stroke="#ffb347" stroke-width="7"/><text x="22" y="134" fill="#c9c3ff">a night bus planner</text></svg>
          </span>
          <span class="parola" aria-hidden="true"><span class="meta meta--sx" data-sx>LAN</span><span class="meta meta--dx" data-dx>TERN</span></span>
        </a>
      </li>
      <li class="voce">
        <svg class="filo" data-filo aria-hidden="true" focusable="false"><path/></svg>
        <a class="riga" href="#" data-riga aria-label="Pebble, a savings jar for kids">
          <span class="anteprima" aria-hidden="true">
            <svg viewBox="0 0 300 150"><rect width="300" height="150" rx="22" fill="#f2e2c9"/><ellipse cx="150" cy="98" rx="62" ry="22" fill="#9b8a74"/><ellipse cx="146" cy="68" rx="44" ry="17" fill="#c4b39b"/><ellipse cx="152" cy="44" rx="27" ry="12" fill="#e0d2bb"/><text x="22" y="134" fill="#5b4a35">a savings jar for kids</text></svg>
          </span>
          <span class="parola" aria-hidden="true"><span class="meta meta--sx" data-sx>PEB</span><span class="meta meta--dx" data-dx>BLE</span></span>
        </a>
      </li>
      <li class="voce">
        <svg class="filo" data-filo aria-hidden="true" focusable="false"><path/></svg>
        <a class="riga" href="#" data-riga aria-label="Hayloft, bookings for farm stays">
          <span class="anteprima" aria-hidden="true">
            <svg viewBox="0 0 300 150"><rect width="300" height="150" rx="22" fill="#ffd54d"/><path d="M104 112V62l46-30 46 30v50z" fill="#d9452b"/><path d="M134 112V80h32v32" fill="#ffd54d"/><path d="M134 80l32 32M166 80l-32 32" stroke="#d9452b" stroke-width="5"/><text x="22" y="134" fill="#6b4300">bookings for farm stays</text></svg>
          </span>
          <span class="parola" aria-hidden="true"><span class="meta meta--sx" data-sx>HAY</span><span class="meta meta--dx" data-dx>LOFT</span></span>
        </a>
      </li>
      <li class="voce">
        <svg class="filo" data-filo aria-hidden="true" focusable="false"><path/></svg>
        <a class="riga" href="#" data-riga aria-label="Mosswork, a shared garden diary">
          <span class="anteprima" aria-hidden="true">
            <svg viewBox="0 0 300 150"><rect width="300" height="150" rx="22" fill="#3f8f4f"/><path d="M70 104c-8-30 18-50 40-36 6-24 40-28 50-6 20-14 46 2 40 28 18 4 20 22 6 30H76c-14-2-18-12-6-16z" fill="#a8e06b"/><circle cx="118" cy="88" r="7" fill="#f6ffe0"/><circle cx="176" cy="80" r="5" fill="#f6ffe0"/><text x="22" y="134" fill="#e6ffd2">a shared garden diary</text></svg>
          </span>
          <span class="parola" aria-hidden="true"><span class="meta meta--sx" data-sx>MOSS</span><span class="meta meta--dx" data-dx>WORK</span></span>
        </a>
      </li>
    </ul>
  </main>

  <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 progetti con le righe elastiche» da Animorio e adattala al mio sito

Cosa fa

La pagina dei prodotti di uno studio inventato di due persone, Otter & Oak, su un verde salvia chiaro: cinque nomi enormi in un carattere tondo e gonfio, uno per riga, separati da linee sottili. All’apertura le linee si disegnano da sinistra a destra, una dopo l’altra. Col puntatore su una riga, il nome si divide nel suo punto, TIDE e POOL, LAN e TERN, e le due metà scivolano ai lati in mezzo secondo, quanto basta perché in mezzo stia un’immagine del prodotto con una riga che dice cosa fa; l’immagine compare crescendo appena. Se il puntatore passa a meno di venti pixel da una linea, la linea lo prende: il suo centro lo segue, a destra e a sinistra e un poco in su o in giù, e la linea si curva. Se il puntatore si allontana più di venticinque pixel o esce dalla riga, la linea lo lascia e torna dritta con una molla, oscillando qualche volta, con la velocità che aveva quando è scappata.

Come funziona

Le due metà

Ogni nome è due span uno accanto all’altro. Lo script misura dove finisce la prima metà e dove comincia la seconda e scrive in due variabili CSS quanto deve spostarsi ognuna perché l’immagine, larga una volta e mezzo l’altezza delle lettere, stia al centro con ROOM di margine per lato. Con la riga aperta, una transizione di SPLIT secondi sposta le metà con la curva 0, 0, 0,2, 1. Le misure vengono dall’impaginazione, che le trasformazioni non cambiano: si possono rifare anche a riga aperta.

La riga aperta

Quale riga si apre lo decide lo script, non :hover: a ogni movimento del mouse guarda quale elemento c’è sotto il puntatore e apre la sua riga. Così funziona anche col pilota automatico dell’anteprima, con la tastiera (la riga si apre quando prende il fuoco) e col dito, che apre la riga toccata e la richiude al secondo tocco.

Le linee

Ogni linea è un SVG alto quanto una riga e centrato sul suo bordo, con una curva dal lato sinistro al destro e un solo punto di controllo, al centro quando è dritta. Il puntatore la prende se passa a meno di GRAB pixel; da lì il punto di controllo sta sotto il puntatore, spinto PULL volte più lontano dal centro (una curva arriva solo a metà strada dal suo punto di controllo, così la linea passa vicino al puntatore). La linea scappa se il puntatore si allontana più di LET_GO pixel, o di mezza riga se è meno, o esce dal riquadro.

La molla

Libero, il punto di controllo torna al centro con una molla: a ogni fotogramma, in passi di un duecentoquarantesimo di secondo, la forza è la distanza per la rigidità meno la velocità per lo smorzamento, i due numeri di SPRING. La velocità di partenza è quella della mano nell’ultimo fotogramma: una linea strappata via in fretta oscilla di più.

Il disegno iniziale

All’apertura ogni linea ha pathLength 1, quindi si disegna col solo stroke-dashoffset da 1 a 0, spinto da un’altra molla, i due numeri di DRAW. La prima parte dopo DRAW_DELAY[0] secondi e le altre una dopo l’altra, DRAW_DELAY[1] secondi più tardi.

Valori da cambiare

NomeFileDi partenzaCosa cambia
SPLITscript.js0.5I secondi che le due metà impiegano ad aprirsi (come nel sito).
ROOMscript.js0.18Lo spazio ai lati dell’immagine, in parti dell’altezza delle lettere.
GRABscript.js20Quanto vicino alla linea deve passare il puntatore per prenderla, in pixel (nel sito 20).
LET_GOscript.js25Quanto si può tirare la linea prima che scappi, in pixel (nel sito 25).
PULLscript.js2.2Quante volte più del puntatore si sposta il punto di controllo della curva (nel sito 2,2).
SPRINGscript.js[200, 10]La molla del ritorno: rigidità e smorzamento. Nel sito sono 200 e 30, e la linea torna senza oscillare.
DRAWscript.js[300, 30]La molla del disegno iniziale delle linee (quella del sito).
DRAW_DELAYscript.js[0.15, 0.08]L’attesa prima della prima linea e fra una linea e la successiva, in secondi.

Provali nel Playground

Quando usarla

Per l’elenco dei lavori di uno studio o dei prodotti di un marchio, quando i nomi sono pochi e possono stare grandi: l’immagine si vede solo a chi ci passa sopra, e le linee danno qualcosa da toccare anche a chi sta solo guardando.

Sul telefono

Uguale: col dito si tocca un nome per aprirlo e lo si ritocca per chiuderlo, e trascinando il dito su una linea la si prende e la si piega come col mouse.

Con il movimento ridotto

Le metà si aprono di colpo, senza scivolare, l’immagine compare con una dissolvenza e le linee restano dritte.

Trappole

  • I pezzi della parola misurano la loro posizione dal riquadro più vicino che ha una posizione, cioè la riga: sommarci anche la posizione della parola la conta due volte, e una metà scappa fuori dallo schermo mentre l’altra resta ferma.
  • :hover non risponde agli eventi inventati dal pilota automatico dell’anteprima: la riga aperta la sceglie lo script guardando cosa c’è sotto il puntatore.
  • Col dito la pagina scorrerebbe invece di piegare la linea: l’elenco ha touch-action: none, e la pagina sta tutta in uno schermo.

Librerie

DynaPuff (font variabile) 5.3.0, DM Mono 5.3.0.

Compressi con gzip, i tre file della demo pesano 5,6 KB, e non servono librerie.

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.

Tutte le animazioni