Vai al contenuto
animorio
EN
Tutti i componenti

Il piè di pagina col giardino zen

Piè di pagina, Hover, 3DCanvas, GSAPImpegnativaPeso compresso: Demo 23 KBGSAP 28 KBGratisScarica lo zip

Il piè di pagina di una piccola casa del tè, tutto fatto di un giardino di sabbia rastrellata illuminato da un sole basso, con le pietre, il muschio e gli anelli intorno, e il nome della casa impresso nella sabbia lungo il fondo. Il puntatore è un rastrello che scava solchi dove passa, un link puntato si prende un anello rastrellato intorno alla sua parola, e l'iscrizione alle lettere fa passare un rastrello largo che lascia il giardino come nuovo.

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 zen garden footer</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/newsreader@5.3.0/opsz.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/newsreader@5.3.0/opsz-italic.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/mona-sans@5.3.0/wdth.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the footer of a small tea house: its whole ground is a raked sand garden lit by a low sun, with stones and
         moss and rings raked round them, and the house's name pressed into the sand along the bottom. The pointer is
         a rake that carves grooves where it goes, a link pointed at gets a ring raked round its word, and a sign-up
         to the letters brings a wide rake across that leaves the garden as new -->
    <footer class="zg" data-footer data-autoclic>
      <canvas class="zg__sand" aria-hidden="true" data-sand></canvas>
      <canvas class="zg__still" aria-hidden="true" data-still></canvas>
      <canvas class="zg__rake" aria-hidden="true" data-rake></canvas>

      <div class="zg__top">
        <form class="zg__form" action="#" novalidate aria-labelledby="zg-news" data-form>
          <h2 class="zg__title" id="zg-news" data-in>Letters from the tea house</h2>
          <p class="zg__lede" data-in>New harvests, tasting evenings and the garden through the year. One letter each season.</p>
          <label class="sr" for="zg-email">Email address</label>
          <div class="zg__field" data-field data-in>
            <input class="zg__input" id="zg-email" name="email" type="email" inputmode="email" autocomplete="email" autocapitalize="off" spellcheck="false" enterkeyhint="send" placeholder="you@example.com" aria-describedby="zg-note" aria-invalid="false" data-input>
            <button class="zg__send" type="submit" data-send>
              <span class="zg__send-bg"></span>
              <span class="zg__send-label" data-send-label>Subscribe</span>
              <svg class="zg__spin" viewBox="0 0 24 24" aria-hidden="true" data-spin><circle cx="12" cy="12" r="8"/></svg>
              <svg class="zg__done" viewBox="0 0 24 24" aria-hidden="true" data-done><path d="M6.4 12.6l3.7 3.7 7.6-8.6"/></svg>
            </button>
          </div>
          <p class="zg__note" id="zg-note" aria-live="polite" data-note data-in><span class="zg__line">Four letters a year. Leave with one click.</span></p>
        </form>

        <!-- where the stones lie: the script reads these boxes, the stones are drawn in the sand -->
        <div class="zg__garden" aria-hidden="true">
          <span class="zg__stone zg__stone--big" data-stone></span>
          <span class="zg__stone zg__stone--small" data-stone></span>
        </div>

        <nav class="zg__cols" aria-label="Footer">
          <div class="zg__col" data-in>
            <h3 class="zg__head">Visit</h3>
            <ul>
              <li><a class="zg__link" href="#" data-link>Opening hours</a></li>
              <li><a class="zg__link" href="#" data-link>Find us</a></li>
              <li><a class="zg__link" href="#" data-link>Private rooms</a></li>
              <li><a class="zg__link" href="#" data-link>Gift cards</a></li>
            </ul>
          </div>
          <div class="zg__col" data-in>
            <h3 class="zg__head">Tea</h3>
            <ul>
              <li><a class="zg__link" href="#" data-link>Our teas</a></li>
              <li><a class="zg__link" href="#" data-link>Tastings</a></li>
              <li><a class="zg__link" href="#" data-link>Tea ware</a></li>
              <li><a class="zg__link" href="#" data-link>Wholesale</a></li>
            </ul>
          </div>
          <div class="zg__col" data-in>
            <h3 class="zg__head">House</h3>
            <ul>
              <li><a class="zg__link" href="#" data-link>Our story</a></li>
              <li><a class="zg__link" href="#" data-link>The garden</a></li>
              <li><a class="zg__link" href="#" data-link>Journal</a></li>
              <li><a class="zg__link" href="#" data-link>Contact</a></li>
            </ul>
          </div>
        </nav>
      </div>

      <div class="zg__base" data-in>
        <p class="zg__brand">
          <svg class="zg__mark" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 22V3.2"/><path d="M12 6.4L8.6 9.6M12 6.4l3.4 3.2"/><path d="M12 10.6l-5 4.4M12 10.6l5 4.4"/><path d="M12 15l-6.6 5.2M12 15l6.6 5.2"/></svg>
          <span class="zg__copy"><svg viewBox="0 0 12 12" aria-hidden="true"><circle cx="6" cy="6" r="5.1"/><path d="M7.9 4.5a2.3 2.3 0 1 0 0 3"/></svg><span class="sr">Copyright</span> 2026 Hollow Pine Tea House</span>
          <span class="zg__hours">Open Wednesday to Sunday, 10 till 6</span>
        </p>
        <nav class="zg__legal" aria-label="Legal">
          <a class="zg__link zg__link--small" href="#" data-link>Privacy</a>
          <a class="zg__link zg__link--small" href="#" data-link>Terms</a>
          <a class="zg__link zg__link--small" href="#" data-link>Cookies</a>
        </nav>
      </div>

      <!-- the house's name: real text, pressed into the sand by the script where the text stands -->
      <div class="zg__foot">
        <p class="zg__name" data-name><span data-word>Hollow</span> <span data-word>Pine</span></p>
        <span class="zg__stone zg__stone--corner" aria-hidden="true" data-stone></span>
      </div>
    </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.

