Vai al contenuto
animorio
EN
Torna alla libreria

La torta a strati

Scroll, SVGGSAPImpegnativaPeso compresso: Demo 19 KBGSAP + ScrollTrigger 45 KBLenis 5,3 KBGratisScarica lo zip

Scorri dentro l’anteprima

La pagina di una pasticceria: scendendo, su un’alzata che gira piano si monta una torta. Il primo disco di pan di spagna cade e rimbalza, la spatola stende la crema, piovono i frutti di bosco, arriva il secondo disco, la glassa al cioccolato cola lungo i bordi in goccioloni, la sac à poche fa le roselline e spuntano le candeline accese. In fondo due tagli, e una fetta esce e si gira per mostrare gli strati. Tornando su la torta si smonta.

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="it">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>La torta a strati</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/full.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/mona-sans@5.3.0/standard.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!-- la testata della pasticceria inventata -->
  <header class="testata">
    <p class="marchio">Bramble <span>&amp; Butter</span></p>
    <nav class="menu" aria-label="Main">
      <a href="#torta">Cakes</a>
      <a href="#fine">Order</a>
      <a href="#fine">Visit</a>
    </nav>
  </header>

  <main>
    <!-- l'apertura -->
    <section class="apertura">
      <p class="apertura__etichetta" data-entra>A small cake shop on Mill Lane</p>
      <h1 class="apertura__titolo">
        <span class="riga"><span data-titolo>Built</span></span>
        <span class="riga"><span data-titolo><em>layer by layer.</em></span></span>
      </h1>
      <p class="apertura__testo" data-entra>Our Sunday sponge, from the first bounce to the last candle. Scroll down and watch it rise on the stand.</p>
      <p class="apertura__cenno" data-entra>
        Scroll to build
        <svg viewBox="0 0 24 32" aria-hidden="true"><path d="M12 3V27M4 19L12 28L20 19" /></svg>
      </p>
      <div class="ciliegie" aria-hidden="true">
        <svg class="ciliegia" viewBox="0 0 60 90" data-ciliegia><path d="M31 46C30 30 34 16 46 6" class="ciliegia__gambo" /><path d="M46 6C52 8 56 13 55 18C49 18 46 13 46 6Z" class="ciliegia__foglia" /><circle cx="30" cy="64" r="22" class="ciliegia__corpo" /><path d="M17 58C18 52 22 48 27 47" class="ciliegia__luce" /></svg>
        <svg class="ciliegia" viewBox="0 0 60 90" data-ciliegia><path d="M31 46C30 30 34 16 46 6" class="ciliegia__gambo" /><path d="M46 6C52 8 56 13 55 18C49 18 46 13 46 6Z" class="ciliegia__foglia" /><circle cx="30" cy="64" r="22" class="ciliegia__corpo" /><path d="M17 58C18 52 22 48 27 47" class="ciliegia__luce" /></svg>
        <svg class="ciliegia" viewBox="0 0 60 90" data-ciliegia><path d="M31 46C30 30 34 16 46 6" class="ciliegia__gambo" /><path d="M46 6C52 8 56 13 55 18C49 18 46 13 46 6Z" class="ciliegia__foglia" /><circle cx="30" cy="64" r="22" class="ciliegia__corpo" /><path d="M17 58C18 52 22 48 27 47" class="ciliegia__luce" /></svg>
      </div>
    </section>

    <!-- la torta: il palco resta fermo e, scorrendo, si monta strato dopo strato -->
    <section class="storia" id="torta" data-storia>
      <div class="palco">
        <div class="racconto">
          <nav class="ricetta" aria-label="Steps">
            <button type="button" data-voce>Sponge</button>
            <button type="button" data-voce>Cream</button>
            <button type="button" data-voce>Berries</button>
            <button type="button" data-voce>Stack</button>
            <button type="button" data-voce>Glaze</button>
            <button type="button" data-voce>Pipe</button>
            <button type="button" data-voce>Candles</button>
            <button type="button" data-voce>Slice</button>
          </nav>

          <div class="passi">
            <article class="passo" data-passo>
              <p class="passo__etichetta" data-linea>The sponge</p>
              <h2 class="passo__titolo">
                <span class="riga"><span data-riga>Drop the</span></span>
                <span class="riga"><span data-riga>first <em>layer.</em></span></span>
              </h2>
              <p class="passo__testo" data-linea>Vanilla sponge, baked the night before so it holds its shape. It lands, it bounces, it settles.</p>
            </article>
            <article class="passo" data-passo>
              <p class="passo__etichetta" data-linea>The cream</p>
              <h2 class="passo__titolo">
                <span class="riga"><span data-riga>Spread it thin,</span></span>
                <span class="riga"><span data-riga>turn the <em>stand.</em></span></span>
              </h2>
              <p class="passo__testo" data-linea>Mascarpone from the middle out. The stand does the turning, the spatula stays still.</p>
            </article>
            <article class="passo" data-passo>
              <p class="passo__etichetta" data-linea>The berries</p>
              <h2 class="passo__titolo">
                <span class="riga"><span data-riga>Let it rain</span></span>
                <span class="riga"><span data-riga><em>berries.</em></span></span>
              </h2>
              <p class="passo__testo" data-linea>Raspberries, blueberries and strawberries, wherever they land. No two cakes look the same inside.</p>
            </article>
            <article class="passo" data-passo>
              <p class="passo__etichetta" data-linea>The stack</p>
              <h2 class="passo__titolo">
                <span class="riga"><span data-riga>Second layer,</span></span>
                <span class="riga"><span data-riga><em>gently.</em></span></span>
              </h2>
              <p class="passo__testo" data-linea>Just enough weight for the cream to peek out at the edges, and no more.</p>
            </article>
            <article class="passo" data-passo>
              <p class="passo__etichetta" data-linea>The glaze</p>
              <h2 class="passo__titolo">
                <span class="riga"><span data-riga>Pour it warm,</span></span>
                <span class="riga"><span data-riga>let it <em>drip.</em></span></span>
              </h2>
              <p class="passo__testo" data-linea>Dark chocolate, warm but never hot, so it rolls over the edge in slow, fat drips.</p>
            </article>
            <article class="passo" data-passo>
              <p class="passo__etichetta" data-linea>The piping</p>
              <h2 class="passo__titolo">
                <span class="riga"><span data-riga>One swirl</span></span>
                <span class="riga"><span data-riga>per <em>turn.</em></span></span>
              </h2>
              <p class="passo__testo" data-linea>Raspberry buttercream round the rim. The bag stays put and the stand brings every spot to it.</p>
            </article>
            <article class="passo" data-passo>
              <p class="passo__etichetta" data-linea>The candles</p>
              <h2 class="passo__titolo">
                <span class="riga"><span data-riga>Light them</span></span>
                <span class="riga"><span data-riga><em>all.</em></span></span>
              </h2>
              <p class="passo__testo" data-linea>Striped candles in the middle. Make a wish before the knife comes out.</p>
            </article>
            <article class="passo" data-passo>
              <p class="passo__etichetta" data-linea>The slice</p>
              <h2 class="passo__titolo">
                <span class="riga"><span data-riga>Two cuts,</span></span>
                <span class="riga"><span data-riga>lift it <em>out.</em></span></span>
              </h2>
              <p class="passo__testo" data-linea>Sponge, cream, berries, sponge, glaze. Scroll back up and the cake comes apart again.</p>
            </article>
          </div>

          <p class="misura">On the stand <strong><span data-peso>0</span> g</strong></p>
        </div>

        <svg class="scena" data-scena viewBox="0 130 600 630" preserveAspectRatio="xMidYMax meet" aria-hidden="true">
          <defs>
            <linearGradient id="grad-alzata" x1="0" y1="0" x2="1" y2="0">
              <stop offset="0" class="stop-alzata-scura" />
              <stop offset="0.4" class="stop-alzata" />
              <stop offset="0.6" class="stop-alzata-chiara" />
              <stop offset="1" class="stop-alzata-scura" />
            </linearGradient>
            <linearGradient id="grad-acciaio" x1="0" y1="0" x2="1" y2="1">
              <stop offset="0" class="stop-acciaio-chiaro" />
              <stop offset="0.5" class="stop-acciaio" />
              <stop offset="1" class="stop-acciaio-scuro" />
            </linearGradient>
            <linearGradient id="grad-rame" x1="0" y1="0" x2="1" y2="0">
              <stop offset="0" class="stop-rame-scuro" />
              <stop offset="0.45" class="stop-rame" />
              <stop offset="1" class="stop-rame-scuro" />
            </linearGradient>
          </defs>

          <!-- l'alzata: piede, gambo e piatto; le scanalature del bordo girano -->
          <g data-alzata>
            <ellipse cx="300" cy="744" rx="150" ry="16" class="ombra-alzata" />
            <path d="M195 718V730A105 22 0 0 0 405 730V718Z" fill="url(#grad-alzata)" />
            <ellipse cx="300" cy="718" rx="105" ry="22" class="alzata-sopra" />
            <path d="M276 600C276 640 286 660 286 680C286 700 240 706 222 716C250 726 350 726 378 716C360 706 314 700 314 680C314 660 324 640 324 600Z" fill="url(#grad-alzata)" />
            <path d="M100 590V604A200 60 0 0 0 500 604V590Z" fill="url(#grad-alzata)" />
            <path class="scanalature" data-scanalature />
            <ellipse cx="300" cy="590" rx="200" ry="60" class="alzata-sopra" />
            <ellipse cx="300" cy="590" rx="186" ry="54" class="alzata-incavo" />
          </g>

          <!-- la torta (i pezzi li disegna lo script) -->
          <ellipse class="ombra-torta" data-ombra />
          <g data-torta></g>
          <g data-fetta></g>

          <!-- gli attrezzi -->
          <g data-spatola>
            <path d="M150 0C186 -4 196 -30 214 -54" class="spatola-collo" />
            <path d="M0 -5C-7 -5 -9 5 0 6L156 7C162 7 164 -6 156 -6Z" fill="url(#grad-acciaio)" class="spatola-lama" />
            <path d="M206 -46L282 -100" class="spatola-manico" />
          </g>
          <g data-pentola>
            <g data-pentola-corpo>
              <path d="M-96 18L-196 4" class="pentola-manico" />
              <path d="M2 -3C-4 0 -8 3 -10 8L-12 52C-12 62 -20 68 -30 68H-86C-96 68 -104 62 -104 52L-104 6C-104 2 -100 0 -96 0H-14C-8 -2 -3 -4 2 -3Z" fill="url(#grad-rame)" class="pentola" />
              <path d="M-100 4H-12" class="pentola-bordo" />
            </g>
          </g>
          <path class="filo-glassa" data-filo />
          <g data-sac>
            <path d="M-8 -16C-30 -56 -44 -104 -26 -142L44 -152C58 -112 40 -56 8 -16Z" class="sac" />
            <path d="M-26 -142C-14 -150 30 -158 44 -152L48 -166C30 -172 -12 -166 -28 -156Z" class="sac-nodo" />
            <path d="M-14 -40C-2 -38 8 -40 18 -46" class="sac-piega" />
            <path d="M0 2L-9 -18H9Z" fill="url(#grad-acciaio)" />
          </g>
          <g data-coltello-clip-g>
            <clipPath id="taglio"><path data-coltello-clip /></clipPath>
            <g clip-path="url(#taglio)">
              <path class="coltello-lama" fill="url(#grad-acciaio)" data-lama />
              <path class="coltello-manico" data-manico />
            </g>
          </g>

          <!-- dove il puntatore fa tremare la torta -->
          <ellipse cx="300" cy="540" rx="210" ry="150" class="presa" data-presa />
        </svg>
      </div>
    </section>

    <footer class="fine" id="fine">
      <p class="fine__frase">Your slice is waiting. <em>Come by on Sunday.</em></p>
      <a class="fine__bottone" href="#torta"><span>Order a cake</span></a>
    </footer>
  </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.

