Vai al contenuto
animorio
EN
Torna alla libreria

Il logo sotto la palla da demolizione

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

L’anteprima di un logo in tre atti: il logo si costruisce come un muro, a file di mattoni, poi arriva una gru con un operaio baffuto in cabina e una palla da demolizione che oscilla come un pendolo vero. Prima tocca appena, poi colpisce: una lettera va in pezzi, la vicina cade a domino, un’altra si crepa. 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 wrecking-ball logo</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/archivo@5.3.0/wdth.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="scena">
    <!-- the stage: the script measures it, builds the logo in it and drives the crane -->
    <svg class="palco" data-stage role="img" aria-label="BRAWNLY" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <!-- the operator is seen only through the cabin window -->
        <clipPath id="op-window">
          <rect x="-150" y="-290" width="88" height="110" rx="5" />
        </clipPath>
        <!-- the counterweight, to keep its warning stripes inside it -->
        <clipPath id="weight-clip">
          <path d="M120 -86L180 -86Q188 -86 188 -94L188 -164Q188 -172 180 -172L120 -172Z" />
        </clipPath>
      </defs>

      <g data-world>
        <g data-scene>
          <g data-ground>
            <line class="terra" data-floor />
            <ellipse class="ombra-palla" data-ball-shadow />
          </g>
          <g data-haze-back></g>

          <!-- the crane: drawn facing left, the point under its tracks is 0 0 -->
          <g data-crane>
            <ellipse class="gru-ombra" cx="12" cy="2" rx="196" ry="11" />
            <!-- the boom, built by the script along its length: it turns on its foot, behind the cabin -->
            <g data-boom></g>
            <!-- the cable that holds the boom, from the top of the mast to the tip -->
            <line class="gru-cavo" data-pendant />
            <!-- the mast at the back -->
            <path class="asta-bordo" d="M44 -196L76 -322M112 -196L76 -322" />
            <path class="asta" d="M44 -196L76 -322M112 -196L76 -322" />
            <circle class="perno" cx="76" cy="-322" r="8" />
            <!-- the exhaust -->
            <rect class="tubo" x="92" y="-238" width="12" height="44" rx="3" />
            <rect class="tubo" x="88.5" y="-244" width="19" height="8" rx="2.5" />
            <!-- the ring the upper works turn on -->
            <rect class="scuro" x="-100" y="-84" width="200" height="20" rx="4" />
            <!-- the upper works -->
            <path class="gru" d="M-150 -78L128 -78L128 -188Q128 -198 118 -198L-150 -198Z" />
            <path class="gru-scuro" d="M-150 -94L128 -94L128 -78L-150 -78Z" />
            <path class="gru-linea" d="M-150 -78L128 -78L128 -188Q128 -198 118 -198L-150 -198" />
            <path class="gru-lucido" d="M-40 -190L114 -190" />
            <path class="gru-righe" d="M8 -172L64 -172M8 -160L64 -160M8 -148L64 -148M8 -136L64 -136" />
            <path class="gru-righe" d="M-30 -186L-30 -100M80 -186L80 -100" />
            <circle class="rivetto" cx="-20" cy="-176" r="3" />
            <circle class="rivetto" cx="-20" cy="-112" r="3" />
            <circle class="rivetto" cx="92" cy="-176" r="3" />
            <circle class="rivetto" cx="92" cy="-112" r="3" />
            <!-- the counterweight, with warning stripes -->
            <path class="contrappeso" d="M120 -86L180 -86Q188 -86 188 -94L188 -164Q188 -172 180 -172L120 -172Z" />
            <g clip-path="url(#weight-clip)">
              <path class="strisce" d="M104 -86L122 -86L150 -172L132 -172ZM140 -86L158 -86L186 -172L168 -172ZM176 -86L194 -86L222 -172L204 -172Z" />
            </g>
            <path class="contrappeso-bordo" d="M120 -86L180 -86Q188 -86 188 -94L188 -164Q188 -172 180 -172L120 -172Z" />
            <!-- the tracks: the treads run, the wheels turn -->
            <rect class="cingolo" x="-164" y="-66" width="328" height="66" rx="33" />
            <rect class="battistrada" x="-157" y="-59" width="314" height="52" rx="26" data-tread />
            <rect class="cingolo-piastra" x="-134" y="-51" width="268" height="36" rx="18" />
            <g data-wheel data-cx="-131" data-cy="-33" data-r="22">
              <circle class="ruota" r="22" />
              <path class="raggi" d="M0 -15L0 15M-13 -7.5L13 7.5M-13 7.5L13 -7.5" />
              <circle class="mozzo" r="6" />
            </g>
            <g data-wheel data-cx="-66" data-cy="-31" data-r="14">
              <circle class="ruota" r="14" />
              <path class="raggi" d="M0 -9L0 9M-8 -4.5L8 4.5M-8 4.5L8 -4.5" />
              <circle class="mozzo" r="4" />
            </g>
            <g data-wheel data-cx="0" data-cy="-31" data-r="14">
              <circle class="ruota" r="14" />
              <path class="raggi" d="M0 -9L0 9M-8 -4.5L8 4.5M-8 4.5L8 -4.5" />
              <circle class="mozzo" r="4" />
            </g>
            <g data-wheel data-cx="66" data-cy="-31" data-r="14">
              <circle class="ruota" r="14" />
              <path class="raggi" d="M0 -9L0 9M-8 -4.5L8 4.5M-8 4.5L8 -4.5" />
              <circle class="mozzo" r="4" />
            </g>
            <g data-wheel data-cx="131" data-cy="-33" data-r="22">
              <circle class="ruota" r="22" />
              <path class="raggi" d="M0 -15L0 15M-13 -7.5L13 7.5M-13 7.5L13 -7.5" />
              <circle class="mozzo" r="6" />
            </g>

            <!-- the cabin: the inside, the operator, the glass, then the frame with the window cut out -->
            <rect class="cabina-dentro" x="-150" y="-290" width="88" height="110" />
            <g clip-path="url(#op-window)">
              <rect class="sedile" x="-141" y="-270" width="70" height="104" rx="15" />
              <rect class="sedile-cuscino" x="-131" y="-262" width="50" height="14" rx="7" />
              <!-- the far arm, behind the body -->
              <path class="braccio-bordo" data-arm-far-line />
              <path class="manica" data-arm-far />
              <circle class="mano" r="6.2" data-hand-far />
              <g data-op-body>
                <path class="camicia" d="M-143 -168L-143 -190Q-143 -208 -122 -210L-90 -210Q-69 -208 -69 -190L-69 -168Z" />
                <path class="gilet" d="M-141 -168L-141 -190Q-141 -206 -122 -208L-114 -208L-106 -195L-98 -208L-90 -208Q-71 -206 -71 -190L-71 -168Z" />
                <path class="striscia" d="M-141 -191L-71 -191L-71 -185L-141 -185Z" />
                <rect class="pelle" x="-112.5" y="-216" width="13" height="12" />
              </g>
              <!-- the head: it tilts on the neck -->
              <g data-op-head>
                <circle class="pelle" cx="-128" cy="-232" r="5.5" />
                <circle class="pelle" cx="-84" cy="-232" r="5.5" />
                <ellipse class="pelle" cx="-106" cy="-233" rx="21.5" ry="23" />
                <ellipse class="guance" cx="-121" cy="-224" rx="4.6" ry="3" data-op-blush />
                <ellipse class="guance" cx="-91" cy="-224" rx="4.6" ry="3" data-op-blush />
                <circle class="occhio" cx="-114" cy="-238" r="6" />
                <circle class="occhio" cx="-98" cy="-238" r="6" />
                <g data-op-eyes>
                  <circle class="iride" cx="-115.4" cy="-237.6" r="3.7" />
                  <circle class="iride" cx="-99.4" cy="-237.6" r="3.7" />
                  <circle class="pupilla" cx="-115.8" cy="-237.6" r="2" />
                  <circle class="pupilla" cx="-99.8" cy="-237.6" r="2" />
                  <circle class="riflesso" cx="-116.8" cy="-239" r="1.1" />
                  <circle class="riflesso" cx="-100.8" cy="-239" r="1.1" />
                </g>
                <ellipse class="palpebra" cx="-114" cy="-238" rx="7" ry="7" data-op-lid />
                <ellipse class="palpebra" cx="-98" cy="-238" rx="7" ry="7" data-op-lid />
                <path class="ciglio" d="M-121 -246.5Q-114 -250 -107.5 -246.5" data-op-brow />
                <path class="ciglio" d="M-104.5 -246.5Q-98 -250 -91 -246.5" data-op-brow />
                <ellipse class="naso" cx="-106" cy="-229" rx="5.6" ry="4.6" />
                <ellipse class="bocca" cx="-106" cy="-213.5" rx="5.5" ry="2.4" data-op-mouth />
                <!-- the moustache, big and bushy -->
                <path class="baffi" d="M-106 -227C-112 -229.5 -120 -229 -124 -224C-127 -220 -131 -220.5 -134 -223.5C-132 -215.5 -123 -214.5 -117 -217.5C-112 -219.5 -108.5 -220.5 -106 -220.5C-103.5 -220.5 -100 -219.5 -95 -217.5C-89 -214.5 -80 -215.5 -78 -223.5C-81 -220.5 -85 -220 -88 -224C-92 -229 -100 -229.5 -106 -227Z" data-op-stache />
                <path class="baffi-righe" d="M-122 -222Q-118 -219.5 -113 -221M-90 -222Q-94 -219.5 -99 -221" />
                <!-- the yellow helmet -->
                <path class="casco" d="M-130.5 -250C-130.5 -268 -121 -278 -106 -278C-91 -278 -81.5 -268 -81.5 -250Z" />
                <path class="casco-cresta" d="M-110 -277.2L-102 -277.2L-102 -250L-110 -250Z" />
                <path class="casco-falda" d="M-135 -251.5L-77 -251.5Q-74.5 -248.5 -77.5 -246.5L-134.5 -246.5Q-137.5 -248.5 -135 -251.5Z" />
                <path class="casco-lucido" d="M-125 -255Q-123.5 -266 -114 -271.5" />
              </g>
              <!-- the lever, and the near arm with its hand on it -->
              <g data-lever>
                <line class="leva" x1="-66" y1="-172" x2="-66" y2="-206" />
                <circle class="pomello" cx="-66" cy="-210" r="5.6" />
                <circle class="pomello-lucido" cx="-67.8" cy="-211.8" r="1.7" />
              </g>
              <path class="braccio-bordo" data-arm-near-line />
              <path class="manica" data-arm-near />
              <circle class="mano" r="6.2" data-hand-near />
            </g>
            <rect class="vetro" x="-150" y="-290" width="88" height="110" />
            <g clip-path="url(#op-window)">
              <path class="vetro-riflesso" d="M-128 -292L-112 -292L-150 -230L-150 -256ZM-104 -292L-98 -292L-150 -206L-150 -216Z" />
            </g>
            <path class="gru" fill-rule="evenodd" d="M-166 -300L-52 -300L-52 -78L-166 -78ZM-150 -290L-62 -290L-62 -180L-150 -180Z" />
            <path class="gru-scuro" d="M-166 -100L-52 -100L-52 -78L-166 -78Z" />
            <path class="gru-linea" fill-rule="evenodd" d="M-166 -300L-52 -300L-52 -78L-166 -78ZM-150 -290L-62 -290L-62 -180L-150 -180Z" />
            <path class="gru-righe" d="M-158 -168L-60 -168M-120 -168L-120 -96" />
            <rect class="maniglia" x="-114" y="-142" width="16" height="5" rx="2.5" />
            <path class="gru-scuro" d="M-172 -308L-46 -308Q-42 -308 -42 -304L-42 -297L-176 -297L-176 -304Q-176 -308 -172 -308Z" />
            <path class="gru-linea" d="M-172 -308L-46 -308Q-42 -308 -42 -304L-42 -297L-176 -297L-176 -304Q-176 -308 -172 -308Z" />
          </g>

          <g data-logo></g>

          <!-- the chain and the ball: the script places them under the tip of the boom -->
          <g data-rig>
            <g data-chain></g>
            <g data-ball>
              <g data-ball-spin>
                <path class="grillo-bordo" d="M-21 -96L-21 -122Q-21 -142 0 -142Q21 -142 21 -122L21 -96" />
                <path class="grillo" d="M-21 -96L-21 -122Q-21 -142 0 -142Q21 -142 21 -122L21 -96" />
                <rect class="grillo-piastra" x="-30" y="-110" width="60" height="18" rx="6" />
              </g>
              <circle class="palla-scura" r="100" />
              <circle class="palla" cx="-12" cy="-12" r="85" />
              <g data-ball-spin>
                <path class="ammaccatura" d="M26 18Q36 25 46 18M-30 46Q-21 52 -12 46M44 -36Q50 -28 58 -32M-52 2Q-46 10 -38 6" />
              </g>
              <ellipse class="palla-riflesso" cx="-42" cy="-46" rx="25" ry="13" transform="rotate(-40 -42 -46)" />
              <circle class="palla-riflesso" cx="-12" cy="-70" r="6.5" />
              <circle class="palla-bordo" r="100" />
            </g>
          </g>

          <g data-shards></g>
          <g data-dust></g>
          <g data-haze></g>
          <g data-fx></g>
        </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.