61 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 «Il piè di pagina col giardino zen» da Animorio e adattala al mio sito

Cosa fa

Su un fondo bianco un piè di pagina con gli angoli tondi, largo 1080 pixel e alto circa 400, di Hollow Pine, una casa del tè inventata. Tutto il suo fondo è un giardino di sabbia chiara rastrellata in lunghe righe dritte, illuminato da un sole basso che arriva da sinistra in alto: ogni solco è una riga di luce e una d'ombra, e la sabbia ha la sua grana. A sinistra l'iscrizione alle lettere della casa (Letters from the tea house, una riga che dice cosa arriva, il campo dell'email chiaro col pulsante Subscribe dentro e una riga d'aiuto sotto), a destra tre colonne di link (Visit, Tea, House), fra loro due pietre scure in un cuscino di muschio, con tre anelli rastrellati intorno che si fondono in uno solo, e una terza pietra nell'angolo in basso; poi il marchio (un pino disegnato), il copyright, l'orario e i link legali, e lungo tutto il fondo il nome Hollow Pine impresso nella sabbia in grandi lettere graziate: il fondo delle lettere è liscio e un po' più scuro, le pareti prendono la luce da una parte e l'ombra dall'altra, e intorno la sabbia è stata spinta su. Le pietre fanno la loro ombra sulla sabbia, sono granito con le crepe e la grana, e il muschio sale dal piede dalla parte in ombra. Quando il piè di pagina entra in vista la sabbia è liscia e un rastrello largo, una barra di legno alta quanto il piè di pagina coi denti nella sabbia, la attraversa da sinistra a destra lasciando dietro di sé le righe, gli anelli e il nome. Il puntatore sulla sabbia è un piccolo rastrello di bambù a cinque denti, tirato per il manico: la testa resta indietro e gira per seguirlo, e dove passa lascia cinque solchi paralleli, coi bordi di sabbia spinta su, che tagliano le righe, gli anelli e anche il nome, che si consuma; i solchi restano. Sopra un link o il campo il rastrello si alza e sparisce; puntando un link, o arrivandoci col tasto Tab, un piccolo rastrello a due denti traccia un anello ovale intorno alla parola, partendo da sinistra, e dentro la sabbia si liscia, così la parola sta in una pozza ferma; andandosene la sabbia si riassesta com'era. L'iscrizione ha i suoi stati: un indirizzo sbagliato fa tremare il campo e la riga sotto dice in rosso mattone cosa non va; uno giusto fa uscire la parola dal pulsante, che si stringe in un cerchio con l'arco che gira e poi una spunta, la riga sotto ringrazia con una foglia, e il rastrello largo passa di nuovo su tutto il piè di pagina, da sinistra a destra, spingendo davanti a sé un po' di sabbia: dietro di lui il giardino torna come appena rastrellato, coi solchi spariti e il nome di nuovo intero.

Come funziona

La sabbia è una mappa d'altezza

