Vai al contenuto
animorio
EN
Tutti i componenti

Il cuscino che ricorda

Selettori, WebGL, Fisica, HoverWebGL, GSAPImpegnativaPeso compresso: Demo 11 KBGSAP 28 KBGratisScarica lo zip

La fermezza di un materasso scelta su un lungo cuscino di velluto blu notte imbottito di memory foam: l'opzione scelta è quella premuta nel cuscino. Scegliendone un'altra la pressione scivola fin lì, e dove è passata la schiuma si riempie piano, come il memory foam vero: per un attimo il percorso resta stampato nel velluto. La scelta cambia il cuscino stesso: morbido affonda di più e ci mette tanto a tornare, rigido cede appena e torna su con un piccolo rimbalzo.

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 memory foam picker</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/full.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the firmness picker of a mattress shop, made as a long velvet cushion of memory foam. The chosen firmness is
         where the cushion is pressed in; choosing another, the press slides across the cover to it and the foam it
         leaves fills back in slowly, as memory foam does. The choice changes the cushion itself: soft, it sinks deep
         and takes its time to recover; firm, it barely gives and springs back. The cushion is drawn by a WebGL shader
         under four real radio buttons, and the letters soften with the foam -->
    <div class="firm" data-firmness>
      <div class="firm__head">
        <span class="firm__title" id="firm-title">Firmness</span>
        <span class="firm__hint" aria-live="polite" data-hint>For most sleepers</span>
      </div>
      <div class="firm__bed" role="radiogroup" aria-labelledby="firm-title" data-bed>
        <canvas class="firm__canvas" aria-hidden="true" data-canvas></canvas>
        <span class="firm__dent" aria-hidden="true" data-dent></span>
        <label class="firm__opt" data-opt data-say="For side sleepers">
          <input class="firm__radio" type="radio" name="firmness" value="soft">
          <span class="firm__name">Soft</span>
        </label>
        <label class="firm__opt" data-opt data-say="For most sleepers">
          <input class="firm__radio" type="radio" name="firmness" value="medium" checked>
          <span class="firm__name">Medium</span>
        </label>
        <label class="firm__opt" data-opt data-say="For back sleepers">
          <input class="firm__radio" type="radio" name="firmness" value="firm">
          <span class="firm__name">Firm</span>
        </label>
        <label class="firm__opt" data-opt data-say="For stomach sleepers">
          <input class="firm__radio" type="radio" name="firmness" value="extra-firm">
          <span class="firm__name">Extra firm</span>
        </label>
      </div>
    </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.

32 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 cuscino che ricorda» da Animorio e adattala al mio sito

Cosa fa

Su un fondo bianco, da solo, il selettore della fermezza di un materasso: sopra a sinistra la parola Firmness e a destra per chi è la scelta (For most sleepers); sotto un cuscino lungo e stretto, alto 56 pixel, di velluto blu notte con il cordoncino lungo la cucitura, con quattro nomi stampati in avorio: Soft, Medium, Firm, Extra firm. L'opzione scelta è premuta nel cuscino: una buca a forma di pillola, con l'ombra sul bordo dalla parte della luce, il bordo opposto che si accende e il pelo schiacciato del fondo un po' più chiaro; il suo nome è pieno e più spesso, gli altri sono velati. All'apertura il cuscino sale piano dalla pagina e la pressione ci affonda dentro, e il nome si accende mentre affonda. Scegliendo un'altra opzione la pressione scivola fin lì come un dito trascinato sul cuscino, un poco più su mentre corre, con la stoffa che si raccoglie davanti a lei; dove è passata resta un solco che si riempie piano, come il memory foam, e i nomi che attraversa si abbassano e si rialzano con lui. Il nome nuovo si accende quando la pressione arriva, non al clic. Intanto cambia il cuscino: Soft è più gonfio, la buca è profonda, larga e dai bordi morbidi, e il solco dura un paio di secondi; Extra firm è teso, la buca è bassa e netta, arriva con un piccolo rimbalzo e il solco sparisce quasi subito. Anche le lettere si ammorbidiscono o si induriscono con lui, sull'asse SOFT del carattere. La riga in alto cambia frase in dissolvenza. Il mouse sopra il cuscino ci affonda appena e lascia la sua scia; premuto affonda di più; ripremendo l'opzione già scelta la buca affonda e poi torna.

