Vai al contenuto
animorio
EN
Tutti i componenti

Il tris a tratto

Giochi, SVG, FisicaGSAPImpegnativaPeso compresso: Demo 11 KBGSAP 28 KBGratisScarica lo zip

Nello stile minimal: il tris contro il barista, per far passare il tempo ai clienti di un caffè mentre aspettano. La griglia è fatta di quattro filetti sottili che si disegnano all’entrata e sono corde: quando una X o una O ci cade accanto cedono di un pixel o due e si assestano. Le X e le O si scrivono a tratto, con la penna che va un filo oltre e torna; il barista ci pensa, guarda una casella che non prende e poi scrive. La riga della vittoria si disegna in vermiglio sopra le tre caselle e pizzica le corde che attraversa, le altre sbiadiscono; Play again riavvolge la partita dall’ultima mossa.

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>Noughts and crosses in pen</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/archivo@5.3.0/wdth.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- a game of noughts and crosses against the barista, for a café's customers while the coffee brews. The four
         grid lines are thin strings drawn by the script: they draw themselves on arrival and give a little when a
         mark lands next to them. X and O are written stroke by stroke, the barista thinks for a moment before its
         move, the winning row is drawn in vermilion over its three squares and the rest fade. Play again rewinds
         the game, the last move first. The nine squares are real buttons: arrows move between them, Enter plays -->
    <section class="game" aria-labelledby="ttt-title" data-game data-autoclic>
      <h2 class="game__title" id="ttt-title" data-title>Beat the barista</h2>

      <div class="board" data-board>
        <svg class="board__ink" viewBox="0 0 300 300" aria-hidden="true" data-ink>
          <g class="board__grid" data-grid></g>
          <g class="board__marks" data-marks></g>
          <path class="board__ghost" data-ghost-x />
          <path class="board__ghost" data-ghost-o />
          <path class="board__win" data-win />
        </svg>
        <div class="cells" role="group" aria-label="Board, three squares by three" data-cells>
          <button class="cell" type="button" tabindex="-1" data-cell aria-label="Top left, empty"></button>
          <button class="cell" type="button" tabindex="-1" data-cell aria-label="Top middle, empty"></button>
          <button class="cell" type="button" tabindex="-1" data-cell aria-label="Top right, empty"></button>
          <button class="cell" type="button" tabindex="-1" data-cell aria-label="Middle left, empty"></button>
          <button class="cell" type="button" tabindex="0" data-cell aria-label="Centre, empty"></button>
          <button class="cell" type="button" tabindex="-1" data-cell aria-label="Middle right, empty"></button>
          <button class="cell" type="button" tabindex="-1" data-cell aria-label="Bottom left, empty"></button>
          <button class="cell" type="button" tabindex="-1" data-cell aria-label="Bottom middle, empty"></button>
          <button class="cell" type="button" tabindex="-1" data-cell aria-label="Bottom right, empty"></button>
        </div>
      </div>

      <p class="status" aria-live="polite" data-status>Pick a square. You’re X.</p>

      <div class="foot">
        <p class="score" data-score>You <b data-n="X">0</b><span class="score__sep">·</span>Barista <b data-n="O">0</b><span class="score__sep">·</span>Draws <b data-n="D">0</b></p>
        <button class="again" type="button" data-again><span class="again__bg" aria-hidden="true"></span><span class="again__label">Play again</span></button>
      </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.

25 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 tris a tratto» da Animorio e adattala al mio sito

Cosa fa

Su un fondo bianco, in alto il titolo Beat the barista in un grottesco variabile, che all’entrata si apre dalla forma stretta e leggera a quella piena. Sotto, quattro filetti neri sottili si disegnano uno dopo l’altro, ognuno da un lato diverso, vanno un filo oltre la fine, tornano e vibrano appena: è la griglia del tris. Più sotto una riga dice cosa succede (Pick a square. You’re X.) e il punteggio, You 0 · Barista 0 · Draws 0. Col mouse su una casella libera compare una X pallida, la mossa che si sta per fare; col dito compare premendo, con la tastiera sulla casella scelta dalle frecce, chiusa da una cornice sottile. Con un clic, un tocco o Invio la X si scrive davvero, prima un tratto e poi l’altro, ognuno che va un poco oltre e torna, e i filetti attorno alla casella cedono verso fuori e si assestano. La riga dice The barista is thinking: dopo una pausa breve una O pallida comincia in una casella e torna nella penna, poi il barista scrive la sua O in un’altra, girando in senso antiorario, e la riga dice dove l’ha messa. Se la mossa è obbligata (vincere o fermare una fila di due) il barista non si guarda intorno e fa prima. Quando qualcuno fa tris una riga vermiglia si disegna sopra le tre caselle, partendo dall’ultima mossa se sta in fondo alla fila, e pizzica i filetti che attraversa; le altre mosse sbiadiscono, il numero del punteggio prende peso e si posa, e compare Play again, una pillola sottile che si gonfia sotto il mouse mentre la scritta si allarga. In pareggio tutte le mosse diventano grigie e i quattro filetti suonano uno dopo l’altro. Play again riavvolge la partita: la riga vermiglia torna nella penna, poi le mosse si cancellano dall’ultima alla prima, ogni tratto all’indietro, sempre più svelte, e a ogni casella che si svuota i filetti sentono un piccolo colpo.

Come funziona

Le corde della griglia

I quattro filetti sono path SVG in un viewBox di 300 per 300 (una casella è 100), con vector-effect non-scaling-stroke perché restino di un pixel e mezzo a ogni misura. Ognuno ha quanto è disegnato (t) e una molla smorzata (STRING: rigidità e smorzamento) che lo piega nel punto in cui è stato pizzicato: a ogni fotogramma diventa una curva quadratica col punto di controllo lì, a una distanza doppia della piega.