38 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 sotto la palla da demolizione» da Animorio e adattala al mio sito

Cosa fa

Su una carta color calce arriva il logo di un marchio inventato, Brawnly, scritto in un carattere nerissimo e larghissimo: si costruisce come un muro, una fila di mattoni alla volta, con ogni pezzo che cade, si schiaccia e rimbalza; alla fine il logo si assesta con una scossa e un po’ di polvere. Il logo si sposta di lato e da destra entra una gru cingolata gialla: i cingoli girano, il tubo di scarico sbuffa, la palla da demolizione dondola sotto il braccio a traliccio e, quando la gru frena, oscilla avanti e indietro. In cabina c’è un operaio con il casco giallo, due grandi baffi e una mano sulla leva. Prima cala piano la palla e la appoggia sul logo: un toc, le lettere tremano, e lui fa spallucce. Poi tira la leva: il braccio si abbassa, la palla carica indietro, resta un attimo in alto e scende come un pendolo vero, sempre più veloce, fino a colpire una lettera. Il palco trema, la lettera va in pezzi che volano girando, rimbalzano a terra e si fermano, mentre una polvere densa esplode in nuvole; la palla, frenata, spinge la lettera prima, che si rovescia e si appoggia a quella dopo come un domino. Rimbalzando, la palla prende lo spigolo della lettera successiva, che si crepa e resta in bilico su un angolo. L’operaio tira su la palla ed esulta a braccia alzate. Il logo resta così per qualche secondo: la polvere si posa piano, la lettera crepata ondeggia e cigola, la palla dondola lenta. Poi tutto si rimonta come un film al contrario, i pezzi tornano al loro posto con un rimbalzo elastico, la gru se ne va salutando e la storia ricomincia. Un clic la fa ripartire da capo. Al posto della parola si può mettere un’immagine: la palla ne frantuma un angolo.

