Vai al contenuto
animorio
EN
Tutti i componenti

La finestra da rompere

Finestre, Transizioni, Fisica, SVGGSAP, Solo CSSImpegnativaPeso compresso: Demo 14 KBGSAP 28 KBGratisScarica lo zip

L’accesso d’emergenza di una console, dietro un vetro: il pulsante alza una lastra di vetro fumé che si raddrizza su molle mentre la luce la attraversa, Cancel la rimette nel pulsante, e Break glass fa calare un martelletto: il vetro si crepa dal punto colpito, tiene un attimo e cade in pezzi che girano nello spazio e prendono la luce. Le crepe si calcolano a ogni colpo e i pezzi sono copie della finestra tagliate lungo di loro.

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 break-glass dialog</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/reddit-sans@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the break-glass dialog: Emergency access raises a pane of smoked glass that asks to break it. Cancel puts it
         back; Break glass swings the hammer, the glass cracks from where it is hit and falls in pieces, and the
         button becomes the emergency access with its countdown and End -->
    <div class="slot" data-slot data-autoclic>
      <button class="trigger" type="button" aria-haspopup="dialog" data-open>
        <svg class="hammer" viewBox="0 0 24 24" aria-hidden="true"><path d="M12.3 3.3 18.6 9.6 19.5 13.9 15.2 13 8.9 6.7z"/><path d="M13.1 10.9 4.6 19.4"/></svg>
        <span>Emergency access</span>
      </button>
      <div class="active" hidden data-active>
        <svg class="active__icon" viewBox="0 0 24 24" aria-hidden="true"><rect x="5" y="10.5" width="14" height="10" rx="2.2"/><path d="M8.2 10.5V7.4a3.8 3.8 0 0 1 7.3-1.5M12 14.4v2.4"/></svg>
        <span class="active__name">Admin access</span>
        <span class="active__clock"><span class="sr">Time left </span><span data-clock></span></span>
        <button class="active__end" type="button" data-end>End</button>
      </div>
      <span class="slot__pill" aria-hidden="true"></span>
    </div>
  </main>

  <div class="layer" hidden data-layer>
    <div class="layer__scrim" data-scrim></div>
    <div class="pane" role="alertdialog" aria-modal="true" aria-labelledby="pane-title" aria-describedby="pane-text" tabindex="-1" data-pane>
      <div class="glass" data-glass>
        <div class="glass__icon" aria-hidden="true">
          <svg viewBox="0 0 24 24"><path d="M12 3.4 18.8 6v5.6c0 4.1-2.8 7.4-6.8 8.9-4-1.5-6.8-4.8-6.8-8.9V6z"/><circle cx="12" cy="10.6" r="1.7"/><path d="M12 12.3v3"/></svg>
        </div>
        <h2 class="glass__title" id="pane-title">Break glass?</h2>
        <p class="glass__text" id="pane-text">You’ll get full admin rights for <span data-minutes></span> minutes. Everything you do is recorded, and the security team is told straight away.</p>
        <p class="glass__meta">
          <svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="8.2"/><path d="M12 7.6V12l2.9 1.8"/></svg>
          <span>Ends on its own at <time data-ends></time></span>
        </p>
        <div class="glass__actions">
          <button class="btn btn--quiet" type="button" data-cancel>Cancel</button>
          <button class="btn btn--break" type="button" data-confirm>
            <svg class="hammer" viewBox="0 0 24 24" aria-hidden="true" data-hammer><path d="M12.3 3.3 18.6 9.6 19.5 13.9 15.2 13 8.9 6.7z"/><path d="M13.1 10.9 4.6 19.4"/><circle class="hammer__tip" cx="19.2" cy="13.6" r="0.4" data-tip/></svg>
            <span>Break glass</span>
          </button>
        </div>
        <span class="glass__sheen" aria-hidden="true" data-sheen></span>
      </div>
      <div class="pane__shards" aria-hidden="true" data-shards></div>
      <svg class="pane__cracks" aria-hidden="true" data-cracks></svg>
    </div>
  </div>
  <p class="sr" aria-live="polite" data-live></p>

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

36 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 finestra da rompere» da Animorio e adattala al mio sito

Cosa fa

