Vai al contenuto
animorio
EN
Tutti i componenti

Il modulo che va in forno

Moduli, Transizioni, SVG, TestoGSAP, Solo CSSImpegnativaPeso compresso: Demo 17 KBGSAP 28 KBGratisScarica lo zip

Il modulo d’iscrizione al corso di tornio di una bottega di ceramica, fatto d’argilla: un campo giusto prende una mano di smalto crudo data col pennello, uno sbagliato diventa rosso ferro e traballa come un vaso fuori centro. Inviato, va in forno: in poco più di due secondi si accende da solo di rosso scuro, ciliegia, arancio e giallo, coi colori veri di un corpo così caldo calcolati con la legge di Planck, si ritira del dodici per cento come l’argilla ed esce una piastrella smaltata nello smalto scelto, con la prenotazione impressa.

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 form that goes in the kiln</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/soft.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/bricolage-grotesque@5.3.0/wdth.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the booking form of a pottery's wheel class, made of clay: a field that is right gets a coat of raw glaze
         brushed over it, one that is wrong turns iron red; sent, the slab goes in the kiln, glows from dull red to
         yellow white, shrinks like clay and comes out a glazed tile in the glaze chosen. The booking is pretended:
         see book() in the script -->
    <form class="kiln" action="#" novalidate aria-labelledby="kiln-title" data-kiln data-autoclic>
      <div class="slab" data-slab>
        <div class="face" data-face>
          <div class="head">
            <h2 class="head__title" id="kiln-title">Thursday wheel class</h2>
            <p class="head__sub">Six evenings on the wheel, 7 to 9 pm. Clay, tools and two firings included.</p>
          </div>

          <div class="field" data-field="name">
            <label class="field__label" for="kiln-name">Your name</label>
            <div class="well" data-well>
              <svg class="coat" aria-hidden="true" data-coat></svg>
              <input class="well__input" id="kiln-name" name="name" type="text" autocomplete="name" autocapitalize="words" spellcheck="false" enterkeyhint="next" aria-describedby="kiln-name-msg" aria-invalid="false" data-input>
              <span class="well__caret" aria-hidden="true" data-caret></span>
              <svg class="tick" viewBox="0 0 20 20" aria-hidden="true" data-tick><path d="M4.8 10.6l3.4 3.4 7-7.6"/></svg>
            </div>
            <div class="field__msg" id="kiln-name-msg" data-msg></div>
          </div>

          <div class="field" data-field="email">
            <label class="field__label" for="kiln-email">Email</label>
            <div class="well" data-well>
              <svg class="coat" aria-hidden="true" data-coat></svg>
              <input class="well__input" id="kiln-email" name="email" type="text" inputmode="email" autocomplete="email" autocapitalize="off" autocorrect="off" spellcheck="false" enterkeyhint="send" placeholder="you@example.com" aria-describedby="kiln-email-msg" aria-invalid="false" data-input>
              <span class="well__caret" aria-hidden="true" data-caret></span>
              <svg class="tick" viewBox="0 0 20 20" aria-hidden="true" data-tick><path d="M4.8 10.6l3.4 3.4 7-7.6"/></svg>
            </div>
            <div class="field__msg" id="kiln-email-msg" data-msg></div>
          </div>

          <fieldset class="field field--picks" role="radiogroup" aria-labelledby="kiln-date-legend" aria-describedby="kiln-date-msg" aria-required="true" aria-invalid="false" data-field="date">
            <legend class="field__label" id="kiln-date-legend">First Thursday</legend>
            <div class="picks">
              <label class="pick">
                <input type="radio" name="date" value="Thursday 15 October" data-input>
                <span class="pick__body"><svg class="coat" aria-hidden="true" data-coat></svg><span class="pick__main">15 Oct</span><span class="pick__sub">4 seats left</span><svg class="tick tick--pick" viewBox="0 0 20 20" aria-hidden="true" data-tick><path d="M4.8 10.6l3.4 3.4 7-7.6"/></svg></span>
              </label>
              <label class="pick">
                <input type="radio" name="date" value="Thursday 5 November" disabled data-input>
                <span class="pick__body"><span class="pick__main">5 Nov</span><span class="pick__sub">Full</span></span>
              </label>
              <label class="pick">
                <input type="radio" name="date" value="Thursday 26 November" data-input>
                <span class="pick__body"><svg class="coat" aria-hidden="true" data-coat></svg><span class="pick__main">26 Nov</span><span class="pick__sub">9 seats left</span><svg class="tick tick--pick" viewBox="0 0 20 20" aria-hidden="true" data-tick><path d="M4.8 10.6l3.4 3.4 7-7.6"/></svg></span>
              </label>
            </div>
            <div class="field__msg" id="kiln-date-msg" data-msg></div>
          </fieldset>

          <fieldset class="field field--picks" role="radiogroup" aria-labelledby="kiln-glaze-legend" aria-describedby="kiln-glaze-msg" aria-required="true" aria-invalid="false" data-field="glaze">
            <legend class="field__label" id="kiln-glaze-legend">Glaze for your first bowl</legend>
            <div class="picks">
              <label class="pick">
                <input type="radio" name="glaze" value="celadon" data-input>
                <span class="pick__body"><svg class="coat" aria-hidden="true" data-coat></svg><svg class="bowl" viewBox="0 0 40 20" aria-hidden="true"><path class="bowl__glaze bowl--celadon" d="M2 3.5h36c0 8.6-7.4 14-18 14S2 12.1 2 3.5z"/><path class="bowl__shine" d="M7.5 7.2c2.2 3.6 6 5.4 10.4 5.8"/></svg><span class="pick__main">Celadon</span><svg class="tick tick--pick" viewBox="0 0 20 20" aria-hidden="true" data-tick><path d="M4.8 10.6l3.4 3.4 7-7.6"/></svg></span>
              </label>
              <label class="pick">
                <input type="radio" name="glaze" value="tenmoku" data-input>
                <span class="pick__body"><svg class="coat" aria-hidden="true" data-coat></svg><svg class="bowl" viewBox="0 0 40 20" aria-hidden="true"><path class="bowl__glaze bowl--tenmoku" d="M2 3.5h36c0 8.6-7.4 14-18 14S2 12.1 2 3.5z"/><path class="bowl__shine" d="M7.5 7.2c2.2 3.6 6 5.4 10.4 5.8"/></svg><span class="pick__main">Tenmoku</span><svg class="tick tick--pick" viewBox="0 0 20 20" aria-hidden="true" data-tick><path d="M4.8 10.6l3.4 3.4 7-7.6"/></svg></span>
              </label>
              <label class="pick">
                <input type="radio" name="glaze" value="shino" data-input>
                <span class="pick__body"><svg class="coat" aria-hidden="true" data-coat></svg><svg class="bowl" viewBox="0 0 40 20" aria-hidden="true"><path class="bowl__glaze bowl--shino" d="M2 3.5h36c0 8.6-7.4 14-18 14S2 12.1 2 3.5z"/><path class="bowl__shine" d="M7.5 7.2c2.2 3.6 6 5.4 10.4 5.8"/></svg><span class="pick__main">Shino</span><svg class="tick tick--pick" viewBox="0 0 20 20" aria-hidden="true" data-tick><path d="M4.8 10.6l3.4 3.4 7-7.6"/></svg></span>
              </label>
            </div>
            <div class="field__msg" id="kiln-glaze-msg" data-msg></div>
          </fieldset>

          <button class="fire" type="submit" data-fire>
            <span class="fire__bg" aria-hidden="true"></span>
            <span class="fire__label" data-fire-label>Book my seat · €240</span>
            <span class="fire__heat" aria-hidden="true" data-heat></span>
          </button>
        </div>

        <!-- what comes out of the kiln -->
        <section class="tile" aria-labelledby="kiln-tile-title" hidden data-tile>
          <span class="tile__shine" aria-hidden="true" data-shine></span>
          <div class="tile__top">
            <p class="tile__kicker"><svg viewBox="0 0 20 20" aria-hidden="true"><path d="M4.8 10.6l3.4 3.4 7-7.6"/></svg>Seat booked</p>
            <h2 class="tile__title" id="kiln-tile-title" tabindex="-1" data-tile-title>See you at the wheel.</h2>
          </div>
          <dl class="tile__facts">
            <div><dt>First class</dt><dd data-out="date"></dd></div>
            <div><dt>Your bowl’s glaze</dt><dd data-out="glaze"></dd></div>
            <div><dt>Details sent to</dt><dd data-out="email"></dd></div>
          </dl>
          <p class="tile__note">Bring an apron and short nails. Your bowl comes out of its last firing three weeks later.</p>
          <button class="again" type="button" data-again><span class="again__bg" aria-hidden="true"></span><span class="again__label">Book another seat</span></button>
        </section>

        <span class="slab__dark" aria-hidden="true" data-dark></span>
        <span class="slab__glow" aria-hidden="true" data-glow></span>
        <span class="slab__veil" aria-hidden="true" data-veil></span>
        <span class="slab__flame" aria-hidden="true" data-flame></span>
      </div>
      <p class="sr" role="status" aria-live="polite" data-live></p>
    </form>
  </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.

