Vai al contenuto
animorio
EN
Tutti i componenti

Il pulsante del tubo pneumatico

Pulsanti, Fisica, TransizioniCanvas, GSAPImpegnativaPeso compresso: Demo 10 KBGSAP 28 KBGratisScarica lo zip

Il pulsante Submit request spedisce la richiesta con la posta pneumatica degli uffici d'una volta: una capsula d'ottone col foglio arrotolato esce dal pulsante, viene risucchiata con uno strattone nel tubo di vetro, accelera, si inclina e si schiaccia nelle curve e sparisce in alto; il vetro vibra, esce un soffio d'aria, e poco dopo una capsula più piccola torna giù con Received.

Il codice

Una cartella che funziona da sola: index.html, style.css, script.js e le librerie da CDN. Nella scheda React 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 pneumatic tube button</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/instrument-sans@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the pneumatic tube: a glass tube rises from the top of the Submit button, bends and climbs out of sight.
         Pressed, a brass carrier with the rolled request inside comes up out of the button, is sucked into the tube and
         shoots away; a little later a smaller carrier comes back down with the receipt -->
    <div class="pneu" data-pneu>
      <!-- the line the carrier follows, read with getPointAtLength; the glass is drawn along it in the canvas -->
      <svg class="pneu__route" viewBox="0 0 340 480" aria-hidden="true" focusable="false">
        <path data-route d="M170 432 L170 316 C170 274 180 258 214 241 L258 219 C292 202 296 186 296 150 L296 -30"/>
      </svg>
      <canvas class="pneu__canvas" aria-hidden="true" data-canvas></canvas>

      <button class="pneu__btn" type="button" aria-describedby="pneu-live" data-btn data-autoclic>
        <span class="pneu__words" aria-hidden="true">
          <span class="pneu__word" data-word>
            <svg class="pneu__icon" viewBox="0 0 24 24" data-icon="send"><path d="M12 19V6.5M6.5 11.5L12 6l5.5 5.5"/><path d="M5 3.5h14"/></svg>
            <span data-text>Submit request</span>
          </span>
        </span>
        <span class="sr" data-name>Submit request</span>
      </button>
      <p class="sr" id="pneu-live" aria-live="polite" data-live></p>
    </div>
  </main>

  <!-- the tick drawn on Received -->
  <template data-tick>
    <svg class="pneu__icon pneu__icon--tick" viewBox="0 0 24 24"><path d="M5 12.5l4.4 4.4L19 7.4"/></svg>
  </template>

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

23 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 del tubo pneumatico» da Animorio e adattala al mio sito

Cosa fa

Su un fondo bianco un pulsante a pillola blu notte con una freccia e Submit request; dal suo bordo di sopra, dentro un collare d'ottone, sale un tubo di vetro trasparente con i riflessi bianchi e i bordi azzurrini, che curva a destra, sale in diagonale tenuto da due fascette d'ottone, torna dritto e svanisce in alto, con la sua ombra morbida sul foglio. Col mouse sopra il pulsante (o col dito che preme) dal collare si affaccia la capsula. Cliccando, la scritta diventa Sending…, la capsula d'ottone con i due anelli di feltro rosso e una finestrella da cui si vede il foglio arrotolato sale dal pulsante nel tubo con un piccolo rimbalzo, trema un istante mentre la pressione sale e poi viene risucchiata con uno strattone: accelera, si allunga per l'accelerazione, nelle curve si inclina, si schiaccia e sbatte contro la parete esterna, lascia una scia color ottone e sparisce in alto. Il tubo vibra con un'onda che corre verso l'alto e dalla bocca esce una nuvoletta d'aria; la scritta diventa Request sent. Dopo poco più di un secondo una capsula più piccola scende giù per il tubo, viene frenata dal cuscino d'aria in fondo, rimbalza e si posa nella bocca con un altro soffio; la scritta diventa Received con una spunta verde che si disegna. Dopo un paio di secondi la capsula rientra nel pulsante e torna Submit request.

Come funziona

Il tracciato letto una volta

Il tubo è un tracciato SVG nascosto (due curve di Bézier fra tratti dritti). All'avvio getTotalLength e getPointAtLength lo leggono ogni 2 unità in una tabella: posizione, angolo della tangente e curvatura (quanto gira l'angolo per unità di lunghezza). Durante l'animazione la capsula non chiama più l'SVG: interpola nella tabella, e prima dell'inizio o dopo la fine prosegue dritta.

La legge della pressione

