Vai al contenuto
animorio
EN
Tutti i componenti

La chat sottovuoto

Chat, Fisica, SVG, Transizioni, TestoGSAPImpegnativaPeso compresso: Demo 17 KBGSAP 28 KBGratisScarica lo zip

La chat di casa di tre coinquilini, dove il campo per scrivere è una pelle grigia fatta di punti su molle. Inviando, la pelle si stacca dal campo e si stringe intorno alle parole come una busta sottovuoto, diventa gialla e le porta su nella conversazione, allungandosi per strada e ondeggiando quando arriva; dal pulsante ne esce una nuova. La risposta si scrive in una bolla fantasma del colore di chi scrive: al posto delle parole crescono barrette lunghe come loro, a raffiche e con qualche ripensamento, e quando arriva la bolla si riempie e le barrette si sviluppano nelle parole.

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 vacuum-sealed chat</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/rubik@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the group chat of a shared flat: the field's grey skin closes round the words like a vacuum pack and carries
         them up into the conversation, and a flatmate's answer is written in a ghost bubble that shows the shape of
         its words before the words themselves -->
    <section class="chat" aria-label="Flat 4B, group chat" data-chat data-autoclic>
      <header class="chat__head">
        <div class="chat__faces" aria-hidden="true">
          <span class="face" style="--who: var(--who-1)">I</span>
          <span class="face" style="--who: var(--who-2)">T</span>
        </div>
        <div class="chat__title">
          <h2 class="chat__name">Flat 4B</h2>
          <p class="chat__status" aria-hidden="true" data-status><span class="status__line">Iris, Theo and you</span></p>
        </div>
      </header>

      <div class="chat__thread" data-thread>
        <div class="chat__log" role="log" aria-live="polite" aria-label="Messages" data-log></div>
      </div>

      <form class="chat__composer" data-form>
        <div class="field" data-field>
          <label class="sr" for="chat-input">Message Flat 4B</label>
          <textarea class="field__input" id="chat-input" rows="1" placeholder="Message Flat 4B" maxlength="280" enterkeyhint="send" aria-describedby="chat-keys" data-input></textarea>
          <span class="sr" id="chat-keys">Enter sends, Shift and Enter starts a new line.</span>
          <span class="field__caret" aria-hidden="true" data-caret></span>
          <button class="send" type="submit" aria-label="Send" disabled data-send>
            <span class="send__bg" aria-hidden="true"></span>
            <svg class="send__arrow" viewBox="0 0 24 24" aria-hidden="true" data-arrow><path d="M12 18.6V5.8M6.6 11.2 12 5.8l5.4 5.4"/></svg>
          </button>
        </div>
      </form>

      <!-- the skins that move between the field and the conversation, and the words they carry -->
      <svg class="chat__skins" aria-hidden="true" data-skins></svg>
      <div class="chat__fly" aria-hidden="true" data-fly></div>
    </section>
  </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.

48 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 chat sottovuoto» da Animorio e adattala al mio sito

Cosa fa

Su un fondo bianco una chat larga 384 pixel: in alto i due tondi con le iniziali, Flat 4B e Iris, Theo and you; sotto, quattro messaggi (Iris e Theo a sinistra in grigio, col nome colorato sopra il primo di ogni gruppo, i miei a destra in giallo) e in fondo il campo Message Flat 4B, una pillola grigia alta 56 pixel col pulsante tondo per inviare. Toccando il campo gli si disegna intorno un bordo grigio; scrivendo, il fondo nero del pulsante si gonfia con un rimbalzo e la freccia diventa gialla, e quando le parole vanno a capo il campo cresce verso l’alto, fino a cinque righe, col bordo di sopra che ondeggia un attimo mentre i messaggi salgono a fargli posto. Inviando (Invio, o il pulsante; Maiusc+Invio va a capo) il pulsante si abbassa e torna su, la freccia schizza via e ne sale una grigia, e la pelle grigia del campo si stacca e si stringe intorno alle parole, ingiallendo: per un istante nel campo vuoto c’è solo il messaggio sottovuoto. Poi sale e scivola al suo posto in fondo alla conversazione, allungandosi nel verso in cui va, con le parole dentro che non si spostano dalle loro righe; arrivando si schiaccia e ondeggia, e i messaggi sopra, che si erano già alzati, ricevono una piccola spinta. Intanto dal pulsante esce una goccia grigia che si allarga nel campo nuovo. Poco dopo sotto il mio messaggio compare la bolla di chi risponde: solo un contorno nel suo colore, col nome sopra, e al posto della riga sotto Flat 4B c’è Theo is typing. Dentro crescono barrette azzurre lunghe come le parole che sta scrivendo, a raffiche, con un cursore dopo l’ultima: a volte una parola cresce, si ferma, viene cancellata e riscritta, e una parola che non ci sta più scivola alla riga sotto mentre la bolla si allunga. Mandata la risposta, la bolla si riempie di grigio con un piccolo sobbalzo, le barrette svaniscono e al loro posto le parole vengono a fuoco una dopo l’altra. A seconda di quello che si scrive risponde Theo (in blu) o Iris (in lampone).