49 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 modulo che va in forno» da Animorio e adattala al mio sito

Cosa fa

Su un fondo nero una lastra di gres color biscotto dagli angoli tondi: il titolo Thursday wheel class, la riga Six evenings on the wheel, 7 to 9 pm, due pozzetti premuti nell’argilla per il nome e l’email, tre tessere per il primo giovedì (15 Oct con 4 seats left, 5 Nov barrato e Full, 26 Nov con 9 seats left), tre tessere con una ciotolina dipinta per lo smalto della prima ciotola (Celadon, Tenmoku, Shino) e il pulsante blu cobalto Book my seat · €240. Toccato, un pozzetto si schiarisce con un bordo cobalto. Scrivendo, un attimo dopo l’ultimo tasto il campo si rilegge: se è giusto ci passa sopra un pennello, le setole arrivano in fondo una dopo l’altra lasciando una mano di smalto crudo color gesso con le sue righe, e in fondo si disegna una spunta cobalto. Se lasciandolo è sbagliato, il pozzetto diventa rosso ferro, traballa come un vaso fuori centro sul tornio e sotto scende una riga con un triangolo che dice cosa manca (Add the ending, like .com); appena il campo torna giusto l’errore se ne va e arriva lo smalto. Scegliendo una tessera, lei si preme nella lastra, prende il bordo cobalto, lo smalto e la spunta, e la vicina lascia andare il suo. Premendo Book my seat con qualcosa che manca, ogni campo sbagliato traballa col suo messaggio e il fuoco va sul primo. Se è tutto giusto la scritta del pulsante diventa Firing coi gradi che salgono, la luce intorno alla lastra si spegne come in un forno chiuso e l’argilla comincia a brillare da sola: rosso scuro verso i 600 gradi, ciliegia, arancio e in cima, a 1.240 gradi, un giallo chiaro con chiazze più luminose che respirano, mentre intorno si allarga un alone; i bordi, più sottili, si accendono prima del centro. Salendo la lastra si ritira tutta insieme del dodici per cento; in cima, per un decimo di secondo, il modulo sparisce nella luce e, raffreddandosi da giallo ad arancio, rosso e buio, il bordo per primo, diventa una piastrella lucida nello smalto scelto (verde celadon, bruno tenmoku o pesca shino) con un riflesso che la attraversa una volta (dal clic alla piastrella che si legge passano poco più di due secondi): Seat booked, See you at the wheel, Mara., il primo giovedì, lo smalto, l’email, cosa portare e il pulsante Book another seat, che riporta un modulo nuovo.