Come funziona

Quattro radio veri

Il cuscino è un role radiogroup con aria-labelledby sulla parola Firmness, e dentro quattro label con il loro input radio, nascosto ma presente: prende il fuoco, le frecce lo muovono come in ogni gruppo di radio (anche da un capo all'altro) e lo screen reader legge il nome. La riga in alto è aria-live polite, così dopo la scelta si sente anche per chi è. L'anello del fuoco gira intorno all'opzione, dentro il cuscino, solo con la tastiera. Sotto le label c'è un canvas più grande del cuscino, per la sua ombra sulla pagina.

Il cuscino in WebGL

Uno shader disegna un campo di altezze: una capsula (la distanza dal bordo, negativa dentro) con un profilo gonfio, ripido alla cucitura e tondo in alto, e un cordoncino di 2,4 pixel di raggio lungo il bordo. Dall'altezza meno la schiuma premuta si prende la pendenza con le differenze centrali, e da lì la normale. La luce viene dall'alto a sinistra e avvolge come su una stoffa; il velluto si scurisce visto di fronte e si accende dove la superficie gira via, più dalla parte della luce; il pelo schiacciato nel fondo della buca è più chiaro, e due rumori morbidi danno al pelo un verso diverso qua e là.

La schiuma che ricorda

La schiuma è una fila di 256 profondità lungo il cuscino, calcolata a ogni fotogramma: ogni punto si riempie moltiplicando per exp(−dt/memoria), e la pressione e la mano lo spingono di nuovo giù col massimo. La memoria va da MEMORY secondi (morbido) a circa un settimo di secondo (rigido), ma segue la fermezza con un ritardo di 0,9 secondi: il solco lasciato da una pressione morbida resta morbido. Prima di disegnarla la fila si sfuma su nove punti e va allo shader come una texture di 256 per 1 pixel, due byte per punto (LUMINANCE_ALPHA): la pendenza viene liscia anche nelle buche poco profonde.

Pressione e fermezza su molle

La pressione corre verso l'opzione scelta su una molla (65 per GLIDE al quadrato, smorzamento 0,72: va un poco oltre e torna), e mentre corre si alza fino al 28%. La sua profondità è una seconda molla che morbida è smorzata del tutto e rigida rimbalza (frequenza da 10 a 24, smorzamento da 1 a 0,32). Davanti a lei la stoffa si raccoglie in un rilievo che cresce con la velocità (PLOW). Anche la fermezza del cuscino è una molla: da lei dipendono profondità, larghezza e durezza dei bordi della buca, quanto è gonfio il cuscino e la memoria. Il conto si fa sul ticker di GSAP a passi di 1/240 di secondo, col fotogramma limitato a 1/30.

L'ombra nella buca

Le pendenze vere di una buca di pochi pixel si vedono appena: nello shader la buca conta 1,7 volte e le normali 1,35. Poi da ogni punto si cammina verso la luce in sette passi di 2,2 pixel sopra il campo delle altezze: se il bordo della buca sta sopra il raggio, il punto è in ombra, sfumata con la distanza. Così il bordo dalla parte della luce getta un'ombra morbida dentro la buca.

I nomi e il riposo

Ogni nome si abbassa con la schiuma sotto di lui (2,4 pixel nella buca più profonda) e si accende (opacità e peso da 470 a 640) quanto più la pressione gli è vicina e affondata, così si accende all'arrivo; col mouse vicino si schiarisce un poco. La fermezza muove l'asse SOFT di Fraunces da 100 a 0. Quando tutto è fermo e il solco è pieno, il ciclo esce dal ticker e non disegna più. Senza WebGL il cuscino è una pillola di velluto in CSS con una buca che scivola; se il browser toglie il contesto WebGL, al ritorno si ricostruisce. L'anteprima della libreria clicca l'opzione dopo quella scelta, che ha data-autoclic.

Valori da cambiare

NomeFileDi partenzaCosa cambia
STARTscript.js1L'opzione scelta all'apertura della pagina (0 è la prima).
FIRMscript.js[0, 0.38, 0.7, 1]Quanto è rigida ogni opzione, da 0 (la schiuma più morbida) a 1 (la più dura).
DEPTHscript.js9Quanto affonda la pressione dell'opzione più morbida, in pixel (la più rigida la metà).
MEMORYscript.js1.6I secondi che la schiuma più morbida ci mette a riempirsi dove è passata la pressione (le più rigide fanno prima).
GLIDEscript.js1Quanto in fretta la pressione scivola all'opzione nuova (di più, più svelta).
PLOWscript.js0.6Quanto si raccoglie la stoffa davanti alla pressione che scivola.
TOUCHscript.js0.3Quanto affonda il mouse, o un dito, rispetto alla pressione dell'opzione scelta.
SHEENscript.js0.85Quanto si accende il velluto dove la superficie gira via dalla luce.
SOFTENscript.jstrueLe lettere si ammorbidiscono con la schiuma, sull'asse SOFT del carattere.
data-sayindex.htmlFor side sleepers, For most sleepers…La frase per chi è ogni opzione, che compare in alto a destra quando la si sceglie.

Provali nel Playground

Quando usarla

Per una scelta che parla di morbidezza o di comodità: la fermezza di un materasso, di un cuscino o di un topper, l'imbottitura di un divano, l'ammortizzazione di una scarpa da corsa. La buca dice subito che cosa è scelto, e il cuscino che cambia dice che cosa cambia scegliendo. Sta bene in una pagina prodotto calma, con tre, quattro o cinque opzioni dai nomi brevi.

Sul telefono

Il cuscino resta alto 56 pixel e si stringe allo schermo: a 390 pixel è largo 358, le opzioni 89 e i nomi scendono a 15 pixel; il canvas col cuscino e la sua ombra non esce mai dallo schermo. Il dito che tocca il cuscino ci affonda dove tocca, come il mouse premuto, e al tocco la pressione scivola all'opzione nuova; niente scia del mouse, che col dito non c'è.

Con il movimento ridotto

Niente pressione che scivola e niente solco: la buca vecchia si riempie in un decimo di secondo mentre la nuova affonda nel suo posto in 0,3 secondi, così l'ombra passa da un'opzione all'altra in dissolvenza; il nome nuovo si accende con lei. La fermezza cambia subito, i nomi non si abbassano, il mouse non affonda e la riga in alto cambia in dissolvenza. All'apertura il cuscino compare in dissolvenza già premuto.

Trappole

  • La prima buca non si vedeva: sei pixel di profondità su un cuscino alto dodici cambiano la pendenza di pochissimo. Nello shader la buca ora conta 1,7 volte, le normali 1,35, e il bordo dalla parte della luce getta un'ombra vera dentro la buca, cercata camminando sopra le altezze.
  • Le pieghe a raggiera intorno alla pressione, calcolate con l'angolo, sembravano graffi scuri sopra e sotto il nome: tolte. La buca a forma di pillola, coi bordi più netti in orizzontale, si legge meglio da sola.
  • Andando verso un'opzione rigida il solco spariva subito, perché tutta la schiuma prendeva di colpo la memoria corta. Dare a ogni punto la memoria del momento in cui era stato premuto faceva un gradino verticale dove il rimbalzo dell'arrivo ripremeva una striscia: ora la memoria di tutta la schiuma segue la fermezza con 0,9 secondi di ritardo.
  • Dove la pressione incontrava il suo solco il massimo fra le due faceva uno spigolo, e nella luce una riga verticale netta: la fila delle profondità si sfuma su nove punti prima di andare allo shader.
  • Con la forma a fondo piatto anche per l'opzione morbida, la buca profonda aveva un bordo quasi verticale: ora la durezza del bordo va con la fermezza, morbida per Soft, netta per Extra firm.
  • Il nome si accendeva al clic, mentre la pressione era ancora dall'altra parte del cuscino: ora si accende quanto più la pressione gli è vicina e affondata.
  • Il mouse affondava quasi come la scelta e sembrava una seconda opzione scelta: affonda per tre decimi ed è più stretto, come un polpastrello.
  • Il ciclo si fermava quando la scia cambiava meno di un millesimo e mezzo di pixel per passo, cioè con ancora un terzo di pixel di solco che restava per sempre: ora si ferma solo quando il solco è sotto 0,04 pixel, e allora la schiuma prende esattamente la forma della pressione.

Librerie

GSAP 3.15.0, Fraunces (font variabile, con l'asse SOFT) 5.3.0.

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