Su un fondo nero una pillola scura alta 56 pixel con un martelletto d’emergenza rosso e la scritta Emergency access; col mouse sopra il martelletto si alza, pronto. Premuta, le sue parole spariscono e dal pulsante sale una lastra di vetro fumé, inclinata all’indietro e un po’ più piccola: si raddrizza su una molla, va appena oltre e torna, e mentre cambia inclinazione la attraversa il riflesso di una lampada. Sul vetro: uno scudo rosso, Break glass?, la spiegazione (diritti di amministratore per 60 minuti, tutto registrato, la squadra della sicurezza avvisata), l’ora in cui l’accesso finisce da solo e i pulsanti Cancel e Break glass. Cancel, Esc o un tocco fuori la rimettono via: la lastra si inclina di nuovo all’indietro, il riflesso ripassa, e lei rimpicciolisce dentro il pulsante, che riprende le sue parole con un piccolo rimbalzo. Break glass alza e cala il martelletto nel pulsante: dove arriva la punta il vetro si crepa, prima i raggi che corrono verso i bordi, poi gli anelli intorno al colpo, con qualche capello di crepa di lato; la lastra trema per il colpo, ogni pezzo si sposta di un pixel e prende una luce sua, così le parole si spezzano lungo le crepe. Dopo un attimo il vetro cade: prima i pezzetti intorno al colpo, che sfondano verso l’interno, poi gli altri, che girano nello spazio, mostrano i bordi rotti e mandano un lampo quando si voltano verso la luce. Il pulsante diventa rosso e, quando nessun pezzo gli passa più davanti, dice Admin access con un lucchetto aperto, il tempo che resta (60:00, 59:59…) ed End, che chiude l’accesso e lo riporta com’era.

Come funziona

Una lastra su molle

La finestra ha quattro misure, l’altezza, la scala e le due inclinazioni rotateX e rotateY, e ognuna è una molla smorzata, x'' = −ω²(x − meta) − 2ζω·x', a passi di 1/240 di secondo sul ticker di GSAP, col passo limitato a 1/30. Aprendo parte 34 pixel più in basso, a 0,9 e inclinata di 32 gradi all’indietro: l’inclinazione ha ω = 7,2/RISE e ζ = 0,42, quindi va un poco oltre e torna, l’altezza e la scala ω = 8/RISE e ζ = 0,78. Chiudendo le mete diventano 26 pixel, 0,62 e 30 gradi, con ζ = 0,9 e la lastra che svanisce in PUT_AWAY secondi. Quando le molle sono ferme il ciclo dorme.

La luce sul vetro

Il riflesso è una fascia diagonale chiara con mix-blend-mode: screen, dentro il vetro. Non ha un tempo suo: la sua posizione viene dall’inclinazione, translateX = −130% + 12,5·rotateX − 8·rotateY, quindi attraversa la lastra mentre si raddrizza, mentre torna nel pulsante e quando il colpo la fa tremare, e da ferma resta fuori. Le parole del pulsante svaniscono prima che il vetro sia opaco, così non si vedono mai attraverso.

Le crepe, calcolate a ogni colpo

Il colpo è la punta del martelletto (un punto segnato nel suo disegno) dopo che è salito a −40 gradi e sceso a 18. Da lì partono RAYS raggi ad angoli un po’ irregolari, con un punto su ogni anello e fra due anelli altri punti che deviano di due pixel; gli anelli sono RINGS, da 15 pixel fino all’84% della distanza dall’angolo più lontano, a raggi che crescono in progressione geometrica. Un settore si chiude su un anello con probabilità 0,7 (sempre sul primo, che fa i pezzetti del colpo); se l’arco è più largo di 130 pixel si apre in due con un raggio nuovo che parte da lì. Ogni arco che chiude un settore chiude un pezzo, poi tagliato sui quattro lati del vetro con Sutherland e Hodgman.

Il disegno delle crepe

In un SVG sopra il vetro ogni crepa sono due tratti, uno scuro e uno chiaro mezzo pixel più su, con un’opacità diversa per crepa, più qualche capello corto che parte di lato dai raggi. Si disegnano con stroke-dashoffset: i raggi a 2600 pixel al secondo, ognuno dal suo anello, gli anelli in 0,06 secondi quando la crepa ci arriva. I pezzi sono tagliati lungo gli stessi punti, quindi crepe e parole spezzate combaciano.

Pezzi veri

Ogni pezzo è una copia del vetro (senza id né data-, coi pulsanti fuori dal Tab) tagliata con clip-path: polygon(), il transform-origin sul suo baricentro, un SVG coi soli bordi rotti e una luce sua. Durante HOLD si spostano di un pixel intero e cambiano un poco di luce. Poi si staccano dal colpo verso fuori, a 2200 pixel al secondo: spinta (50 + 260·vicinanza²)·BURST, una velocità verso l’interno fino a 640 pixel al secondo vicino al colpo, rotazioni su tre assi, gravità GRAVITY. La normale del pezzo, girata da rotateX e rotateY, contro il vettore a metà fra lampada e occhio, alla cinquantesima potenza, dà il lampo della sua lucentezza.

Tasti, accesso e anteprima

