Vai al contenuto
animorio
EN
Tutti i componenti

Il pulsante della porta

Pulsanti, Fisica, 3DSolo CSS, Canvas, GSAPImpegnativaPeso compresso: Demo 13 KBGSAP 28 KBGratisScarica lo zip

Il pulsante Log out di un account, con una porta vera nella punta tonda della pillola: lo stipite color crema con la soglia, la porta dipinta con due specchiature e la maniglia d'ottone, e dietro una stanza con la lampadina accesa, di cui si vede il filo di luce sotto la porta. La porta è in CSS 3D e gira sui cardini: sotto il puntatore la maniglia si abbassa e la porta si socchiude, e una lama di luce calda si allarga sulla pillola, larga quanto lo spiraglio. Al clic la porta si spalanca, una piccola sagoma esce camminando, la porta sbatte e rimbalza sulla battuta, e la luce dentro si spegne: Signed out. Il clic dopo la luce si riaccende, la sagoma rientra e la porta si richiude.

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 door button</title>
  <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 door button: the Log out button of an account, with a real door in the round right end of the pill, built
         in CSS 3D: the frame, the door with its lever handle, and behind it a room with its light on. Under the
         pointer the handle goes down and the door opens a few degrees: a blade of warm light spreads over the pill.
         A click opens it wide, a small figure walks out, the door shuts and bounces on its stop and the light goes
         out; the next click signs back in, the light comes on and the figure walks home -->
    <div class="exit" data-exit>
      <button class="exit__btn" type="button" data-btn data-autoclic>
        <span class="exit__fill" aria-hidden="true"></span>
        <canvas class="exit__light" aria-hidden="true" data-light></canvas>
        <span class="exit__faces">
          <span class="exit__face" data-face="in">
            <span class="exit__lead" data-lead-in>Signed in as Ada</span>
            <span class="exit__word" data-wide="Log out" data-word-in>Log out</span>
          </span>
          <span class="exit__face" data-face="out" aria-hidden="true">
            <span class="exit__lead" data-lead-out>Signed out</span>
            <span class="exit__word" data-wide="Sign in" data-word-out>Sign in</span>
          </span>
          <span class="exit__face exit__face--busy" data-face="busy" aria-hidden="true">
            <span class="exit__shine" data-busy-text>Signing out…</span>
          </span>
          <span class="exit__face exit__face--big" data-face="big" aria-hidden="true">
            <span class="exit__big" data-big-text>Signed out</span>
          </span>
        </span>
        <span class="exit__doorway" aria-hidden="true" data-doorway>
          <span class="exit__room" data-room>
            <span class="exit__wall"></span>
            <span class="exit__cord"></span>
            <span class="exit__bulb" data-bulb></span>
          </span>
          <span class="exit__persp" data-persp>
            <span class="exit__door" data-door>
              <span class="exit__panel exit__panel--top"></span>
              <span class="exit__panel exit__panel--low"></span>
              <span class="exit__shade" data-shade></span>
              <span class="exit__handle">
                <span class="exit__rose"></span>
                <span class="exit__lever" data-lever></span>
              </span>
            </span>
          </span>
          <span class="exit__frame"></span>
          <span class="exit__sill"></span>
          <span class="exit__under" data-under></span>
        </span>
        <svg class="exit__walker" aria-hidden="true" data-walker>
          <defs>
            <clipPath id="exit-clip"><rect data-clip x="-60" y="-20" width="400" height="100"/></clipPath>
          </defs>
          <g clip-path="url(#exit-clip)">
            <g data-figure opacity="0">
              <path class="exit__limb exit__limb--far" data-limb="farLeg"/>
              <path class="exit__limb exit__limb--far exit__limb--arm" data-limb="farArm"/>
              <path class="exit__limb exit__limb--body" data-limb="body"/>
              <circle class="exit__head" r="3.1" data-head/>
              <path class="exit__limb" data-limb="nearLeg"/>
              <path class="exit__limb exit__limb--arm" data-limb="nearArm"/>
            </g>
          </g>
        </svg>
      </button>
      <p class="sr" aria-live="polite" data-live></p>
    </div>
  </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.

28 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 pulsante della porta» da Animorio e adattala al mio sito

Cosa fa