Come funziona

Una scena a misura

Il logo si compone a corpo 100 dentro un gruppo SVG che poi si scala alla finestra: tutte le misure (palla, gru, catena, polvere) sono in altezze di lettera. Le lettere si misurano nella pagina stessa con getComputedTextLength, che conosce di sicuro la larghezza 125 del carattere; l’inchiostro vero di ogni lettera si legge invece disegnandola su una canvas (fontStretch expanded) e leggendone i pixel: il contorno serve alla palla, una griglia di punti interni serve ai pezzi.

Un pendolo vero

La palla è il punto in cima al braccio, una lunghezza di catena e un angolo: il centro sta a L·sen θ e L·cos θ dalla punta. Prima di cominciare lo script cerca, provando angolo per angolo, il punto della punta e la lunghezza della catena per cui la prima cosa che la palla tocca scendendo da destra è proprio la lettera scelta, sul suo spigolo in alto, senza sfiorare quella dopo; poi dove va a finire (la lettera prima o il suolo) e di quanto deve allungarsi la catena perché, rimbalzando, prenda lo spigolo della lettera successiva. La discesa segue un coseno, come un pendolo: rallenta in cima e accelera in fondo.

I pezzi

La lettera colpita si taglia in celle di Voronoi intorno a punti presi dentro il suo inchiostro: ogni cella è un poligono, ritagliato da un semipiano per ogni altro punto, che fa da clipPath a una copia della lettera. Il volo si calcola una volta sola, fotogramma per fotogramma, con spinta, gravità, rotazione e rimbalzi sull’angolo più basso del poligono girato; la timeline poi legge la posizione al suo tempo, così si può andare avanti e indietro.