La capsula ha una sola coordinata, la lunghezza percorsa lungo il tubo, mossa a passi di 1/240 di secondo (col passo del fotogramma limitato a 1/30): accelerazione = (JOLT·e^(−t/0,09) + 2300)·SUCTION − FRICTION·v. Lo strattone iniziale svanisce in un decimo di secondo, resta la spinta costante, l'attrito cresce con la velocità: parte di colpo e poi corre verso una velocità limite. Al ritorno cade frenata dall'aria e in fondo una molla smorzata (il cuscino d'aria del tubo chiuso) la ferma con un rimbalzo.

Inclinazione, parete e squash

L'angolo della capsula insegue la tangente con una molla poco smorzata, limitata a ±0,32 radianti: entra nella curva in ritardo e ne esce oscillando. La forza centripeta v²·k la spinge contro la parete esterna e la schiaccia lungo l'asse; l'accelerazione la allunga. Allungamento e schiacciamento passano per un'altra molla, così la capsula tremola dopo ogni curva; oltre una certa velocità dietro compare una scia sfumata.

Il vetro disegnato lungo la linea

Il tubo si disegna in canvas come più tratti paralleli alla linea centrale, spostati lungo la normale: la parete di fondo velata, la capsula, poi i due bordi scuri dove il vetro è più spesso e due riflessi bianchi sfalsati. L'ombra sul foglio è disegnata una volta con shadowBlur in un canvas a parte. La vibrazione sposta i punti lungo la normale con un'onda che sale e si smorza, nulla vicino al collare; in cima un gradiente destination-out fa svanire tubo e capsula.

Gli stati

Sending…, Request sent e Received girano come un rullo nel pulsante, la spunta si disegna con stroke-dashoffset. Mentre la richiesta viaggia il pulsante ha aria-disabled e i clic si ignorano; una regione aria-live dice ogni passaggio. Il canvas si ridisegna solo mentre qualcosa si muove.

Valori da cambiare

NomeFileDi partenzaCosa cambia
SUCTIONscript.js1Quanto tira il tubo: 1 è la spinta normale, 2 il doppio.
JOLTscript.js9000Lo strattone del primo istante del risucchio, in pixel al secondo al quadrato.
FRICTIONscript.js1.3Quanto l'aria e le pareti frenano la capsula.
LEANscript.js1Quanto la capsula si inclina nelle curve (0 = segue il tubo esattamente).
SQUASHscript.js1Quanto la capsula si allunga accelerando e si schiaccia nelle curve.
SHAKEscript.js1Quanto vibra il vetro quando la capsula passa.
BACKscript.js1.3I secondi prima che la ricevuta torni giù per il tubo.
HOLDscript.js2.4I secondi in cui resta Received prima che il pulsante torni pronto.

Provali nel Playground

Quando usarla

Per l'invio di un modulo che conta: una richiesta di preventivo, un ticket all'assistenza, una candidatura, un ordine a un ufficio. Sta bene in un sito con un carattere artigianale o d'archivio, dove l'attesa di un invio diventa un piccolo spettacolo e la ricevuta che torna dice che è arrivato.

Sul telefono

Il componente è largo 340 pixel e sta in uno schermo da 390; sotto i 370 si stringe a 300 e il disegno del tubo si scala con lui. Il canvas segue la densità dello schermo (fino a 2). Il dito che preme fa affacciare la capsula come il mouse sopra.

Con il movimento ridotto

Niente viaggio nel tubo: la scritta passa in dissolvenza a Sending…, poi a Request sent, e la piccola capsula compare in dissolvenza già posata nella bocca con Received; poi svanisce. Il tubo non vibra e non escono soffi.

Trappole

  • Con l'ombra del tubo disegnata a ogni fotogramma con shadowBlur, nel browser senza GPU ogni fotogramma costava decine di millisecondi: l'ombra non vibra, quindi si disegna una volta in un canvas a parte e si copia.
  • La capsula rimbalzata in fondo restava schiacciata e girata come all'ultimo passo della fisica: posandosi si rimettono a posto allungamento, angolo e scostamento dalla parete.
  • Il rullo delle scritte con fromTo dentro una timeline spostava subito la scritta vecchia in basso (immediateRender): la scritta saltava prima di uscire. Serve immediateRender: false.
  • Il cuscino d'aria del ritorno fatto come una forza crescente faceva oscillare la capsula senza mai fermarsi esattamente: ora è una molla smorzata verso il punto di riposo, e dopo tre secondi la capsula si posa comunque.
  • Con il passo di tempo intero di un fotogramma lento lo strattone faceva saltare la capsula oltre la prima curva: la fisica va a passi di 1/240 di secondo, col fotogramma limitato a 1/30.

Librerie

GSAP 3.15.0, Instrument Sans (font variabile) 5.3.0.

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

Collaudo

Provata il 5 ottobre 2026

  • Computer: Fatto
  • Telefono: Fatto
  • Movimento ridotto: Fatto
  • Safari su iPhone: Fatto

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