Vai al contenuto
animorio
EN
Torna alla libreria

La ruota che si arrotonda

Scroll, FisicaCanvas, GSAPImpegnativaPeso compresso: Demo 14 KBGSAP + ScrollTrigger 45 KBLenis 5,3 KBGratisScarica lo zip

Scorri dentro l’anteprima

Scorrendo, una ruota quadrata rotola su una strada di gobbe: sono archi di catenaria, la matematica vera della ruota quadrata, e il suo mozzo non si muove mai dalla linea tratteggiata. Strada facendo prende lati uno alla volta, da quattro a dodici, poi si gonfia fino al cerchio e la strada si spiana sotto di lei.

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 wheel that rounds off</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/bricolage-grotesque@5.3.0/standard.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/full-italic.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/red-hat-mono@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!-- a made-up bike workshop, Round Trip Cycle Works. The stage sticks while you scroll: a square wheel rolls along a
       road of catenary arches (the real maths of the square wheel, drawn on a canvas), takes on sides from four to
       twelve, swells into a circle and the road flattens out under it. The four steps of a service light up as the
       wheel passes over them. Everything is drawn by the script -->
  <main>
    <section class="corsa" data-corsa>
      <div class="palco" data-palco>
        <canvas class="strada" data-strada aria-hidden="true"></canvas>

        <header class="testa">
          <a class="marchio" href="#" data-marchio>
            <svg class="marchio__segno" viewBox="0 0 40 40" aria-hidden="true">
              <rect class="marchio__ruota" data-marchio-ruota x="7" y="7" width="26" height="26" rx="7"/>
              <path class="marchio__raggi" d="M20 9.5v21M9.5 20h21"/>
              <circle class="marchio__mozzo" cx="20" cy="20" r="3.6"/>
            </svg>
            <span class="marchio__nome" data-entra-testa>Round Trip<span>Cycle Works</span></span>
          </a>
          <p class="testa__orari" data-entra-testa>Open Tuesday to Saturday</p>
          <a class="pillola" href="#" data-pillola data-entra-testa><span class="pillola__fondo" data-pillola-fondo></span><span class="pillola__testo">Book a service</span></a>
        </header>

        <div class="apertura">
          <p class="apertura__etichetta" data-entra>How a service goes</p>
          <h1 class="apertura__titolo">
            <span class="riga"><span class="riga__dentro" data-riga>From square one</span></span>
            <span class="riga"><span class="riga__dentro morbido" data-riga data-morbido>to a smooth ride.</span></span>
          </h1>
          <p class="apertura__testo" data-entra>Bring us the bike that rattles. We take the corners off, one at a time, until it rolls like the day you bought it.</p>
        </div>

        <div class="bandiera" data-bandiera aria-hidden="true">
          <div class="bandiera__telo" data-telo>
            <span class="bandiera__nome" data-bandiera-nome>Square</span>
            <span class="bandiera__lati" data-bandiera-lati>4 sides</span>
          </div>
        </div>

        <p class="cenno" data-cenno>
          <span>Scroll to roll</span>
          <svg viewBox="0 0 20 20" aria-hidden="true"><path d="M10 3v13M4.5 10.5 10 16l5.5-5.5"/></svg>
        </p>

        <ul class="passi" data-passi>
          <li class="passo" data-passo data-forma="primo">
            <svg class="passo__forma" viewBox="-12 -12 24 24" aria-hidden="true"><path data-passo-forma/></svg>
            <h2 class="passo__nome">Drop off</h2>
            <p class="passo__riga">Wheel in, coffee on. We write down every rattle and squeak.</p>
          </li>
          <li class="passo" data-passo data-forma="medio">
            <svg class="passo__forma" viewBox="-12 -12 24 24" aria-hidden="true"><path data-passo-forma/></svg>
            <h2 class="passo__nome">Check-up</h2>
            <p class="passo__riga">Spokes, bearings, brakes and chain. We find every corner.</p>
          </li>
          <li class="passo" data-passo data-forma="ultimo">
            <svg class="passo__forma" viewBox="-12 -12 24 24" aria-hidden="true"><path data-passo-forma/></svg>
            <h2 class="passo__nome">Tune</h2>
            <p class="passo__riga">Trued, tensioned and greased, one side at a time.</p>
          </li>
          <li class="passo" data-passo data-forma="cerchio">
            <svg class="passo__forma" viewBox="-12 -12 24 24" aria-hidden="true"><path data-passo-forma/></svg>
            <h2 class="passo__nome">Ride away</h2>
            <p class="passo__riga">Round, quiet and quick. Same day, most days.</p>
          </li>
        </ul>
        <p class="passi__ora" aria-hidden="true"><span data-passo-ora>Wheel in, coffee on. We write down every rattle and squeak.</span></p>
      </div>
    </section>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/ScrollTrigger.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/lenis@1.3.26/dist/lenis.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.