Come funziona

Un modulo vero sotto l’argilla

Due input veri con le loro label (autocomplete name ed email, inputmode email, testo a 16 pixel perché Safari sul telefono non ingrandisca) e due gruppi di radio veri in un fieldset con role radiogroup: le tessere sono i radio stessi, invisibili sopra il loro disegno, così frecce, spazio, tocco e lettori di schermo funzionano da soli e la tessera Full è disabilitata davvero. Ogni campo ha aria-invalid e aria-describedby verso la sua riga di sotto; all’invio il fuoco va al primo campo sbagliato e una regione aria-live dice cosa controllare, poi legge la prenotazione.

La convalida mentre si scrive

Ogni campo ha tre stati: a riposo, giusto, sbagliato. Scrivendo, SETTLE secondi dopo l’ultimo tasto (un delayedCall di GSAP che riparte a ogni tasto) un campo diventato giusto prende lo smalto; uno non ancora giusto viene lasciato in pace finché non lo si lascia, e solo allora diventa rosso. Un campo rosso si rilegge a ogni tasto: torna giusto appena lo è, mentre le parole del suo errore cambiano solo dopo una pausa, così non lampeggiano fra un tasto e l’altro. La riga sotto entra con l’altezza animata fino ad auto.

Lo smalto dato col pennello