98 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 torta a strati» da Animorio e adattala al mio sito

Cosa fa

La pagina di una pasticceria inventata, Bramble & Butter, su un fondo color crema. In apertura un titolo grande, «Built layer by layer.», e tre ciliegie che cadono rimbalzando e poi dondolano sul gambo; il puntatore le fa saltare. Sotto, il palco si ferma: a destra un’alzata verde menta vista dall’alto di poco, con le scanalature del bordo che girano, a sinistra il racconto in otto passaggi, con i loro nomi in alto (Sponge, Cream, Berries, Stack, Glaze, Pipe, Candles, Slice) e i grammi sull’alzata che salgono. Scorrendo, il primo disco di pan di spagna cade dall’alto, rimbalza e si schiaccia ondeggiando, mentre la sua ombra si stringe sul piatto. Entra una spatola a gomito, appoggiata sul disco dal centro al bordo: è l’alzata che gira sotto di lei, e la crema si allarga a cerchi fino a uscire un poco dal bordo, lasciando i segni della spatola. Piovono lamponi, mirtilli e mezze fragole, ognuno col suo rimbalzo e la sua rotazione. Cade il secondo disco, e quando si schiaccia la crema sotto sborda. Un pentolino di rame entra, si inclina e versa un filo di glassa al cioccolato nel centro: la glassa si allarga sopra e poi scende lungo i bordi in goccioloni, ognuno lungo a modo suo e con la goccia in fondo. La sac à poche si ferma su un punto del bordo e preme a ogni rosellina, mentre l’alzata fa un giro intero e porta sotto la bocchetta tutti i posti. Le candeline a righe cadono nel centro con un piccolo rimbalzo e si accendono una dopo l’altra, con la fiamma che trema. In fondo un coltello scende due volte, dove taglia resta il segno; poi la fetta viene tirata in avanti su una paletta, l’alzata si sposta a sinistra e la fetta si gira finché il taglio guarda verso di noi: pan di spagna, crema coi frutti, pan di spagna, glassa. Nella torta resta lo spacco, con gli strati anche lì, e i grammi scendono. Scorrendo indietro tutto torna al contrario. Il puntatore sulla torta la fa tremare come una gelatina; i nomi dei passaggi portano al loro punto.