La sabbia è un'altezza ogni CELL pixel, disegnata su un canvas di quella misura che il browser allarga sfumando. Per ogni punto la pendenza viene dalle differenze coi vicini, e un sole basso (SUN e SUN_HEIGHT) la illumina alla Lambert: la luce che prende, divisa per quella del terreno piatto, sceglie fra tre colori della sabbia (piatta, al sole, in ombra), una cavità prende un po' d'ombra (il laplaciano) e la luce si scalda appena dalla parte del sole. La grana è un rumore nell'altezza di ogni punto più una polvere fine di granelli chiari e scuri disegnata una volta sola ai pixel dello schermo.

Il giardino appena rastrellato

Si calcola una volta: righe dritte con un'onda lenta e una profondità che varia appena, come rastrellate a mano; anelli intorno alle pietre misurati dal bordo del muschio lungo il raggio che parte dal centro della pietra, più tondi man mano che si allontanano, con le righe che finiscono sulla cresta più esterna. Il nome si disegna col suo carattere su un canvas nascosto, grande il doppio, proprio dove stanno le parole vere (il riquadro di ogni parola più fontBoundingBoxAscent); la sfocatura ne fa le pareti dello stampo, il fondo è piatto e un po' più scuro, intorno la sabbia è lisciata e sollevata.

Il rastrello tirato per il manico

La testa del rastrello si muove solo quando il puntatore è più lontano di HANDLE pixel, e allora dritta verso di lui: così resta indietro e gira per seguirlo, e i denti stanno sempre di traverso. Fra due posizioni del puntatore si va a passi di 0,7 punti, così un gesto veloce non salta niente. A ogni passo la sabbia dentro la larghezza del rastrello prende il profilo dei denti (un coseno con le conche tonde e le creste più strette), i denti esterni ammucchiano una cresta e appena fuori la sabbia spinta via sale; dove ci sono pietre e muschio non si scava. Si illumina di nuovo solo il rettangolo toccato, col rettangolo sporco di putImageData.

Gli anelli intorno ai link

Un anello non si scrive nella sabbia: mentre la si illumina, il suo nastro (due denti) prende il posto della sabbia sotto, fin dove GSAP l'ha già tracciato (l'angolo contato dall'estremo sinistro, con la punta morbida), e dentro l'ovale la sabbia si liscia. La distanza dall'ovale viene dall'equazione dell'ellisse divisa per la sua pendenza. Andandosene la sua forza scende a zero e sotto ricompare la sabbia com'era, solchi compresi.

Il rastrello largo, le pietre e il muschio

Dopo l'iscrizione un tween di GSAP porta il fronte da sinistra a destra in SWEEP secondi: ogni colonna che passa riprende la sabbia appena rastrellata, e davanti alla barra si gonfia un mucchietto di sabbia spinta. La barra coi denti e il rastrello piccolo si disegnano su un terzo canvas, con l'ombra. Pietre, muschio e ombre si disegnano una volta, pixel per pixel, alla risoluzione dello schermo: un masso piatto in cima e tondo alle spalle, crepe da un rumore a creste, la grana del granito, un velo di lucido, un cuscino di muschio fatto di cupolette e il muschio che sale dal lato in ombra; l'ombra portata è la sagoma disegnata fuori dal canvas con la sua ombra sfocata riportata dentro.

Valori da cambiare

NomeFileDi partenzaCosa cambia
TINESscript.js5Quanti denti ha il rastrello: tanti solchi lascia a ogni passata.
TINE_GAPscript.js9Quanto sono distanti i denti, in pixel: un solco e una cresta. Vale anche per le righe e gli anelli del giardino.
DEPTHscript.js1.2Quanto scavano i denti, in pixel di sabbia: di più fa solchi più netti, con più luce e più ombra.
PRESSscript.js2.6Quanto è impresso nella sabbia il nome lungo il fondo, in pixel: a 0 sparisce.
SUNscript.js125Da dove arriva il sole, in gradi intorno al piè di pagina: 90 dall'alto, 180 da sinistra. Da sinistra pura le righe orizzontali quasi spariscono.
SUN_HEIGHTscript.js24Quanto è alto il sole, in gradi: più basso fa i solchi più marcati e le ombre delle pietre più lunghe.
GRAINscript.js0.6Quanta grana ha la sabbia: a 0 è liscia come gesso.
RINGSscript.js3Quanti anelli sono rastrellati intorno a ogni pietra.
CELLscript.js2Quanti pixel copre ogni punto della sabbia: di più è meno lavoro e sabbia più morbida, di meno più dettaglio.
HANDLEscript.js34Quanto resta indietro la testa del rastrello rispetto al puntatore, in pixel: di più fa curve più larghe e morbide.
SWEEPscript.js1.9Quanto ci mette il rastrello largo ad attraversare il piè di pagina dopo un'iscrizione, in secondi.
WAITscript.js1.1Quanto dura l'iscrizione nella demo, in secondi.