Un solo ciclo

Le molle si integrano sul ticker di GSAP in quattro sotto-passi, col passo limitato a 1/30 di secondo; i tween muovono solo numeri (quanto è scritto un tratto, l’opacità) e segnano il fotogramma come sporco. Quando le corde sono ferme e nessun tween ha mosso niente, il ciclo si toglie dal ticker.

La penna

Una X sono due tratti, un numero da 0 a 1 ciascuno, il secondo che parte prima che il primo si sia posato; una O è un arco ricostruito a ogni fotogramma come una spezzata, 364 gradi in senso antiorario. Ogni numero va fino a 1 + OVERSHOOT e torna a 1 con un sine.out: la penna passa un filo oltre la fine e si ferma. Quando la mossa è scritta, le corde attorno alla casella ricevono una spinta verso fuori (PLUCK), piena per quelle accanto e più piccola per le altre.

Il barista

Gioca col minimax completo (vincere presto vale di più), con una probabilità SLIP di scegliere una mossa peggiore, altrimenti nessuno vincerebbe mai. Aspetta un tempo a caso in THINK e intanto disegna e ritira mezza O pallida in una casella che non prenderà; se la mossa è obbligata non si guarda intorno e fa prima. Tutto il turno è una timeline di GSAP, quindi si ferma col banco come il resto.

La vittoria e il riavvolgimento

La riga vermiglia va dal centro di una casella in fondo alla fila a quello dell’altra, allungata di 38 unità per parte; prima di disegnarla si calcola dove attraversa ogni corda, e mentre il tratto avanza ogni corda viene pizzicata quando la penna ci passa. Play again rimette piene le mosse sbiadite, ritira la riga e cancella le mosse in ordine inverso, ogni tratto all’indietro, con un intervallo che si accorcia del 14% a ogni mossa.

Tastiera, schermo e anteprima

Le nove caselle sono button veri in un group, con un solo tabindex 0 che si sposta con le frecce, Home e End; ogni casella dice il suo nome e cosa c’è (Top left, X) e aria-disabled quando non si può giocare, la riga di stato è aria-live. Un clic da script sul componente (l’anteprima della libreria, detail 0) fa una partita intera già scritta, con una forchetta, la vittoria, la pausa e il riavvolgimento; una mano vera la interrompe e la partita continua da lì.

Valori da cambiare

NomeFileDi partenzaCosa cambia
SLIPscript.js0.2Quanto spesso il barista sbaglia la mossa migliore: 0 non perde mai, 1 gioca a caso.
THINKscript.js[0.55, 0.95]La pausa del barista prima di una mossa, a caso fra questi due valori, in secondi.
DRAWscript.js0.3I secondi che ci vuole a scrivere un tratto (una O ne prende una volta e mezza).
OVERSHOOTscript.js0.04Quanto la penna va oltre la fine del tratto prima di tornare (0,04 = il 4%).
PLUCKscript.js1.8Quanto cedono i filetti della griglia, in pixel, quando una mossa cade accanto a loro.
STRINGscript.js[1700, 0.11]La molla dei filetti: la rigidità (più alta vibra più in fretta) e lo smorzamento (più basso vibra più a lungo).
FADEscript.js0.16L’opacità delle mosse fuori dalla fila vincente.

Provali nel Playground

Quando usarla

Per il sito o il menu digitale di un caffè, di un bar o di una pasticceria, la pagina dell’attesa di un ordine o di un tavolo, la schermata di un locale, una pagina 404 o di manutenzione: qualunque posto dove qualcuno aspetta qualche minuto e un gioco piccolo e curato fa compagnia.

Sul telefono

La griglia è larga al massimo 300 pixel e sta nello schermo con 32 pixel per lato; le caselle sono grandi quasi un terzo della griglia, comode sotto il dito. Premendo una casella libera compare la X pallida, come l’hover col mouse, e si scrive lasciandola. Sotto i 360 pixel la riga di stato e il punteggio si stringono con l’asse wdth del carattere per restare su una riga.

Con il movimento ridotto

Niente tratti che corrono né corde che vibrano: la griglia e il titolo compaiono con una dissolvenza, le X e le O si accendono già intere, la riga vermiglia compare sopra le tre caselle e le altre sbiadiscono, e Play again spegne tutto insieme. Il gioco, il barista e la tastiera restano uguali.

Trappole

  • Un barista col minimax perfetto non perde mai e dopo tre partite annoia: serve una probabilità di sbagliare, ma non quando la mossa è obbligata a vista, o sembra distratto invece che umano. Per questo la pausa e lo sguardo dipendono da quanto è urgente la mossa.
  • Con il viewBox scalato i filetti diventano più sottili sul telefono: vector-effect non-scaling-stroke li tiene della stessa misura in pixel, e così niente va ricalcolato al resize.
  • L’anteprima della libreria clicca da script ogni tre secondi circa: un passo per clic lasciava il video a metà. Il primo clic fa la partita intera in una sola regia di GSAP e i clic che arrivano durante il giro vengono ignorati.
  • Il mouse fermo su una casella mentre il barista pensa non riceve un nuovo pointerenter: la X pallida va rimessa da sola quando le caselle tornano libere (alla fine dell’entrata, dopo la mossa del barista, dopo il riavvolgimento).
  • Una O chiusa con il raggio che rientra lasciava un dentino nel punto dove si chiude: il raggio resta lo stesso e l’arco passa sopra il suo inizio, così la chiusura sparisce.
  • Un secondo Play again durante il riavvolgimento avrebbe cancellato le mosse due volte: un flag tiene un solo riavvolgimento alla volta.

Librerie

GSAP 3.15.0, Archivo (font variabile) 5.3.0.

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

Collaudo

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