37 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 ruota che si arrotonda» da Animorio e adattala al mio sito

Cosa fa

La pagina «come funziona un tagliando» di una bottega di biciclette inventata, Round Trip Cycle Works. Il palco resta fermo mentre si scorre: in alto il titolo «From square one to a smooth ride», in basso, sul terreno, i quattro passi del servizio (Drop off, Check-up, Tune, Ride away). All’apertura la strada si disegna da sinistra, la ruota cade dall’alto e rimbalza, la bandierina sul suo palo oscilla. Scorrendo, la ruota quadrata (copertone nero, raggi, mozzo e valvola arancioni) rotola verso destra sulle gobbe della strada: il mozzo corre dritto sulla linea tratteggiata, mentre gli spigoli scendono nelle buche e alzano un po’ di polvere. Poco dopo prende un lato, poi un altro: pentagono, esagono, fino a dodici lati, e intanto le gobbe si fanno più basse e più fitte, sempre giuste per la forma di quel momento. Poi i lati si gonfiano, la ruota diventa un cerchio e la strada si spiana in una linea dritta. La bandierina dice che forma è la ruota (Square, Pentagon… Circle), cambia scritta con un rimbalzo, si piega all’indietro quando la ruota accelera e trema a ogni buca. Ogni passo si accende quando la ruota ci arriva, con l’icona della forma che gira ed entra con un elastico; nel titolo la parte in corsivo diventa più morbida man mano che la ruota perde gli spigoli, e all’ultimo passo il pulsante «Book a service» fa un saltello.

Come funziona

La strada di ogni ruota

Visto dal mozzo, il contorno della ruota è una distanza r per ogni angolo. Se il mozzo resta alla stessa altezza e la ruota non scivola, il punto che tocca la strada è sempre proprio sotto il mozzo: lì la strada è r più in basso, e avanzando di dx la ruota gira di dx diviso r. Quindi la strada è x uguale alla somma di r per l’angolo, y uguale a r. Per un lato dritto a distanza d dal centro, r è d diviso il coseno dell’angolo dalla sua perpendicolare, e la somma viene d per asinh(tan(angolo)): un arco di catenaria rovesciato, d·cosh(x/d), largo quanto il lato. È la strada della ruota quadrata.

I lati che crescono

Fra n e n+1 lati la ruota non salta: il poligono riceve un vertice nuovo a metà del suo ultimo lato, poi tutti i vertici scivolano dove li ha il poligono con un lato in più, girato di quel poco che li fa muovere il meno possibile. I lati vanno da SIDES[0] a SIDES[1] nella prima metà della corsa (con una smoothstep), poi i lati si gonfiano: ogni punto del contorno va verso il raggio pieno, cioè r diventa lerp(r, 1, tondo), e la strada si calcola con la stessa r, così si spiana da sola.

Quanto ha girato

Siccome la forma cambia mentre rotola, l’angolo della ruota non si legge dalla forma: si somma una volta sola, all’inizio, in 2.400 passi piccoli (dx diviso r, con un passo intermedio per essere precisi) e si tiene in una tabella. Ogni fotogramma legge la tabella al punto della corsa, così tornando indietro la ruota ripassa per le stesse posizioni.

Inseguire lo scorrimento