È un alertdialog con aria-modal, aria-labelledby e aria-describedby: aprendo il fuoco va su Cancel, Tab gira fra i due pulsanti, Esc la rimette via, il pulsante dietro è inert; chiudendo il fuoco torna sul pulsante, o va su End dopo il colpo. Il pulsante diventa rosso quando il vetro cade, e le sue parole arrivano quando nessun pezzo gli è più davanti; il tempo che resta si riscrive solo quando cambia il secondo, e a zero l’accesso finisce da solo. Una regione aria-live lo dice. Un clic da script sul riquadro del pulsante (l’anteprima della libreria) apre, poi una volta rimette via e una volta rompe, e chiude l’accesso, guardando lo stato e non una lista fissa.

Valori da cambiare

NomeFileDi partenzaCosa cambia
RISEscript.js0.62I secondi in cui la lastra sale e si posa.
PUT_AWAYscript.js0.34I secondi in cui Cancel rimette la lastra nel pulsante.
RAYSscript.js11Quante crepe partono dal punto in cui arriva il martelletto.
RINGSscript.js5Quanti anelli di crepe girano intorno al colpo.
HOLDscript.js0.4I secondi in cui il vetro crepato sta ancora insieme prima di cadere.
GRAVITYscript.js3200Quanto velocemente cadono i pezzi, in pixel al secondo al quadrato.
BURSTscript.js1Quanto forte il colpo lancia i pezzi: 0 cadono e basta, 2 il doppio.
DIMscript.js0.62Quanto si scurisce la pagina dietro il vetro, da 0 a 1.
MINUTESscript.js60Quanti minuti dura l’accesso d’emergenza.

Provali nel Playground

Quando usarla

Per le azioni che si fanno di rado e devono costare un gesto in più: un accesso d’emergenza, la cancellazione di un account o di un progetto, lo spegnimento di un servizio, il ripristino di fabbrica. Il vetro che si rompe dice che non è una conferma come le altre; per le conferme di tutti i giorni c’è la finestra che nasce dal pulsante.

Sul telefono

La lastra prende la larghezza dello schermo meno 16 pixel per lato (358 a 390) e la spiegazione va su tre righe; il pulsante resta alto 56 e i due del vetro 46. Col dito un tocco apre, un tocco fuori la rimette via, e i pezzi cadono oltre il fondo dello schermo senza farlo scorrere né sforare di lato.

Con il movimento ridotto

La lastra non sale e non si inclina: le parole del pulsante svaniscono e il vetro compare con una dissolvenza al suo posto, e se ne va allo stesso modo. Il martelletto non si muove; premendo Break glass le crepe compaiono tutte insieme, già disegnate, poi il vetro crepato svanisce e solo dopo compare l’accesso, anche lui con una dissolvenza.

Trappole

  • Nel momento in cui il vetro si crepa ogni pezzo si spostava di frazioni di pixel e girava di qualche decimo di grado: il browser ricampionava le lettere e tutta la finestra diventava sfocata. Ora i pezzi si spostano di pixel interi e senza girare, e la crepa si vede dalla luce un poco diversa che prende ognuno.
  • Nei primi centesimi di secondo la lastra, ancora mezza trasparente, lasciava vedere sotto la scritta Emergency access: due testi uno sull’altro. Le parole del pulsante svaniscono in 0,1 secondi appena si preme, e il vetro diventa pieno in poco più.
  • I pezzi che cadono passavano davanti alla scritta Admin access appena comparsa. Il pulsante ora diventa rosso subito, ma le sue parole aspettano che nessun pezzo gli stia davanti, misurando i riquadri dei pezzi contro il suo.
  • Una luce bianca piatta su un pezzo che si gira lo faceva sembrare un foglio grigio. La lucentezza è una sfumatura che attraversa il pezzo stesso (lo strato di luce ha la misura del suo riquadro), più debole e solo vicino all’angolo giusto.
  • Un punto in un angolo del vetro sta su due lati: controllando un lato solo, il bordo rotto di un pezzo d’angolo veniva disegnato lungo il bordo dritto, fuori dall’angolo arrotondato. I lati ora sono bit, e l’SVG dei bordi è tagliato con inset(0 round 24px).
  • Le crepe disegnate e i tagli dei pezzi devono passare per gli stessi punti, anche quelli che deviano fra un anello e l’altro: altrimenti le parole si spezzano un poco più in là della riga. Ogni raggio tiene i suoi punti intermedi e li usano tutti e due.
  • Col movimento ridotto l’accesso compariva sotto il vetro crepato che svaniva, e dopo End il pulsante tornava vuoto perché le sue parole erano rimaste a opacità zero. Ora prima svanisce il vetro e poi compare l’accesso, e tornando le parole riprendono la loro opacità.
  • L’anteprima della libreria clicca sempre lo stesso riquadro: con una lista fissa di passi (apri, annulla, apri, rompi, chiudi) bastava un clic vero fuori turno per bloccarla. Lo script guarda lo stato: chiusa apre, aperta alterna annulla e rompi, con l’accesso attivo lo chiude.

Librerie

GSAP 3.15.0, Reddit Sans (font variabile) 5.3.0.

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

Collaudo

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