Vai al contenuto
animorio
EN
Tutti i componenti

La finestra disegnata a filo

Finestre, Transizioni, SVGGSAPImpegnativaPeso compresso: Demo 10 KBGSAP 28 KBGratisScarica lo zip

Una finestra di conferma nello stile minimal, disegnata da un filo solo: il contorno del pulsante Archive project è la fine di una linea sottile che, premuta, esce dal pulsante con la punta vermiglia, sale e gira tutto intorno alla finestra, mentre il pulsante si srotola per darle filo; quando il giro si chiude la finestra si assesta di un pixel e le parole si accendono una dopo l’altra. Cancel riavvolge il filo nel pulsante, Archive chiude la finestra in una riga che si stringe e torna il pulsante, ora Archived.

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 dialog drawn on a thread</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/mona-sans@5.3.0/wdth.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage" data-stage>
    <!-- the dialog drawn on a thread: the button's outline is the end of one thin thread. Pressed, the thread runs out
         of the button and draws the window round; Cancel winds it back into the button, Archive closes the window into
         a single line that tightens into the button, now done -->
    <span class="slot" data-slot data-autoclic>
      <button class="opener" type="button" aria-haspopup="dialog" aria-controls="archive-dialog" data-open>
        <span class="opener__fill" aria-hidden="true"></span>
        <span class="opener__face">
          <span class="opener__label opener__label--size" aria-hidden="true" data-size></span>
          <span class="opener__label" data-rest>Archive project</span>
          <span class="opener__label opener__label--done" aria-hidden="true" data-done>
            <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12.6l4.3 4.3L19 7.4" data-tick/></svg>
            <span>Archived</span>
          </span>
        </span>
      </button>
      <span class="slot__under">
        <button class="undo" type="button" hidden data-undo>Undo</button>
      </span>
    </span>
  </main>

  <div class="veil" data-veil></div>

  <div class="layer">
    <div class="box" id="archive-dialog" role="dialog" aria-modal="true" aria-labelledby="archive-title" aria-describedby="archive-text" data-box>
      <div class="box__paper" data-paper></div>
      <div class="box__body">
        <h2 class="box__title" id="archive-title" data-title>Archive this project?</h2>
        <p class="box__text" id="archive-text" data-part><strong>Brightwell rebrand</strong> leaves your workspace with its files and comments. You can restore it from Archive at any time.</p>
        <div class="box__rule" aria-hidden="true" data-rule></div>
        <div class="box__actions">
          <button class="act act--ghost" type="button" data-part data-cancel>Cancel</button>
          <button class="act act--ink" type="button" data-part data-confirm>Archive</button>
        </div>
      </div>
    </div>
  </div>

  <svg class="thread" aria-hidden="true" data-thread>
    <path class="thread__ink" d="" data-ink/>
    <path class="thread__tip" d="" data-tip/>
  </svg>

  <p class="sr" aria-live="polite" data-live></p>

  <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 «La finestra disegnata a filo» da Animorio e adattala al mio sito

Cosa fa

Su un fondo bianco c’è solo un pulsante a pillola, Archive project, con il contorno di un filo nero sottile. Arrivando, il filo disegna il pulsante girandogli intorno, guidato da una punta vermiglia. Col mouse sopra il fondo si gonfia, la scritta si allarga e dalla cima del pulsante spunta di qualche pixel la fine del filo, vermiglia. Premendo, quella fine corre in su e disegna tutto il contorno della finestra, mentre il contorno del pulsante si srotola dalla cima e la sua scritta si stringe e sparisce: le due estremità del filo si incontrano nello stesso istante, la finestra respira di un pixel e si posa, arriva la carta bianca con la sua ombra e dentro si accendono una dopo l’altra le lettere di Archive this project? (strette e leggere, poi larghe e piene), la frase su Brightwell rebrand, la riga sottile che si disegna da sinistra e i pulsanti Cancel e Archive. Cancel, Esc o un clic fuori riavvolgono il filo: il contorno del pulsante si ricompone mentre quello della finestra torna indietro nel pulsante. Archive chiude la finestra in una sola riga che passa per il centro del pulsante, la riga si stringe alla sua larghezza e si gonfia alla sua altezza, e il pulsante dice Archived con una spunta vermiglia che si disegna; sotto compare Undo, che lo riporta com’era.

Come funziona

Un filo, tre pezzi

Il filo è un solo path SVG in uno strato grande come lo schermo, rifatto a ogni fotogramma in pixel: il contorno del pulsante (una pillola percorsa in senso orario dalla cima), il tratto che sale dalla cima del pulsante a quella della finestra (dritto, o una S con le estremità verticali se non sono in colonna) e il contorno della finestra (un rettangolo arrotondato che parte e finisce nello stesso punto). Le lunghezze si calcolano esatte: lati più quarti di cerchio, 2πr per gli angoli.

Due estremità che corrono