Come funziona

Il palco fermo

La sezione è alta SCROLL_LENGTH schermi e dentro c’è un palco sticky alto 100lvh: a sinistra il racconto, a destra un SVG con viewBox fisso e preserveAspectRatio xMidYMax meet, così l’alzata resta appoggiata in basso a ogni misura. L’alzata è disegnata una volta sola; la torta, i frutti, le roselline e le candeline li crea lo script, e gli attrezzi (spatola, pentolino, sac à poche, coltello) stanno sopra a tutto.

Una timeline di numeri

Tutto quello che si muove è un numero in un oggetto: quanto è caduto ogni disco, quanto ondeggia, quanto si è allargata la crema, la glassa, le colate, la sac à poche, il giro dell’alzata, il coltello, la fetta. Una sola timeline in pausa li muove, ognuno con la sua curva (bounce.out per i dischi e i frutti, back.out per gli attrezzi che entrano, elastic.out per le fiamme). Un tween porta la sua time da 0 alla fine con uno ScrollTrigger in scrub: scorrendo su la timeline va indietro e la torta si smonta.

Un cilindro visto dall’alto

Ogni strato è un cilindro schiacciato: un’ellisse sopra (il raggio per 0,3 in altezza) e la fascia davanti, cioè gli angoli da 0 a 180 gradi. Un ticker di GSAP rifà i tracciati a ogni fotogramma con il fondo, l’altezza e il raggio di ogni strato: il disco che atterra si abbassa e si allarga con un seno smorzato. Tutto quello che sta sulla torta (briciole, frutti, colate, roselline, candeline) ha un suo angolo: si aggiunge il giro dell’alzata, e quello che passa dietro sparisce o si ordina dietro agli altri.