Il domino e la crepa

La lettera spinta ruota intorno al suo angolo in basso a sinistra finché un punto del suo contorno, girato, cade dentro l’inchiostro della lettera prima (anche lei un po’ inclinata): lì si ferma, e si appoggia. La crepa è uno zigzag col colore della carta, che parte dallo spigolo colpito e si traccia con stroke-dashoffset; poi la lettera si inclina nel vuoto lasciato dall’altra e oscilla su un angolo, con due archetti che cigolano.

La gru e l’operaio

La gru è disegnata una volta sola nella pagina, a pezzi e col contorno; il braccio a traliccio lo costruisce lo script lungo quanto serve. Posto della gru, angolo del braccio, angolo e lunghezza della catena, leva e pose dell’operaio stanno in un oggetto che si scrive come attributi a ogni aggiornamento: i cingoli e le ruote girano da soli in base a dove si trova la gru, le braccia dell’operaio sono due ossa con il gomito piegato verso l’esterno, dalla spalla alla mano, che sta sul pomello della leva o in alto quando esulta.

Il film al contrario

Tutto quello che il colpo fa al logo (pezzi, polvere, domino, crepa) sta in una timeline a parte, in pausa: la storia la fa andare avanti animandone il tempo, e alla fine la fa tornare indietro con power3.inOut, come un film riavvolto; poi le lettere rimbalzano con un elastico e la storia riparte dall’etichetta «arrive». Se IMAGE ha un indirizzo, il logo diventa quell’immagine: un pezzo solo, di cui la palla frantuma l’angolo colpito, con un clipPath evenodd per quello che resta.