La parte che si vede è un tratto solo di stroke-dasharray, spostato con stroke-dashoffset: la punta va dalla fine del pulsante alla fine della finestra (u), la coda dall’inizio del pulsante all’inizio della finestra (v), partendo un attimo dopo. Le due corse sono frazioni ricalcolate sulle lunghezze di quel fotogramma, così un ridimensionamento a metà disegno non sposta niente. La punta vermiglia è lo stesso path con un tratto di TIP pixel davanti alla punta.

La cucitura

Dove il giro si chiude due tratti col bordo dritto lasciano un capello di vuoto: il primo giro comincia un pixel e mezzo prima del suo punto, l’ultimo finisce un pixel e mezzo dopo, e i due si sovrappongono. Appena chiuso, il contorno si allarga di 1,4 pixel e torna con elastic.out: l’assestamento.

Le parole

Il titolo è diviso in lettere (le parole non si spezzano): ognuna arriva da wdth 72 e wght 300 a wdth 100 e wght 640, con back.out per un pixel di slancio, una ogni LETTERS secondi. Poi la frase, la riga sottile (scaleX da sinistra) e i due pulsanti, che salgono di 8 pixel con back.out. La scritta del pulsante usa una variabile --w dentro font-variation-settings e una copia invisibile della scritta, larga come sotto il mouse, tiene il pulsante sempre della stessa misura: il contorno non si sposta mai.

Chiudersi in una riga

Con Archive il contorno della finestra cambia forma invece di srotolarsi: il lato di sopra e quello di sotto si incontrano nella riga che passa per il centro del pulsante (power3.in), la riga si ferma un istante, si stringe alla larghezza del pulsante e si apre alla sua altezza con back.out(1.1), un pixel oltre. Quando coincide col pulsante, lo stesso disegno passa al primo pezzo del filo senza che si veda il cambio.

Dialog vero

La finestra ha role dialog e aria-modal, il pulsante aria-haspopup e aria-expanded. Aprendosi la pagina dietro diventa inert e la focalizzazione va su Cancel; il Tab gira fra Cancel e Archive, Esc e un clic fuori annullano. Appena si chiude la finestra smette di rispondere e la focalizzazione torna al pulsante (o va su Undo), anche se il filo si sta ancora muovendo. Una regione aria-live dice Archived e Back. Un clic da script (l’anteprima della libreria) fa un giro intero in una timeline GSAP: apre, annulla, riapre, archivia, Undo.

Valori da cambiare

NomeFileDi partenzaCosa cambia
DRAWscript.js1.05I secondi in cui il filo esce dal pulsante e disegna la finestra.
REWINDscript.js0.7I secondi in cui il filo si riavvolge nel pulsante con Cancel.
FOLDscript.js0.8I secondi in cui la finestra si chiude in una riga e diventa il pulsante fatto.
TIPscript.js30La lunghezza della punta colorata che guida il filo, in pixel.
PEEKscript.js8Quanto spunta la fine del filo dal pulsante col mouse sopra, in pixel.
DIMscript.js0.05Quanto si scurisce la pagina dietro la finestra, da 0 a 1.
LETTERSscript.js0.018I secondi fra una lettera del titolo e la successiva.
RADIUSscript.js20Il raggio degli angoli della finestra, in pixel.

Provali nel Playground

Quando usarla

Per le conferme di un’azione che si può ancora annullare: archiviare un progetto, spostare un ordine, lasciare uno spazio di lavoro, disdire una prenotazione. Sta bene nelle app e nei pannelli dove tutto è fatto di linee sottili, e il pulsante che si disegna da solo funziona anche da invito.

Sul telefono

La finestra prende tutta la larghezza meno 16 pixel per lato, il filo fa la stessa strada. Sotto il dito il fondo del pulsante si gonfia e la fine del filo spunta, come col mouse; un tocco fuori annulla.

Con il movimento ridotto

Il filo non corre: il contorno del pulsante e la sua scritta svaniscono, poi la finestra compare al loro posto già disegnata, con le parole ferme; chiudendo succede il contrario, e Archived con la sua spunta compare in dissolvenza. Niente si sposta e le due cose non si vedono mai insieme.

Trappole

  • Due tratti con l’estremità dritta che si toccano nello stesso punto lasciano un capello bianco nel contorno chiuso: il primo giro comincia un pixel e mezzo prima e l’ultimo finisce un pixel e mezzo dopo, così si sovrappongono.
  • La scritta del pulsante si stringe con l’asse wdth mentre il filo esce, e un pulsante largo quanto la sua scritta si restringeva: il contorno del filo si spostava e Archived usciva più stretto. Una copia invisibile della scritta, larga come sotto il mouse, tiene il pulsante sempre della stessa misura.
  • Chiudendo con Esc la finestra restava inert e la focalizzazione ferma su Archive per tutto il riavvolgimento: un Invio subito dopo archiviava. Ora la finestra si libera appena si chiude e la focalizzazione torna subito al pulsante.
  • Col movimento ridotto la finestra compariva mentre la scritta del pulsante svaniva e le due si vedevano una sopra l’altra: prima se ne va il pulsante, poi arriva la finestra.

Librerie

GSAP 3.15.0, Mona Sans (font variabile, assi wght e wdth) 5.3.0.

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