Su un fondo nero una pillola color petrolio, alta 60 pixel, con un filo di luce in alto. A sinistra, in Mona Sans, una riga piccola grigio-verde, Signed in as Ada, e sotto Log out color avorio; nella punta tonda di destra una porta vista di fronte: lo stipite e l'architrave color crema, più scuri sul lato in ombra, la soglia chiara che sporge un poco, e la porta color ruggine con due specchiature incassate e una maniglia d'ottone a leva. Sotto la porta passa un filo di luce calda, che si sparge un poco sulla pillola davanti alla soglia: dentro la luce è accesa. All'arrivo il pulsante sale piano e la lampadina, dietro la porta, si accende con un paio di guizzi. Col mouse sopra la scritta si allarga, il fondo si gonfia con un rimbalzo, la maniglia si abbassa con uno scatto e la porta si socchiude di qualche grado: nello spiraglio si vede la stanza illuminata e dalla soglia esce una lama di luce sottile che corre sulla pillola fino sotto la scritta. Togliendo il mouse la porta si richiude e batte appena sulla battuta. Al clic la scritta diventa Signing out…, con un riflesso che la attraversa; la maniglia scende, la porta si spalanca verso l'interno e la lama diventa un ventaglio di luce: si vede la stanza, la parete calda e la lampadina appesa al filo. Una piccola sagoma scura esce da dietro la porta e cammina a sinistra nella luce, passo dopo passo, con le gambe e le braccia che oscillano; mentre cammina la porta si richiude, sbatte sulla battuta e rimbalza due volte, il muro dà un piccolo sussulto, e la sagoma esce dalla luce e svanisce. Il filo di luce sotto la porta resta un momento, poi la lampadina si spegne con un ultimo bagliore arancione. Arriva Signed out, grande, che poi si rimpicciolisce e sale nella riga piccola, mentre sotto sale Sign in. Un altro clic: Signing in…, la porta si apre sulla stanza buia, la lampadina si accende con i suoi guizzi, la sagoma arriva dal buio e cammina dentro la stanza, la porta si richiude dietro di lei e rimbalza; arriva Signed in e la riga piccola torna Signed in as Ada sopra Log out. Con la tastiera il fuoco mostra un anello avorio e la porta si socchiude come sotto il mouse; Invio o Spazio escono ed entrano. Al telefono il dito appoggiato socchiude la porta e il tocco esce.

Come funziona

La porta in CSS 3D

La porta è uno span dentro un contenitore con perspective: 90px, grande quanto l'apertura (24 per 37 pixel), con transform-origin sul bordo destro: rotateY con l'angolo negativo la fa girare sui cardini verso l'interno. Le specchiature sono box-shadow incassati, e un velo nero con l'opacità di 0,62 · sin(angolo) la scurisce mentre si volta. Dietro c'è la stanza: un fondo buio, una parete calda con l'opacità della luce, il filo e la lampadina, la cui luce e il cui alone sono color-mix e calc sulla variabile --lit che lo script scrive. Lo stipite, la soglia e il filo di luce sotto la porta stanno davanti, così la porta aperta ci passa dietro.

Lo spiraglio, calcolato

Lo script sa dove cade sullo schermo il bordo libero della porta: girando di un angolo a, il bordo va indietro di 24 · sin a e verso i cardini di 24 · (1 − cos a), e la prospettiva lo avvicina al centro di 90 / (90 + 24 · sin a), esattamente come il browser. La larghezza dello spiraglio regola tutto il resto: il filo di luce sotto la porta si spegne appena lo spiraglio si apre, la lama prende la sua apertura, e la sagoma è ritagliata (un clipPath SVG riscritto a ogni fotogramma) a destra del bordo libero, quindi entra ed esce da dietro la porta.

La lama di luce

Un canvas grande quanto la pillola, in mix-blend-mode: screen, disegna la luce solo quando la porta o la lampadina cambiano. La lama è un ventaglio che parte dalla soglia e corre a sinistra: il bordo alto sale di 0,02 + 0,13 · √s radianti e quello basso scende di 0,05 + 0,5 · √s, dove s è lo spiraglio diviso per 16 pixel. La radice fa sì che una porta appena socchiusa dia già una lama sottile e viva. I bordi morbidi sono otto ventagli uno dentro l'altro, ognuno a 0,16 di opacità, con un gradiente che parte quasi bianco e svanisce verso sinistra; intorno all'apertura un alone radiale illumina il muro. Il colore scende verso l'arancione quando la luce è debole, come un filamento che si scalda o si raffredda.

La porta che sbatte

L'angolo della porta è una molla smorzata verso un obiettivo: 84 gradi per aprirsi (lenta e quasi senza rimbalzo), 18 gradi socchiusa sotto il mouse, e −6 gradi da chiusa, cioè un poco oltre la battuta, così la molla la spinge contro. A zero gradi c'è la battuta, un arresto rigido: la porta ci arriva con la sua velocità, si ferma e riparte indietro con BOUNCE volte quella velocità, due o tre volte sempre meno, finché si posa. Quando l'urto è forte il muro e il fondo danno un piccolo sussulto elastico. Passi di 1/240 di secondo, fotogramma limitato a 1/30; ferma la porta, il ciclo smette di calcolare e di disegnare.

La sagoma che cammina

La sagoma è un pittogramma in SVG con sei tratti a capi tondi (corpo, testa, due gambe e due braccia) ridisegnati a ogni fotogramma. La fase del passo viene dalla strada fatta (2π ogni 24 pixel), così i piedi non scivolano. La coscia oscilla di 0,44 · sin(fase), il ginocchio si piega mentre la gamba va avanti (cos(fase) positivo), le braccia vanno al contrario delle gambe col gomito che si piega in avanti. Il bacino si alza quanto basta perché il piede più basso tocchi la soglia: il saliscendi della camminata viene da sé. La gamba e il braccio lontani sono un poco più chiari. GSAP porta la sagoma da dietro la porta alla fine del pianerottolo a velocità WALK, e la dissolve uscendo dalla luce.