La sac à poche ferma

Le roselline non vanno a cercare la sac à poche: è l’alzata che gira di 360 gradi mentre la sac à poche resta su un punto del bordo. L’angolo di ogni rosellina è calcolato perché passi sotto la bocchetta proprio quando tocca a lei, e lì cresce con elastic.out. Le candeline invece stanno su un cerchio piccolo, girate in modo che alla fine nessuna sia dove passerà il coltello.

La fetta

Dopo i due tagli la stessa funzione disegna due pezzi: la torta con lo spacco (gli angoli da 108 a 432 gradi) e la fetta (da 72 a 108). Ogni pezzo ha le sue facce del taglio, dei quadrilateri dal centro al bordo, visibili solo quando guardano verso di noi, con dentro i frutti e i buchi del pan di spagna. La fetta si sposta e il suo angolo scende di 108 gradi: alla fine la faccia del taglio è dritta davanti a noi. Il coltello è ritagliato da un clipPath che nasconde la parte già dentro la torta.

Valori da cambiare

NomeFileDi partenzaCosa cambia
SCROLL_LENGTHscript.js7Quanti schermi di scorrimento dura tutta la torta: di più è più lenta.
BERRIESscript.js18Quanti frutti di bosco piovono sulla crema.
DRIPSscript.js14Quante colate di glassa scendono lungo i bordi.
DRIP_LENGTHscript.js1Quanto scendono le colate: 0,4 corte, 1,6 quasi fino al piatto.
ROSETTESscript.js12Quante roselline di crema al burro intorno al bordo.
CANDLESscript.js5Quante candeline nel centro (al massimo 7, perché il coltello passi fra due).
SPINscript.js1Quanto gira l’alzata mentre si scorre: 0 ferma (per le roselline fa comunque un giro).
SQUASHscript.js1Quanto si schiacciano e ondeggiano i dischi quando atterrano; accanto c’è CAKE_GRAMS per il contatore.
--glassastyle.css#4a2216Il colore della glassa; accanto ci sono quelli del pan di spagna, della crema, dei frutti, delle roselline, delle candeline e dell’alzata.