Lo smalto è un SVG grande quanto il pozzetto, rifatto quando cambia misura: una striscia ogni cinque o sei pixel, con le punte tonde come setole. A ogni fotogramma ogni striscia arriva a p·(larghezza + 40) meno il suo ritardo, preso da due seni sfasati: il bordo dello smalto bagnato è sfrangiato mentre corre e dritto quando è arrivato. Ogni striscia ha un’opacità sua, che lascia le righe del pennello. La spunta si disegna con stroke-dashoffset quando il pennello è a metà.

Il colore dell’argilla rovente

All’avvio si calcola una tabella ogni 10 gradi: la legge di Planck da 380 a 780 nanometri, pesata con le curve CIE 1931 (l’approssimazione analitica di Wyman, Sloan e Shirley), portata in sRGB lineare e normalizzata. Poi la si guarda come da uno spioncino: un’esposizione che cresce con la luminanza, e ogni canale che si satura per conto suo (1 − e^(−c·E)), più un poco di abbagliamento al massimo; così sotto i 525 gradi non si vede niente, a 700 è ciliegia e in cima il rosso saturo lascia salire il verde fino a un giallo chiaro. Il bagliore è uno strato in mix-blend-mode screen sopra la lastra già scurita, cioè luce che si somma, con un gradiente radiale fra il bordo e un centro che ha una temperatura sua e la insegue in ritardo. Vicino alla cima uno strato di chiazze chiare in screen si sposta piano e respira con due seni, perché la luce del forno non è mai una tinta piatta.

Il forno, in una timeline

Una timeline di GSAP sola, in poco più di due secondi: l’ambiente si spegne, la temperatura sale in HEAT secondi (il tratto buio in fretta, poi rosso, arancio e giallo un poco più svelti verso la cima) e intanto la lastra si ritira di SHRINK con un scale su tutta lei, come l’argilla: la piastrella è impaginata larga e alta come il modulo, quindi niente si riordina. Per questo in cima basta un velo del colore dell’argilla accesa per un decimo di secondo, sotto cui il modulo diventa la piastrella; dopo SOAK secondi la temperatura scende in COOL secondi, svelta all’inizio come qualsiasi cosa calda, e la porta si riapre all’ultimo rosso: la piastrella si legge. Il riflesso e gli ultimi gradi vengono dopo. In movimento ridotto la lastra non cambia misura e restano solo i colori che si dissolvono. Un clic da script (detail 0, l’anteprima) fa una mossa alla volta senza prendere il fuoco, con un cursore disegnato: il primo riempie il modulo giusto (la locandina), il secondo lo manda in forno; nei giri dopo un nome nuovo, l’email sbagliata, la correzione e le scelte, con un altro smalto.

Valori da cambiare

NomeFileDi partenzaCosa cambia
PEAKscript.js1240La temperatura in cima alla cottura, in gradi: 1240 è il gres; una cottura più bassa resta più rossa.
HEATscript.js1.1Quanti secondi impiega il forno a salire fino in cima.
SOAKscript.js0.2Quanti secondi il forno resta in cima: il modulo diventa la piastrella nel primo decimo.
COOLscript.js1.4Quanti secondi impiega a raffreddarsi: la piastrella si legge già dopo un terzo.
SHRINKscript.js0.12Quanto si ritira la lastra in forno, come l’argilla: 0.12 è il dodici per cento.
BRUSHscript.js0.6Quanti secondi impiega il pennello a dare lo smalto su un campo giusto.
SETTLEscript.js0.6I secondi di silenzio dopo l’ultimo tasto prima che il campo si rilegga.

Provali nel Playground

Quando usarla

Nella prenotazione di un corso, di un laboratorio o di una visita, dove il modulo è corto e la conferma deve restare in mente: la trasformazione all’invio è il momento in cui chi si iscrive capisce che è fatta. La convalida va bene per qualsiasi modulo: aspetta che si smetta di scrivere, non grida mentre si scrive e se ne va appena il campo è giusto. Il forno e lo smalto sono il tema di una bottega di ceramica; per un altro prodotto si tengono il pennello e la trasformazione sotto il velo e si cambiano i colori.

Sul telefono

La lastra prende la larghezza dello schermo (358 pixel su un telefono di 390) ed è alta come lo schermo o poco meno; i campi sono alti 48, le tessere 56 e 64, il pulsante 52, tutti oltre i 44 di un dito. Il testo dei campi è a 16 pixel, così Safari non ingrandisce la pagina al tocco; l’email apre la tastiera con la @; il tasto Invio dice Next nel nome e porta all’email, e Send nell’email. Le tessere si scelgono col tocco e l’hover vale solo dove c’è un puntatore. La piastrella nasce larga 315 e le sue righe vanno a capo da sole.