Come funziona

Una pelle di punti su molle

Ogni forma che si muove è un anello di 62 punti messi sempre nello stesso ordine su un rettangolo arrotondato (sette su ogni angolo, dodici sui lati lunghi, cinque su quelli corti): così un angolo del campo diventa sempre un angolo della bolla. Ogni punto è tirato verso il suo posto da una molla smorzata, x'' = −k(x − meta) − c·x', a passi di 1/240 di secondo col passo del fotogramma limitato a 1/30; i due vicini lo trascinano, ma sulla differenza dal proprio posto e non sulla posizione, così la pelle si posa esattamente sulla forma e si smussano solo le onde. In movimento si disegna come una curva di Catmull-Rom chiusa; ferma, con archi esatti, e lascia il posto alla bolla vera, un elemento con border-radius. Quando niente si muove il ciclo si spegne.

Sottovuoto

All’invio una copia nascosta della textarea, con le stesse misure e uno span per parola, dice dove sta ogni parola; le parole passano in uno strato sopra tutto, nello stesso punto, nello stesso fotogramma in cui la textarea si svuota. La pelle del campo prende come meta il riquadro delle parole più il margine della bolla, con molle 1,9 volte più rigide e smorzamento 0,72, mentre il colore va dal grigio al giallo: in WRAP secondi il campo si è stretto intorno al messaggio.

Il viaggio

Il messaggio vero è già al suo posto nella conversazione, trasparente. Dopo WRAP la meta della pelle è un riquadro a metà strada fra quello del campo e la bolla vera: x e larghezza seguono power3.inOut, y e altezza power3.out, così sale prima e scivola dopo, in LIFT secondi. I punti che stanno davanti nel verso del viaggio hanno le molle più rigide di quelli dietro (fino al 35% in più o in meno, dal prodotto fra la normale del punto e la direzione): la pelle si allunga mentre va e si schiaccia quando si ferma. Una pelle nuova esce dal pulsante, da un punto di 4 pixel, e si allarga nel campo.

Le parole stanno dentro

Le parole non hanno una curva loro: ognuna sta a una distanza fissa dal centro della forma, che va da quella nel campo a quella nella bolla, e tutte si spostano di quanto il baricentro della pelle resta indietro rispetto alla sua meta. Così non escono mai dalla pelle, ondeggiano con lei e sono esattamente al loro posto quando è ferma. La bolla è larga al massimo quanto le righe del campo (max-width: calc(100% − 50px)), quindi gli a capo restano gli stessi e le parole viaggiano in blocco.

La conversazione fa posto

Prima di ogni cambio si legge dove sta ogni messaggio; dopo, ognuno riparte dal vecchio posto su una molla, i più bassi un po’ più rigidi, così la spinta sale per la conversazione. Quando la bolla arriva, i messaggi sopra ricevono una spinta verso l’alto di BUMP pixel al secondo, il 30% in meno per ognuno più su. I più vecchi svaniscono sotto l’intestazione (una maschera in cima) e oltre i quattordici se ne vanno.

La bozza e lo sviluppo

La bozza è una bolla vera con le parole scritte fin lì in inchiostro trasparente: si misurano con getClientRects e non si vedono. Su ogni parola una barretta lunga come lei, un cursore dopo l’ultima, e intorno una pelle col contorno nel colore di chi scrive che segue la bolla mentre cresce; una parola che va a capo fa scivolare la sua barretta alla riga sotto. Il modo di scrivere si inventa una volta per risposta con un generatore col seme preso dal testo: raffiche a TYPING lettere al secondo, pause dopo virgole e punti, una parola scritta e cancellata. Mandata la risposta, il messaggio vero prende il posto della bozza e la sua pelle; il colore passa al grigio pieno mescolato con l’alfa premoltiplicata, una spinta dal centro la gonfia un attimo, le barrette svaniscono e le parole entrano da blur(5px). La conversazione è un role log con aria-live polite, ogni messaggio comincia con chi parla (nascosto alla vista) e la bozza è aria-hidden; un clic da script, l’anteprima della libreria, scrive un messaggio lettera per lettera senza prendere il focus e lo manda.