Provali nel Playground

Quando usarla

Per chi vende o racconta qualcosa che si monta a strati: una pasticceria, una torta su ordinazione, un catering, un corso di cake design, una ricetta da seguire passo passo, ma anche un prodotto fatto di parti che si sovrappongono, come un panino, un materasso o un pacchetto con i suoi livelli.

Sul telefono

La stessa animazione con le misure adattate: il racconto sta in alto, più piccolo, con i nomi dei passaggi su due righe e sotto i grammi in piccolo, e l’alzata nello spazio che resta, appoggiata al fondo dello schermo. Un tocco sulla torta la fa tremare, uno sulle ciliegie le fa saltare.

Con il movimento ridotto

Niente cadute, niente colate, niente giri, niente scorrimento morbido: a ogni passaggio la torta e il testo spariscono in dissolvenza e tornano col passaggio già fatto (il disco al suo posto, la crema stesa, i frutti, la glassa colata, le roselline, le candeline accese con la fiamma ferma, la fetta fuori). Anche il titolo e le ciliegie dell’apertura compaiono in dissolvenza.

Trappole

  • Un tracciato a forma di torta intera, con un pezzo «nascosto» sopra, non permette di tirare fuori una fetta: lo spacco resterebbe pieno. La stessa funzione disegna un settore di cilindro qualsiasi (da un angolo a un altro), con le sue facce del taglio visibili solo quando guardano verso di noi (il coseno dell’angolo dice da che parte stanno). Prima del taglio disegna la torta intera, dopo due settori che combaciano.
  • I frutti, le roselline e le candeline stanno in un gruppo per pezzo: dopo il taglio quelli che cadono nella fetta passano nel gruppo della fetta (appendChild), altrimenti resterebbero sospesi nello spacco. Tornando su, prima del taglio, tornano nella torta.
  • Con le roselline e le candeline in un ordine fisso, quelle dietro coprivano quelle davanti quando l’alzata girava. A ogni fotogramma si ordinano per profondità (il seno dell’angolo), ma si rimettono nel DOM solo se l’ordine è cambiato.
  • Con il movimento ridotto, fermare la timeline alla fine di un passaggio lasciava il testo a metà uscita (le righe escono mezzo secondo prima del passaggio dopo). Il testo del passaggio mostrato si mette visibile a mano, e gli altri spenti.
  • Una candelina poteva finire proprio dove passa il coltello e venire tagliata a metà. Le candeline sono girate in modo che il centro della fetta cada fra due di loro, e sono al massimo sette, così la più vicina resta fuori dal taglio.

Librerie

GSAP 3.15.0, Lenis 1.3.26, Fraunces (font variabile) 5.3.0, Mona Sans (font variabile) 5.3.0.

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

Collaudo

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