Vai al contenuto
animorio
EN
Torna alla libreria

Il logo rosicchiato dal bruco

Intro, SVG, TestoGSAPImpegnativaPeso compresso: Demo 23 KBGSAP 28 KBGratisScarica lo zip

L’anteprima di un logo raccontata come un piccolo documentario: le lettere spuntano come germogli, un bruco paffuto scende su un filo di seta, cammina sul bordo delle lettere e le rosicchia a morsi smerlati, scava un tunnel in una lettera, si chiude nel bozzolo e ne esce una farfalla che si porta via il puntino della i. Nel Playground ci metti il tuo nome o carichi il tuo logo.

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 caterpillar-nibbled logo</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fredoka@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="scena">
    <!-- the stage: the script measures it, writes the logo in it and walks the caterpillar along its top -->
    <svg class="palco" data-stage role="img" aria-label="Olivebud" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <!-- the bites: everything white stays, the black circles are the holes in the logo -->
        <mask id="nibble" maskUnits="userSpaceOnUse" data-nibble-mask>
          <rect fill="#fff" data-nibble-full />
          <g fill="#000" data-nibble></g>
        </mask>
        <!-- the new growth that fills the bites when the logo heals: only inside the holes -->
        <mask id="grow" maskUnits="userSpaceOnUse" data-grow-mask>
          <rect fill="#000" data-grow-full />
          <g fill="#fff" data-grow></g>
        </mask>
        <!-- inside the tunnel the caterpillar is hidden under the top of the letter, except in the holes -->
        <mask id="hide" maskUnits="userSpaceOnUse" data-hide-mask>
          <rect fill="#fff" data-hide-full />
          <path fill="#000" data-hide-shape />
          <g fill="#fff" data-hide-holes></g>
        </mask>
        <!-- the piece of logo the butterfly carries away -->
        <clipPath id="loot-cut" clipPathUnits="userSpaceOnUse" data-loot-cut></clipPath>
        <!-- the little leaf, eaten bite by bite (in the leaf's own units) -->
        <mask id="leaf-bites" maskUnits="userSpaceOnUse" x="-80" y="-140" width="160" height="170">
          <rect fill="#fff" x="-80" y="-140" width="160" height="170" />
          <g fill="#000">
            <circle cx="-18" cy="-36" r="0" data-leaf-bite />
            <circle cx="-10" cy="-76" r="0" data-leaf-bite />
            <circle cx="16" cy="-66" r="0" data-leaf-bite />
            <circle cx="12" cy="-22" r="0" data-leaf-bite />
            <circle cx="0" cy="-2" r="0" data-leaf-bite />
          </g>
        </mask>
        <!-- the eyes keep the irises inside them -->
        <clipPath id="eye-near"><circle cx="7" cy="-7" r="8.2" /></clipPath>
        <clipPath id="eye-far"><circle cx="18" cy="-6" r="6" /></clipPath>
        <!-- the dark tip of the butterfly's fore wing -->
        <clipPath id="fore-wing"><path d="M6 -2C22 -46 70 -88 96 -72C114 -60 102 -20 78 -4C56 10 24 8 6 -2Z" /></clipPath>

        <!-- one segment of the caterpillar, drawn once and copied by the script: centre 0 0, walking to the right,
             feet down. The feet are behind the body, so only their ends show -->
        <g data-seg-model>
          <path class="zampa zampa--lontana" d="M-10 10L-10 22Q-10 26.5 -5.5 26.5Q-1 26.5 -1 22L-1 10Z" data-foot-far />
          <path class="zampa" d="M2 10L2 23Q2 27.5 6.5 27.5Q11 27.5 11 23L11 10Z" data-foot-near />
          <circle class="bruco" r="20" />
          <path class="bruco-pancia" d="M-17.5 6A18.5 18.5 0 0 0 17.5 6Q0 12.5 -17.5 6Z" />
          <path class="bruco-macchia" d="M-9 -13C-6 -18 2 -18 4 -13C2 -9 -6 -9 -9 -13Z" />
          <path class="bruco-lucido" d="M-12 -8Q-8 -15 0 -16.5" />
        </g>

        <!-- one wing of the butterfly, the right one: the left one is the same, mirrored -->
        <g id="wing">
          <path class="ala ala--dietro" d="M6 4C40 0 88 28 80 62C74 88 40 92 22 72C12 60 6 34 6 4Z" />
          <path class="ala-macchia" d="M44 58C48 50 60 50 62 58C60 66 48 66 44 58Z" />
          <path class="ala" d="M6 -2C22 -46 70 -88 96 -72C114 -60 102 -20 78 -4C56 10 24 8 6 -2Z" />
          <g clip-path="url(#fore-wing)">
            <ellipse class="ala-punta" cx="100" cy="-66" rx="34" ry="30" />
          </g>
          <path class="ala-bordo" d="M6 -2C22 -46 70 -88 96 -72C114 -60 102 -20 78 -4C56 10 24 8 6 -2Z" />
          <ellipse class="ala-macchia" cx="62" cy="-34" rx="9" ry="7" />
          <circle class="ala-macchia" cx="90" cy="-58" r="4.5" />
          <circle class="ala-macchia" cx="98" cy="-44" r="3.5" />
          <path class="ala-vena" d="M10 -2Q46 -30 86 -64M12 0Q50 -10 90 -30M10 6Q40 30 66 70" />
        </g>
      </defs>

      <g data-world>
        <g id="logo" data-logo></g>
        <g mask="url(#grow)" data-regrow></g>

        <!-- the little leaf that opens on one of the letters: its base is 0 0 and it grows upwards -->
        <g data-leaf>
          <g data-leaf-grow>
            <g mask="url(#leaf-bites)">
              <path class="foglia-gambo" d="M0 6Q-1.5 -2 0 -10" />
              <path class="foglia foglia--scura" d="M0 -8C-26 -22 -26 -66 0 -92Z" data-leaf-left />
              <path class="foglia" d="M0 -8C26 -22 26 -66 0 -92Z" data-leaf-right />
              <path class="foglia-vena" d="M0 -10L0 -84M0 -30L-11 -42M0 -50L-11 -62M0 -30L11 -42M0 -50L11 -62M0 -68L7 -76M0 -68L-7 -76" />
            </g>
          </g>
        </g>

        <!-- the silk thread it comes down on -->
        <line class="seta-filo" data-thread x1="0" y1="0" x2="0" y2="0" />

        <!-- the caterpillar: the script copies the segments in here, behind the head -->
        <g mask="url(#hide)" data-bug>
          <!-- the head: centre 0 0, looking to the right. It turns on its neck -->
          <g data-head-place>
            <g data-head-turn>
              <g data-ant-far>
                <g data-ant-far-wobble>
                  <path class="antenna antenna--lontana" d="M-6 -19Q-12 -33 -7 -45" />
                  <circle class="pallina pallina--lontana" cx="-7" cy="-46" r="4.6" />
                </g>
              </g>
              <g data-ant-near>
                <g data-ant-near-wobble>
                  <path class="antenna" d="M5 -21Q4 -36 12 -46" />
                  <circle class="pallina" cx="13" cy="-47" r="5.2" />
                </g>
              </g>
              <!-- the cheek that swells with food: behind the head, so that it bulges out of its outline -->
              <circle class="bruco" cx="12" cy="10" r="0" data-puff />
              <circle class="bruco" r="23" />
              <path class="bruco-lucido" d="M-15 -9Q-9 -18 1 -19.5" />
              <path class="bruco-macchia" d="M-15 3C-13 -1 -7 -1 -6 3C-7 7 -13 7 -15 3Z" />
              <ellipse class="guancia" cx="6" cy="8" rx="5.6" ry="3.4" data-cheek />
              <g data-mouth-box>
                <ellipse class="bocca" cx="18" cy="12.5" rx="4.6" ry="3.8" data-mouth />
                <path class="sorriso" d="M13.5 11.5Q18 15.5 22.5 11" data-smile />
              </g>
              <!-- the far eye, half behind the near one -->
              <circle class="occhio" cx="18" cy="-6" r="6.4" />
              <g clip-path="url(#eye-far)">
                <g data-pupil-far>
                  <circle class="iride" cx="20" cy="-5.5" r="4" />
                  <circle class="pupilla" cx="20.5" cy="-5.5" r="2.2" />
                  <circle class="riflesso" cx="19" cy="-7.2" r="1.3" />
                </g>
              </g>
              <ellipse class="palpebra" cx="18" cy="-6" rx="7.4" ry="7.4" data-lid-far />
              <circle class="occhio" cx="7" cy="-7" r="8.6" />
              <g clip-path="url(#eye-near)">
                <g data-pupil>
                  <circle class="iride" cx="10" cy="-6.5" r="5.3" />
                  <circle class="pupilla" cx="10.6" cy="-6.5" r="2.9" />
                  <circle class="riflesso" cx="8.4" cy="-9" r="1.8" />
                </g>
              </g>
              <ellipse class="palpebra" cx="7" cy="-7" rx="9.6" ry="9.6" data-lid />
            </g>
          </g>
        </g>

        <g data-loot></g>

        <!-- the cocoon: it hangs from 0 0, under the last letter -->
        <g data-cocoon-place>
          <g data-cocoon-swing>
            <path class="seta-gambo" d="M0 0L0 9" />
            <g data-shell>
              <path class="bozzolo" d="M0 6C18 8 26 38 23 64C20 88 8 102 0 104C-8 102 -20 88 -23 64C-26 38 -18 8 0 6Z" />
              <path class="bozzolo-ombra" d="M8 12C20 22 22 50 19 70C16 88 8 98 2 101C10 90 14 70 14 52C14 34 12 20 8 12Z" />
              <path class="bozzolo-righe" d="M-18 24Q0 31 18 23M-22.5 44Q0 53 22.5 43M-23 64Q0 73 22.5 63M-18 84Q0 91 17 83" />
              <path class="bozzolo-lucido" d="M-13 22Q-19 44 -15 70" />
              <ellipse class="bozzolo-buco" cx="0" cy="91" rx="10.5" ry="4.5" data-opening />
              <path class="bozzolo" d="M-12.5 90Q0 95 12.5 90C10 97 5 102.5 0 104C-5 102.5 -10 97 -12.5 90Z" data-cap />
            </g>
            <polyline class="filo" data-wrap />
          </g>
        </g>

        <!-- the butterfly: centre 0 0, head up. The wings fold towards the body to beat -->
        <g data-fly-place>
          <g data-wing-left><use href="#wing" /></g>
          <g data-wing-right><use href="#wing" /></g>
          <path class="farfalla-antenna" d="M-4 -42Q-10 -60 -20 -66M4 -42Q10 -60 20 -66" />
          <circle class="farfalla-pallina" cx="-21" cy="-67" r="3.6" />
          <circle class="farfalla-pallina" cx="21" cy="-67" r="3.6" />
          <path class="farfalla-corpo" d="M0 -26C7 -26 8 -10 7 10C6 32 3 44 0 46C-3 44 -6 32 -7 10C-8 -10 -7 -26 0 -26Z" />
          <path class="farfalla-righe" d="M-6 0Q0 3 6 0M-6 12Q0 15 6 12M-5 24Q0 27 5 24M-4 35Q0 37 4 35" />
          <circle class="farfalla-corpo" cx="0" cy="-34" r="10" />
          <circle class="occhio occhio--farfalla" cx="-4.6" cy="-36" r="4" />
          <circle class="occhio occhio--farfalla" cx="4.6" cy="-36" r="4" />
          <circle class="pupilla" cx="-4" cy="-35.4" r="2.2" />
          <circle class="pupilla" cx="5.2" cy="-35.4" r="2.2" />
          <circle class="riflesso" cx="-5" cy="-36.8" r="0.9" />
          <circle class="riflesso" cx="4.2" cy="-36.8" r="0.9" />
        </g>

        <g data-crumbs></g>
        <g data-fx></g>
      </g>
    </svg>
    <p class="nota">Click or tap to see it again</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.

35 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 logo rosicchiato dal bruco» da Animorio e adattala al mio sito

Cosa fa

Su una carta color panna crescono le lettere di un marchio inventato, Olivebud, in un carattere tondo e pesante color verde foglia: spuntano dal basso una dopo l’altra, ondeggiando come piantine con un rimbalzo morbido, e da ognuna saltano via due foglioline; sulla l si apre una piccola foglia, prima una metà e poi l’altra. Da in alto scende un bruco verde, paffuto, a segmenti, appeso a un filo di seta a testa in giù: tocca la O, si schiaccia come gomma, le antenne con la pallina arancione in punta fanno boing e il filo si ritira. Si guarda intorno, sbatte gli occhioni e comincia a camminare sopra le lettere seguendone il profilo: sale sulle aste alte, scende nelle valli fra una lettera e l’altra, e mentre cammina un’onda gli corre lungo il corpo dalla coda alla testa, un segmento alla volta si solleva e le zampette sotto ogni segmento fanno il passo. Prima si mangia la foglia, a quattro morsi dal lato verso la punta, con le briciole verdi che volano. Poi si ferma più volte sul bordo superiore delle lettere e rosicchia: a ogni morso la bocca si apre e si chiude, la guancia si gonfia, nel bordo compare un cerchietto in più (tre per morso, a smerlo) e una pioggia di briciole cade giù; il boccone gli scende lungo il corpo come un rigonfiamento e a ogni pasto il bruco ingrassa con un elastico. Davanti alla b strizza gli occhi, si dimena e ci si tuffa dentro: sparisce sotto la superficie della lettera, la lettera si gonfia e trema, e il bruco sbuca dall’altra parte con uno scoppio di briciole, lasciando due buchi tondi. Alla fine passa sopra l’ultima lettera, scende lungo il suo fianco e si appende sotto, a forma di J, dondolando. Gira la testa, un filo lo avvolge dall’alto in basso e il bozzolo si chiude; il bozzolo trema due volte, la punta salta via e ne esce una farfalla arancione con le ali ancora piegate, che si aprono a molla e cominciano a battere. La farfalla vola un otto intorno al logo, si abbassa sulla i e se ne porta via il puntino. Il logo resta così, smerlato e bucato, con il bozzolo vuoto che dondola e la farfalla che ripassa col suo bottino; poi guarisce: la farfalla riporta il puntino e lo lascia cadere al suo posto con un rimbalzo, nei morsi ricresce un verde nuovo da cui spuntano foglioline, il verde matura nel colore del logo, la foglia sulla l si riapre e la storia ricomincia. Un clic la fa ripartire da capo. Al posto della parola si può mettere un’immagine: il bruco ne segue il profilo, la morde e ci scava il tunnel anche lì.

Come funziona

Il profilo delle lettere

Il palco è un SVG con il viewBox grande quanto la finestra, così un’unità è un pixel. Le lettere si disegnano su una canvas nello stesso carattere e si leggono i pixel colonna per colonna: per ogni colonna, il punto più alto e il più basso dell’inchiostro. Da lì vengono il bordo da mordere, il buco della i (la colonna al centro della lettera: pieno, vuoto, pieno) e il punto sotto l’ultima lettera dove il bruco si appende. Un’immagine presa da un altro sito non si può leggere (getImageData dà errore) e allora vale come un rettangolo.

La strada del bruco

Il percorso è il centro di una palla grande quanto il bruco fatta rotolare sul bordo superiore: per ogni x, il punto più alto fra tutte le colonne vicine meno la distanza dalla palla. Così il bruco sale sulle aste, scende nelle valli e gira intorno agli angoli alla distanza giusta; dove la palla cade nel vuoto (uno spazio nel nome) c’è un piccolo salto. Il percorso si ricampiona a passo fisso e si leviga, così una distanza lungo la strada è solo un indice. La testa sta a una distanza u, ogni segmento un po’ più indietro: la timeline muove solo il numero u.

Il bruco a segmenti

Un segmento è disegnato una volta nella pagina (corpo, pancia, macchia, riflesso, due zampette) e copiato sei volte dallo script, dalla coda al collo, dietro la testa. A ogni fotogramma render() mette ogni pezzo sulla strada con un attributo transform: posizione, direzione e grandezza. Camminando, un’onda corre dalla coda alla testa (sin della distanza percorsa più un ritardo per segmento) e alza un segmento alla volta, stringe la distanza fra i vicini e fa ruotare le zampette; il boccone è una gaussiana che scorre lungo i segmenti e l’ingrasso è un numero che li allarga tutti con un elastico. Testa, antenne, palpebre, bocca e guance ruotano sulle loro articolazioni, calcolate con getBBox.

I morsi e il tunnel

I morsi sono una maschera SVG sulle lettere: un rettangolo bianco e cerchietti neri che crescono da zero, tre per morso, appoggiati al bordo letto sulla canvas. Nel tunnel il bruco passa sotto una U dentro la lettera; siccome è più grosso delle aste, non si nasconde con la forma della lettera ma con una seconda maschera sul bruco: un poligono nero che copre tutto quello che sta sotto il bordo superiore della lettera, con due cerchi bianchi dove la lettera viene bucata, così la testa si vede entrare e uscire dai buchi.

Bozzolo e farfalla

Appeso, il bruco smette di seguire la strada e diventa una catena che pende dall’ultima lettera e si piega a J; un numero da 0 a 1 passa da una forma all’altra. Il filo che lo avvolge è una spezzata a zigzag disegnata con stroke-dashoffset, mentre il guscio cresce dall’alto. La farfalla vola su curve Catmull-Rom (un otto intorno al logo, poi giù sulla i e via) e le ali battono piegandosi verso il corpo con scaleX. Il puntino della i è una copia della lettera ritagliata da un clipPath sopra lo spazio fra punto e asta, mentre un rettangolo nero nella maschera toglie il punto vero: un numero lo porta dalla lettera alle zampe della farfalla e, alla guarigione, giù di nuovo con bounce.out.

La regia e il tuo logo

Tutta la storia è una timeline sola, con timeScale per la velocità; i numeri del bruco e della farfalla si cambiano con T.set e T.to, mai con callback, così la timeline si può portare avanti e indietro. Alla guarigione una copia verde delle lettere morse si mostra solo dentro cerchi che crescono nei buchi, poi i buchi si chiudono sotto e il verde sfuma; la storia riparte dall’etichetta «arrive». Se IMAGE ha un indirizzo, il logo diventa quell’immagine: il bruco ne segue il profilo, la morde, ci scava il tunnel vicino alla fine e la farfalla se ne porta via un pezzetto tondo.

Valori da cambiare

NomeFileDi partenzaCosa cambia
NAMEscript.js'Olivebud'Il logo scritto: il bruco cammina sul bordo superiore delle sue lettere. Se c’è una i (o una j), la farfalla se ne porta via il puntino.
IMAGEscript.js''Il logo come immagine: l’indirizzo di un file, oppure caricalo dal tuo computer. Se c’è, prende il posto della parola.
BITESscript.js4Quante volte il bruco si ferma a rosicchiare il bordo del logo, al massimo: se il logo è corto, ne fa solo quante ci stanno.
TUNNELscript.js5La lettera in cui scava il tunnel, contando da 0 (gli spazi non contano). Se è troppo stretta, sceglie la più vicina abbastanza larga. Un’immagine la scava vicino alla fine.
GROWscript.js0.5Quanto ingrassa mangiando: 0.5 vuol dire una volta e mezza più grosso alla fine, 0 resta com’è.
BUGscript.js1Quanto è grande il bruco rispetto alle lettere (e con lui il bozzolo e la farfalla).
SPEEDscript.js1La velocità di tutta la storia: 2 è il doppio, 0.5 la metà.
RESTscript.js4Quanti secondi il logo resta rosicchiato, col bozzolo vuoto che dondola, prima di guarire.
LOOPscript.jstrueSe il logo guarisce e la storia ricomincia. Con false resta rosicchiato, il bozzolo continua a dondolare e la farfalla ripassa ogni tanto.

Provali nel Playground

Quando usarla

Per presentare un logo con un sorriso: l’anteprima per un cliente, l’apertura del sito di un marchio di cose naturali (orti, tisane, giardinaggio, prodotti per bambini), una pagina 404 o un caricamento simpatico, un post per i social. Funziona con un marchio scritto e con un’immagine.

Sul telefono

La stessa storia, con le misure adattate: le lettere occupano quasi tutta la larghezza, il bruco, il bozzolo e la farfalla sono un po’ più grandi rispetto alle lettere, e il punto dove il bruco si appende resta sempre dentro lo schermo, così il bozzolo e la farfalla non escono dal bordo. Un tocco la fa ripartire.

Con il movimento ridotto

Niente si muove: il logo compare in dissolvenza, poi il bruco fermo sulle lettere; poi in dissolvenza i morsi e i buchi (e sparisce la foglia), il bruco lascia il posto al bozzolo e compare la farfalla col puntino della i. Se la storia ricomincia, anche la guarigione è una dissolvenza.

Trappole

  • Scendendo a testa in giù sul filo, le antenne piegate all’indietro si stendevano sopra i segmenti del corpo: durante la discesa si piegano in avanti, lontano dal corpo, e tornano a posto con un elastico quando atterra.
  • Ogni morso è fatto di tre cerchietti appoggiati al bordo letto colonna per colonna: sopra la u un cerchietto cadeva nello spazio fra le due gambe (lì il bordo più alto è il fondo della lettera) e bucava la u in mezzo. Un cerchietto che starebbe molto più in basso di quello centrale si salta.
  • Il primo morso arrivava subito dopo l’atterraggio, quando il corpo era ancora dritto sul filo: i morsi stanno ad almeno tre volte e mezza la grandezza del bruco dal punto dove atterra.
  • Sul telefono il bozzolo e la farfalla che ne esce finivano oltre il bordo destro: il punto dove il bruco si appende si sposta verso l’interno quanto basta, anche se resta sotto la lettera prima.
  • Il pezzo di logo portato dalla farfalla, tenuto subito sotto il corpo, spariva dietro le ali di dietro: ora pende più in basso, sotto la coda.
  • In un’immagine la colonna scelta per il pezzetto da portare via cadeva nel vuoto fra due forme (e il pezzetto non c’era): si cerca la colonna piena più vicina.
  • Con un nome lungo la camminata durava quasi un minuto: la velocità cresce con la lunghezza della strada, così la camminata dura al massimo sei secondi e mezzo.

Librerie

GSAP 3.15.0, Fredoka (font variabile) 5.3.0.

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

Collaudo

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