Valori da cambiare

NomeFileDi partenzaCosa cambia
WRAPscript.js0.16I secondi in cui la pelle del campo si stringe intorno alle parole, prima di partire.
LIFTscript.js0.5I secondi del viaggio del messaggio dal campo al suo posto nella conversazione.
SPRINGscript.js[420, 0.5]Le molle della pelle: quanto sono rigide, e quanto smorzate, da 0 (ondeggia per sempre) a 1 (non ondeggia).
TENSIONscript.js0.5Quanto ogni punto della pelle si trascina dietro i vicini, da 0 a 1: più alto, più liscia.
TYPINGscript.js22Le lettere al secondo di un coinquilino che scrive la risposta.
WAITscript.js0.6I secondi fra l’arrivo del messaggio e l’inizio della risposta.
BUMPscript.js130Quanto il messaggio che arriva spinge quelli sopra, in pixel al secondo.
PEOPLEscript.js['Iris', 'Theo']I coinquilini, nei colori --who-1 e --who-2.
REPLIESscript.js[['milk', 'Theo', 'Guilty. Two cartons on my way home, promise.'], …]Una parola da cercare nel mio messaggio, chi risponde e la risposta.
OTHERscript.js[['Iris', 'Ha, fair. Let’s talk about it tonight.'], …]Le risposte a tutto il resto, una dopo l’altra.
DEMOscript.js['Who finished the oat milk?', …]Quello che l’anteprima della libreria scrive e manda, un messaggio per clic.

Provali nel Playground

Quando usarla

Per la chat di un’app di gruppo o di coinquilini, il supporto di un negozio, un assistente che risponde, i commenti dal vivo, la demo di un’app di messaggi: ovunque il campo per scrivere e il momento dell’invio debbano avere un carattere.

Sul telefono

La chat prende la larghezza dello schermo meno i margini (358 pixel a 390) e la bolla resta larga quanto le righe del campo; la textarea è a 16 pixel, così Safari su iPhone non ingrandisce la pagina, la tastiera mostra il tasto per inviare (enterkeyhint send) e il pulsante è un bersaglio di 44 pixel, che si abbassa sotto il dito.

Con il movimento ridotto

Niente pelle che si stringe o viaggia: il messaggio compare al suo posto sfumando e il campo resta com’è; i messaggi non scivolano, la bozza cresce a parole senza che le barrette si spostino e la risposta compare sfumando.

Trappole

  • Parole che seguono la loro curva mentre la pelle insegue sulle molle escono dalla pelle (qui la parola in fondo restava fuori a destra): devono essere portate dalla pelle, a distanza fissa dal centro della forma più il ritardo del suo baricentro.
  • Far partire le parole una dopo l’altra (stagger) mentre vanno tutte a destra fa raggiungere le ultime dalle prime: si accavallano. Viaggiano insieme.
  • Se la bolla è più stretta del campo, le parole cambiano riga per strada e passano sopra le altre: la bolla è larga al massimo quanto le righe del campo, e una parola che cambiasse riga comunque si dissolve e ricompare invece di attraversare.
  • I vicini che tirano sulla posizione, invece che sulla distanza dal proprio posto, arrotondano gli angoli e la pelle non si posa più sulla bolla; e una rigidità diversa da punto a punto oltre il 5% fa seghettato il bordo di una pelle che si stringe di colpo.
  • Mescolare un azzurro quasi trasparente con un grigio pieno canale per canale fa passare la bolla per un azzurro carico: si mescola con l’alfa premoltiplicata.
  • Un pulsante che si disabilita mentre ha il focus lo perde, e chi usa i tasti si ritrova sulla pagina: dopo l’invio dal pulsante il focus torna nel campo. E una transizione CSS sul transform del pulsante ritarda lo scale scritto da GSAP: la pressione la fa solo GSAP.

Librerie

GSAP 3.15.0, Rubik (font variabile) 5.3.0.

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