Gli stati e le parole

Uscire: Signing out…, la porta si apre, la sagoma esce, la porta sbatte quando è a metà della lama, la luce si spegne, Signed out. Entrare: Signing in…, la porta si apre sul buio, la lampadina si accende (una timeline di guizzi, poi power2.out fino a 1), la sagoma entra, la porta si chiude, Signed in. La parola finita, grande, viene misurata e portata col suo scale proprio dove sta la riga piccola, poi la riga vera la sostituisce e sotto sale l'azione dopo. Il pulsante è un button vero, aria-disabled mentre lavora; una zona aria-live dice Signing out…, Signed out, Signing in…, Signed in as Ada. Un giro dura circa 4,2 secondi, più dei 2,8 fra due clic dell'anteprima: un clic cade nell'attesa e ogni stato resta in vista.

Valori da cambiare

NomeFileDi partenzaCosa cambia
PERSONscript.jsAdaChi è entrato: la riga piccola dice Signed in as e questo nome.
LOG_OUTscript.jsLog outLa scritta da dentro, l'azione per uscire.
SIGN_INscript.jsSign inLa scritta da fuori, l'azione per entrare.
SIGNING_OUTscript.jsSigning out…La scritta mentre esce; è anche quello che dice la zona aria-live.
SIGNING_INscript.jsSigning in…La scritta mentre entra.
SIGNED_OUTscript.jsSigned outLa parola a lavoro fatto, che poi diventa la riga piccola sopra Sign in.
SIGNED_INscript.jsSigned inLa parola a lavoro fatto, entrando; la riga piccola aggiunge as e il nome.
AJARscript.js18Di quanti gradi si socchiude la porta sotto il puntatore: più è alta, più larga la lama di luce.
OPENscript.js84Di quanti gradi si apre per far passare la sagoma.
WALKscript.js44Quanto cammina svelta la sagoma, in pixel al secondo: le gambe vanno sempre al passo con la strada.
BOUNCEscript.js0.45Quanta velocità tiene la porta quando batte sulla battuta: 0 si ferma secca, 0,8 sbatacchia a lungo.
FLICKERscript.jstrueLa lampadina guizza prima di accendersi; spento, si accende con una dissolvenza.

Provali nel Playground

Quando usarla

Per il pulsante che fa uscire o entrare: il menu dell'account di un'app, la barra di una dashboard, la pagina del profilo, un'area riservata, un sito di case vacanza o di hotel, uno studio di architettura o di interni. La porta dice cosa succede meglio di una freccia dentro una scatola. Va collegato all'uscita e all'entrata vere del tuo sito (la chiamata al server o al servizio di accesso): qui è tutto simulato.

Sul telefono

La pillola è larga circa 245 pixel: a 390 pixel ci sta con margine, e con scritte più lunghe il carattere si rimpicciolisce. La porta e la sagoma restano della stessa misura. Il dito appoggiato sul pulsante socchiude la porta come il mouse, e il tocco fa uscire o entrare.

Con il movimento ridotto

La porta resta chiusa e la sagoma non cammina; la pillola non si gonfia e la scritta non si allarga (sotto il mouse il fondo si schiarisce appena). Uscendo la luce sotto la porta si spegne in dissolvenza e le parole cambiano in dissolvenza; entrando la luce si riaccende allo stesso modo, senza guizzi.

Trappole

  • Con la prospettiva messa a sinistra della porta (l'occhio al centro della pillola) la porta aperta a 84 gradi, girando verso l'interno, si proiettava quasi su tutta l'apertura: lo spiraglio restava di due pixel e la sagoma non passava. La prospettiva ora ha l'origine al centro dell'apertura, e lo script usa la stessa formula del browser per sapere dove cade il bordo libero.
  • All'apertura della pagina in alto a sinistra della pillola c'era un pallino scuro: la testa della sagoma, un cerchio con r fissato nell'HTML, stava a x 0 e y 0 prima che la sagoma partisse. Il gruppo della sagoma nasce con opacity 0.
  • Con l'obiettivo da chiusa molto oltre la battuta la porta ci arrivava così veloce che rimbalzava di una trentina di gradi, come sbattuta da una corrente. Simulata a parte, la scelta è −6 gradi con smorzamento 0,35: il primo rimbalzo è di circa nove gradi, il secondo di uno.
  • La lama col bordo netto, larga quanto il ventaglio pieno, tagliava la pillola in diagonale come un faro. Ora l'apertura cresce con la radice dello spiraglio, è più stretta in alto, e i bordi sono otto ventagli sovrapposti a bassa opacità.
  • La gamba e il braccio lontani, schiariti verso il colore della luce, fuori dalla lama sembravano una gamba color legno staccata dal corpo. Ora si schiariscono verso il colore del muro.
  • Un giro durava quasi 5,5 secondi e nell'anteprima, che clicca ogni 2,8, lo stato finito restava in vista un attimo prima del clic dopo. La sagoma cammina più svelta e la parola finita aspetta meno: un giro dura circa 4,2 secondi.

Librerie

GSAP 3.15.0, Mona Sans (font variabile) 5.3.0.

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

Collaudo

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