ScrollTrigger dà la frazione di corsa; il disegno la insegue coprendo ogni fotogramma la quota CHASE della distanza (calcolata sul tempo vero, quindi uguale a 60 e a 120 Hz) e, quando la distanza è sotto 0,0005, si ferma lì. Il canvas si ridisegna solo se qualcosa è cambiato: la corsa, la bandierina che oscilla o la polvere ancora in aria.

Bandierina, polvere e passi

Il palo della bandierina è una molla: si piega all’indietro con la velocità della ruota e riceve un colpo ogni volta che uno spigolo cade in una buca, tanto più forte quanto più la ruota è spigolosa; nello stesso momento parte uno sbuffo di polvere (DUST). Il nome della forma cambia sul numero di lati arrotondato, con un rimbalzo. Ogni passo si accende quando il mozzo supera l’inizio della sua colonna, e l’asse SOFT del Fraunces corsivo segue quanto la ruota è tonda.

Valori da cambiare

NomeFileDi partenzaCosa cambia
SIDESscript.js[4, 12]I lati della ruota alla partenza (almeno 4: un triangolo urterebbe la gobba dopo) e quanti ne prende prima di diventare un cerchio; nel sito 4 e 12.
RADIUSscript.js0.13Il raggio della ruota, in frazione del lato corto dello schermo (al telefono per 1,4); nel sito 0,13.
CHASEscript.js0.2Quanta strada verso lo scorrimento fa il disegno a ogni fotogramma: 1 lo segue subito, 0,05 arriva molto morbido; nel sito 0,2.
TYREscript.js0.13Lo spessore del copertone, in frazione del raggio.
DUSTscript.js1Lo sbuffo di polvere quando uno spigolo cade in una buca (0 = niente).
FLAGscript.js1Quanto la bandierina oscilla e rimbalza sul suo palo (0 = rigida).
RIDEscript.js1Quanto scorrimento serve per tutta la corsa: 2 è il doppio.

Provali nel Playground

Quando usarla

Per raccontare un metodo in pochi passi (un servizio, un processo, un percorso da A a B) dove l’idea è «da spigoloso a liscio»: officine, studi, consulenze, app che promettono di semplificare. La ruota fa capire il miglioramento senza parole.

Sul telefono

Uguale: la ruota è un po’ più grande in proporzione, i quattro passi stanno in fila con il solo nome e la riga del passo raggiunto compare sotto, cambiando con un rimbalzo.

Con il movimento ridotto

La ruota non rotola: aspetta ferma a ogni passo, con la forma che ha lì, e il disegno passa da una sosta all’altra con una dissolvenza. Niente polvere, bandierina dritta, entrata solo in dissolvenza.

Trappole

  • La rotazione non è lineare con la distanza: sopra una gobba la ruota gira più in fretta vicino agli spigoli (dx diviso r, e r è più grande lì). Con una rotazione in proporzione alla strada fatta, e gobbe larghe quanto il lato invece di 2a·asinh(tan(π/n)), il quadrato galleggia sulle buche o ci affonda.
  • Con un numero di lati frazionario la forma non è regolare, quindi le catenarie uguali non le vanno più bene: la strada qui si ricava dalla forma del momento, partendo dal punto di contatto, e l’angolo si somma una volta sola in una tabella. Così la ruota tocca sempre senza entrare nella strada, anche a metà fra due forme.
  • Gli spigoli delle buche si perdono se la strada si disegna punto per punto a passo fisso: va disegnata lato per lato, con i vertici esatti, e il tratto con lineJoin miter.
  • Un ciclo requestAnimationFrame sempre acceso consuma batteria anche a pagina ferma: qui il ticker c’è sempre, ma il canvas si ridisegna solo quando qualcosa è cambiato.

Librerie

GSAP 3.15.0, Lenis 1.3.26, Bricolage Grotesque (font variabile) 5.3.0, Fraunces (font variabile) 5.3.0, Red Hat Mono (font variabile) 5.3.0.

Compressi con gzip, i tre file della demo pesano 14 KB; le librerie: GSAP + ScrollTrigger 45 KB, Lenis 5,3 KB.

Collaudo

Provata il 13 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