Con il movimento ridotto

Il pennello non corre: lo smalto e la spunta compaiono in dissolvenza. I campi sbagliati non traballano, le righe di sotto si scambiano in dissolvenza e le scritte del pulsante si incrociano senza muoversi. In forno restano solo i colori, con gli stessi tempi: il buio, il bagliore e il velo si dissolvono uno nell’altro, la lastra non si ritira, le chiazze di luce stanno ferme e il riflesso sulla piastrella non corre. Book another seat dissolve la piastrella nel modulo nuovo.

Trappole

  • La prima cottura durava più di cinque secondi, con il modulo sparito in un rettangolo crema piatto per più di mezzo secondo: per chi prenota era un’attesa e si leggeva come un lampo. Ora dal clic alla piastrella leggibile passano poco più di due secondi, i colori restano tutti, e il velo copre per un decimo di secondo con la luce più forte ai bordi e chiazze che si muovono.
  • Per nascondere un velo così corto niente deve riordinarsi sotto di lui: la lastra si stringeva cambiando larghezza e altezza, e la piastrella, più stretta, andava a capo mentre lo faceva. Ora la piastrella è impaginata grande come il modulo e la lastra si ritira con uno scale, come fa l’argilla; le scritte della piastrella sono un poco più grandi per tornare alla misura giusta una volta ritirate.
  • Un velo di tinta piena sopra il bagliore in screen faceva un piccolo buio al centro proprio nel momento dello scambio: il bagliore schiarisce, il velo copre. Ora il velo ha il colore dell’argilla accesa, cioè il bagliore già sommato all’argilla nel buio del forno.
  • Il colore del corpo nero da solo è sbagliato per un forno: a 1.240 gradi la legge di Planck dà un arancio pieno, ma dallo spioncino si vede giallo bianco. Il giallo bianco è l’occhio, o la macchina fotografica, che si satura: ogni canale ora si espone per conto suo con 1 − e^(−c·E) e il rosso, saturo per primo, lascia salire il verde e un poco di blu.
  • Il velo che copre il modulo in cima prendeva il colore da una variabile CSS scritta sullo strato del bagliore, che è suo fratello e non suo padre: era trasparente e sotto si vedeva il modulo diventare piastrella. Le variabili ora stanno sulla lastra, che le passa a tutti e due.
  • Il centro della lastra seguiva il bordo con uno scarto fisso, meno 150 gradi salendo e più 90 scendendo: nel momento in cui il forno cambiava verso il centro saltava di 240 gradi, e si vedeva. Ora il centro ha una sua temperatura che insegue quella del bordo con un ritardo, salendo e scendendo.
  • L’alone era un box-shadow con la sfocatura che cresceva a ogni fotogramma: nelle foto prese durante il ritiro della lastra restava una riga dura dove la sfocatura non era stata ridisegnata. Ora la sfocatura è fissa e cambiano solo colore e trasparenza, che costano anche meno.
  • La riga d’errore di un campo che si sta correggendo cambiava a ogni tasto (.ne, poi .n, poi giusto) e lampeggiava: un campo rosso torna giusto subito, ma le parole del suo errore aspettano una pausa.
  • Lo sfondo del pulsante, in posizione assoluta, prendeva la grid-area del testo e partiva dopo il padding di sinistra: sporgeva di 20 pixel a destra. La regola della griglia ora vale per tutti i figli tranne lo sfondo.
  • L’ombra interna di una tessera scelta, fatta con box-shadow inset, finiva sotto lo smalto, che è un figlio: il bordo cobalto e quello rosso ora stanno in un ::after sopra lo smalto, e così la profondità del pozzetto.
  • Le parole del pulsante che rotolavano verso Firing restavano una sopra l’altra per un attimo: ora la prima esce del tutto prima che entri la seconda.
  • Con Book another seat la piastrella spariva in un fotogramma e la lastra passava dal verde celadon all’argilla di colpo: ora la piastrella si dissolve nell’argilla e solo dopo la lastra si allarga per il modulo nuovo.

Librerie

GSAP 3.15.0, Fraunces (font variabile) 5.3.0, Bricolage Grotesque (font variabile) 5.3.0.

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

Collaudo

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