Provali nel Playground

Quando usarla

Per il piè di pagina di una casa del tè, di una spa, di un ritiro di meditazione, di un'app per la calma o il sonno, di un vivaio di bonsai, di un ceramista o di uno studio di architettura del paesaggio: ovunque il fondo della pagina possa essere un posto dove fermarsi un momento e giocare con la sabbia.

Sul telefono

Il piè di pagina prende la larghezza dello schermo e diventa una colonna più alta: la newsletter, poi una striscia di sabbia libera con le due pietre e i loro anelli, poi le tre colonne di link, il marchio, l'orario e i link legali, e il nome impresso su due righe, Hollow e Pine, con la terza pietra accanto a Pine. La sabbia ha meno punti ma la stessa grana. Un dito trascinato di lato rastrella (su e giù scorre la pagina), e il rastrello si vede finché il dito è giù; toccando un link l'anello si traccia intorno alla parola e resta un momento.

Con il movimento ridotto

Niente passa da solo: il giardino è già rastrellato quando il piè di pagina compare, in dissolvenza. Il rastrello resta, perché lo muove la mano. Un link puntato ha il suo anello già chiuso, che compare in dissolvenza insieme alla pozza liscia; il campo sbagliato non trema, il pulsante non si stringe e l'arco sta fermo; all'iscrizione il rastrello largo non passa e il giardino torna come nuovo in dissolvenza, dove si trova.

Trappole

  • Con il sole da sinistra pura le righe orizzontali, che hanno la pendenza solo in verticale, non prendevano luce e sparivano: il sole arriva da sinistra in alto (125 gradi), così si vedono sia le righe sia i solchi di traverso.
  • Per imprimere il nome dove sta il testo vero serve la linea di base giusta: il riquadro di una parola in linea comincia a fontBoundingBoxAscent sopra la linea di base, quindi il canvas scrive lì, e il testo vero resta trasparente (per chi legge con lo schermo).
  • Con la riga alta, le aste di H, l e P toccavano la riga del copyright: misurate con actualBoundingBoxAscent, il nome è sceso a 132 pixel con un'interlinea di 0,62, e il piè di pagina resta alto 402.
  • L'anello intorno a un link all'inizio stringeva la parola: il solco interno finiva sotto le lettere e l'hover quasi non si vedeva. Ora l'ovale è più largo, il solco più profondo e dentro la sabbia si liscia, così la parola sta in una pozza ferma.
  • Il rastrello alzato sopra un link restava disegnato a metà trasparenza sopra le parole: ora sopra i link e il campo sparisce, e torna appena la mano è di nuovo sulla sabbia.
  • Il grazie dopo l'iscrizione andava a capo, il piè di pagina cresceva e il cambio di misura rifaceva la sabbia da capo, fermando il rastrello largo a metà. Ora una nuova misura riporta i solchi dove stavano sulla pagina (una maschera ricorda dove ha rastrellato una mano) e lascia finire il rastrello largo; al telefono la riga sotto il campo ha posto per due righe.
  • Al telefono la parola Hollow, che non si spezza, allargava la colonna della pagina oltre lo schermo e il margine destro scendeva a 9 pixel: il nome ha una misura che segue lo schermo e la colonna è minmax(0, 1fr).
  • Su un tablet, fra 780 e 960 pixel, il nome su una riga finiva sotto la pietra dell'angolo: lì la sua misura segue la larghezza lasciando il posto alla pietra, e sotto i 780 va su due righe con la pietra accanto a Pine.
  • Le prime pietre erano una cupola di rumore liscia e sembravano di plastica, col muschio a macchie verdi come vernice: ora sono piatte in cima, con le crepe e la grana del granito ai pixel dello schermo, e il muschio sale dal piede dalla parte in ombra.
  • L'ombra delle pietre non usa ctx.filter, che Safari non conosce: la sagoma si disegna fuori dal canvas e se ne riporta dentro l'ombra sfocata (shadowBlur e shadowOffset, che non seguono la trasformazione e vanno moltiplicati per la densità dei pixel).

Librerie

GSAP 3.15.0, Newsreader (font variabile) 5.3.0, Mona Sans (font variabile) 5.3.0.

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

Collaudo

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

Tutti i componenti