Valori da cambiare

NomeFileDi partenzaCosa cambia
NAMEscript.js'BRAWNLY'Il logo scritto: ogni lettera è un blocco del muro, che la palla può frantumare, spingere o crepare.
IMAGEscript.js''Il logo come immagine: l’indirizzo di un file, oppure caricalo dal tuo computer. Se c’è, prende il posto della parola e la palla ne frantuma un angolo.
HITscript.js4La lettera che la palla frantuma, contando da 0 (gli spazi non contano). Se una lettera più alta accanto le fa da scudo, la palla rompe quella che incontra per prima.
SHARDSscript.js9In quanti pezzi si rompe la lettera colpita.
DUSTscript.js1Quanta polvere: 0 nessuna, 2 il doppio.
BALLscript.js0.9Quanto è grande la palla, in altezze di lettera.
SPEEDscript.js1La velocità di tutta la storia: 2 è il doppio, 0.5 la metà.
RESTscript.js4Quanti secondi il logo resta in rovina prima di rimontarsi.
LOOPscript.jstrueSe il logo si rimonta e la storia ricomincia. Con false resta in rovina, con la lettera che ondeggia e la palla che dondola.

Provali nel Playground

Quando usarla

Per presentare un logo in modo che non si dimentichi: l’anteprima per un cliente, l’apertura del sito di un’impresa edile, di uno studio o di un video, una pagina 404 o una pagina «in costruzione» con un po’ di ironia, un post per i social. Funziona con un marchio scritto e con un’immagine.

Sul telefono

La stessa storia, con le misure adattate: su uno schermo stretto la gru è un po’ più grande e si vedono la cabina con l’operaio e il braccio, la parte dietro resta oltre il bordo. Un tocco la fa ripartire.

Con il movimento ridotto

Niente si muove: il logo compare in dissolvenza, poi la gru con la palla appesa, poi in dissolvenza il logo in rovina (pezzi a terra, lettera rovesciata, crepa). Se la storia ricomincia, anche il ritorno è una dissolvenza.

Trappole

  • La palla scendeva sulla lettera giusta ma ne sfiorava prima un’altra, o finiva dentro il braccio della gru quando caricava indietro: il punto della punta, la lunghezza della catena e l’angolo massimo si cercano provando, con l’inchiostro vero delle lettere letto su una canvas.
  • Su un pendolo con la catena lunga, dopo il colpo la palla andava a cercare il suolo prima della lettera da spingere, e il domino non partiva: fra i piani possibili si preferisce quello in cui la palla, frenata, arriva alla lettera prima.
  • Dopo la crepa la palla, ricadendo, passava di nuovo in mezzo alle lettere: la catena si tira su in fretta (power3.out) e l’oscillazione riparte solo quando la palla è già in alto.
  • Una crepa nascosta con stroke-dashoffset uguale alla sua lunghezza mostrava comunque un puntino: il capo arrotondato di un tratto lungo zero si disegna. Resta invisibile finché non si crepa.
  • Nella canvas il carattere largo non si chiede nella scorciatoia font (la larghezza sparisce) ma con fontStretch; e se il browser non lo sa fare, le lettere si stirano alla larghezza misurata nella pagina.
  • Le lettere fatte di file di mattoni lasciano righe sottili fra una fila e l’altra (l’antialiasing): vanno bene mentre il muro sale, poi si mostra la lettera intera.
  • getComputedTextLength su un testo SVG toglie gli spazi in fondo: per misurare «BRAW » serve xml:space preserve.

Librerie

GSAP 3.15.0, Archivo (font variabile, larghezza e peso) 5.3.0.

Compressi con gzip, i tre file della demo pesano 25 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