Vai al contenuto
animorio
EN
Tutti i componenti

La condivisione al tecnigrafo

Finestre, Transizioni, SVG, FisicaGSAP, Solo CSSImpegnativaPeso compresso: Demo 16 KBGSAP 28 KBGratisScarica lo zip

La finestra di condivisione dei disegni di uno studio di architettura, disegnata come si disegna una tavola: quattro linee di costruzione azzurre entrano dai bordi dello schermo come le righe di un tecnigrafo, oscillano su molle e si fermano dove andranno i lati, la penna ripassa il contorno e la carta si riempie con un tratteggio che si ispessisce finché le linee si toccano. Invitando qualcuno la riga di fondo si riallunga e scende alla misura nuova mentre la persona viene disegnata nell’elenco, in un quadrato col suo materiale tratteggiato; copiando il link, sotto compare la sua quota con scritto Copied.

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 drafted share dialog</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/jost@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the drafted share dialog: Share draws the dialog the way an architect draws a sheet. Blue construction lines
         slide in like the rules of a drafting machine and spring into place, the outline is inked along them, the
         paper fills in with a hatch, and the words come last. A new collaborator is drafted into the list the same
         way, and a copied link gets its dimension line. -->
    <span class="slot" data-slot data-autoclic>
      <button class="opener" type="button" aria-haspopup="dialog" data-open>
        <svg class="opener__icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="9.5" cy="8" r="3.6"/><path d="M3.2 19.5c.7-3.4 3.2-5.4 6.3-5.4 1.7 0 3.2.6 4.3 1.6M18.2 13.2v6.6M14.9 16.5h6.6"/></svg>
        <span>Share</span>
      </button>
      <span class="slot__ticks" aria-hidden="true"></span>
    </span>
  </main>

  <dialog class="share" aria-modal="true" aria-labelledby="share-title" aria-describedby="share-sub" data-dialog>
    <div class="share__veil" data-veil></div>
    <div class="frame" data-frame>
      <div class="frame__shade" data-shade></div>
      <div class="frame__paper" data-paper></div>
      <div class="frame__body" tabindex="-1" data-body>
        <header class="head" data-part>
          <div class="head__text">
            <h2 class="head__title" id="share-title">Share “Casa Albera”</h2>
            <p class="head__sub" id="share-sub">Schematic design, 14 drawings</p>
          </div>
          <button class="close" type="button" aria-label="Close" data-close>
            <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6.5 6.5l11 11M17.5 6.5l-11 11"/></svg>
          </button>
        </header>

        <form class="invite" novalidate data-invite data-part>
          <label class="label" for="invite-email">Invite people</label>
          <div class="invite__row">
            <input class="field invite__email" id="invite-email" type="email" inputmode="email" autocomplete="off" spellcheck="false" placeholder="Email address" aria-describedby="invite-note" data-email>
            <span class="select invite__role">
              <label class="sr" for="invite-role">Permission</label>
              <select class="field" id="invite-role" data-role>
                <option value="view">Can view</option>
                <option value="edit">Can edit</option>
              </select>
              <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M7 10l5 5 5-5"/></svg>
            </span>
            <button class="btn btn--ink invite__send" type="submit" disabled data-send>Invite</button>
          </div>
          <p class="note" id="invite-note" data-note>They get an email with a link to the drawings.</p>
        </form>

        <section class="people" aria-labelledby="people-title">
          <h3 class="label" id="people-title" data-part>People with access</h3>
          <ul class="people__list" data-list>
            <li class="person" data-part data-email="marta@orsa.studio">
              <span class="avatar mat-brick" aria-hidden="true"><span class="avatar__fill"></span><span class="avatar__ini">MF</span></span>
              <span class="person__text"><span class="person__name">Marta Ferrante (you)</span><span class="person__mail">marta@orsa.studio</span></span>
              <span class="person__owner">Owner</span>
            </li>
            <li class="person" data-part data-email="jonas@orsa.studio">
              <span class="avatar mat-steel" aria-hidden="true"><span class="avatar__fill"></span><span class="avatar__ini">JL</span></span>
              <span class="person__text"><span class="person__name">Jonas Lindqvist</span><span class="person__mail">jonas@orsa.studio</span></span>
              <span class="select select--quiet">
                <label class="sr" for="role-jonas">Permission for Jonas Lindqvist</label>
                <select class="field" id="role-jonas" data-person-role>
                  <option value="view">Can view</option>
                  <option value="edit" selected>Can edit</option>
                  <option value="remove">Remove access</option>
                </select>
                <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M7 10l5 5 5-5"/></svg>
              </span>
            </li>
            <li class="person" data-part data-email="priya@greywater.eng">
              <span class="avatar mat-timber" aria-hidden="true"><span class="avatar__fill"></span><span class="avatar__ini">PR</span></span>
              <span class="person__text"><span class="person__name">Priya Raman</span><span class="person__mail">priya@greywater.eng</span></span>
              <span class="select select--quiet">
                <label class="sr" for="role-priya">Permission for Priya Raman</label>
                <select class="field" id="role-priya" data-person-role>
                  <option value="view" selected>Can view</option>
                  <option value="edit">Can edit</option>
                  <option value="remove">Remove access</option>
                </select>
                <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M7 10l5 5 5-5"/></svg>
              </span>
            </li>
          </ul>
        </section>

        <section class="link" data-part data-link-part>
          <label class="label" for="share-link">Link to the drawings</label>
          <div class="link__row">
            <input class="field link__url" id="share-link" type="text" readonly value="orsa.studio/p/casa-albera" data-link>
            <button class="btn btn--line link__copy" type="button" data-copy>
              <span class="link__icons" aria-hidden="true">
                <svg class="link__chain" viewBox="0 0 24 24" data-chain><path d="M10 14a4.2 4.2 0 0 0 6 0l3-3a4.2 4.2 0 0 0-6-6l-1.1 1.1M14 10a4.2 4.2 0 0 0-6 0l-3 3a4.2 4.2 0 0 0 6 6l1.1-1.1"/></svg>
                <svg class="link__tick" viewBox="0 0 24 24" data-tick><path d="M5 12.6l4.4 4.4L19 7.4"/></svg>
              </span>
              <span data-copy-label>Copy link</span>
            </button>
          </div>
          <div class="link__foot">
            <p class="note" data-hint>Anyone with this link can view.</p>
            <svg class="dim" aria-hidden="true" data-dim></svg>
          </div>
        </section>

        <p class="sr" aria-live="polite" data-live></p>
      </div>
    </div>
    <svg class="draft" aria-hidden="true" data-draft></svg>
  </dialog>

  <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.

57 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 condivisione al tecnigrafo» da Animorio e adattala al mio sito

Cosa fa

Su un fondo bianco un pulsante grafite alto 56 pixel con l’icona di una persona e un più e la scritta Share; col mouse sopra dai suoi quattro angoli escono due linee azzurre ciascuno, come i segni di taglio di una tavola: le stesse linee che avrà la finestra. Premuto, la pagina si vela di grigio e dai quattro bordi dello schermo entrano quattro linee azzurre lunghe quanto lo schermo, due orizzontali e due verticali, come le righe di un tecnigrafo: corrono verso il centro, vanno un poco oltre il posto dei lati, tornano indietro e si fermano, le verticali un attimo dopo le orizzontali. Lungo di loro la penna ripassa il contorno in grafite, ogni lato dal suo angolo come una girandola, mentre le linee si ritirano fino a lasciare solo le crocette agli angoli; la carta si riempie con un tratteggio bianco a 45 gradi le cui linee si ispessiscono fino a toccarsi, e solo allora entrano le parole. Il pulsante Share sotto la finestra se ne va prima che arrivi la carta. Nella finestra: Share “Casa Albera”, il progetto preliminare con 14 disegni; il campo per invitare una persona per email con la scelta Can view o Can edit e il pulsante Invite, spento finché il campo è vuoto; le tre persone che hanno già accesso, ognuna in un quadrato di carta col suo materiale tratteggiato (muratura, acciaio, legno) e le iniziali su un cartellino bianco, la proprietaria con Owner e le altre col loro permesso; il link ai disegni col pulsante Copy link. Invitando un indirizzo giusto la riga di fondo della finestra torna lunga quanto lo schermo e scende con un piccolo rimbalzo alla misura nuova, il link scivola giù con lei e nel posto rimasto vuoto la persona nuova viene disegnata: le sue righe entrano, il quadrato viene ripassato, il materiale (vetro) si tratteggia in diagonale e compaiono le iniziali, poi l’indirizzo e Invite sent. Un indirizzo sbagliato fa diventare rosso il campo, che trema, e la nota sotto dice come scriverlo; uno già presente illumina la riga di quella persona. Copy link copia il link, il pulsante dice Copied con una spunta che si disegna, e sotto il link compare la sua quota da disegno tecnico: prima la parola Copied, poi la linea che corre da lei ai due capi del link, le linee di richiamo che scendono e le barrette a 45 gradi che la chiudono; dopo 2,4 secondi se ne va e torna la nota. Ogni permesso si cambia, e Remove access cancella la persona: le iniziali e il materiale si ritirano, il quadrato si scioglie e la finestra si accorcia. Close, Esc o un tocco fuori la cancellano al contrario: via le parole, il tratteggio si apre, il contorno si ritira verso gli angoli e le righe escono dallo schermo, mentre il pulsante Share torna con un piccolo rimbalzo.

Come funziona

Le righe su molle

Le quattro linee di costruzione sono linee di un SVG grande quanto la finestra di dialogo, e ognuna ha la sua distanza dal lato che le spetta: una molla smorzata, x'' = −ω²x − 2ζω·x', a passi di 1/240 di secondo sul ticker di GSAP, col passo limitato a 1/30. Partono appena fuori dallo schermo dal loro lato, con ω = 12/DRAFT e ζ = 1 − 0,7·BOUNCE, quindi vanno oltre e tornano; le verticali partono 0,06 secondi dopo. Mentre corrono sono lunghe quanto lo schermo; poi un secondo valore, da 0 a 1, le accorcia fino a OVERSHOOT pixel oltre gli angoli.

Il contorno a girandola

I quattro lati in grafite sono altre quattro linee che crescono ognuna dal suo angolo, in senso orario, tutte insieme con lo stesso avanzamento: alto da sinistra, destro dall’alto, basso da destra, sinistro dal basso. Ogni lato è mezzo spessore più lungo a ogni capo, così gli angoli si chiudono senza puntini. Tutto si ridisegna a ogni fotogramma dalle misure vere della finestra, e quando niente si muove non si ridisegna.

La carta a tratteggio

La carta è un repeating-linear-gradient a 135 gradi con passo di 10 pixel, bianco da 0 a calc(var(--fill) · 10px) e trasparente dopo: GSAP porta --fill da 0 a 1, le linee bianche si ispessiscono finché si toccano e la carta è piena. Finito, una classe la sostituisce con un bianco pieno, perché un gradiente ripetuto può lasciare un capello di giuntura. Le parole entrano dopo, in fila, quando la carta è chiusa.

La riga di fondo e la persona nuova

La finestra ha la cima fissata quando si apre, così una riga in più la fa crescere solo in giù. Invitando, l’altezza va dalla vecchia alla nuova con back.out(1,7) e la sezione del link scivola dalla stessa distanza con la stessa curva, così resta attaccata al fondo; la riga di fondo torna lunga quanto lo schermo per poco più di mezzo secondo. Intanto il quadrato della persona nuova viene disegnato nel suo SVG con la stessa funzione della finestra, in piccolo: righe che entrano da 12 pixel, lati ripassati, il materiale scoperto da un clip-path a triangolo che si allarga in diagonale, le iniziali per ultime.

La quota del link

Copiando, la larghezza del link si misura su un canvas con il carattere del campo, dalla prima all’ultima lettera, in pixel interi. Sotto, un SVG disegna la quota: la parola Copied al centro, i due tratti di linea che corrono da lei ai capi animando x2, le linee di richiamo che scendono animando y2 e le barrette a 45 gradi che crescono dal loro centro con back.out. Il link si copia con navigator.clipboard e, dove non c’è, selezionando il campo e con execCommand.

Una finestra vera

È un dialog nativo aperto con showModal (la pagina dietro diventa irraggiungibile) con aria-modal, aria-labelledby e aria-describedby; il fuoco va sul campo dell’email per chi usa i tasti e sul foglio per il dito e il mouse, Tab gira fra i controlli della finestra senza uscire, Esc ferma l’evento cancel e la chiude disegnando, e alla fine il fuoco torna su Share. Ogni campo ha la sua label, le conferme passano da una regione aria-live, l’errore anche da aria-invalid e aria-describedby. Un clic da script sul riquadro del pulsante (l’anteprima della libreria) fa un giro semplice, apre e chiude, e uno completo, apre, scrive un indirizzo e lo invita, copia e chiude; chiudendo rimette tutto com’era, e guarda lo stato, non una lista fissa.

Valori da cambiare

NomeFileDi partenzaCosa cambia
DRAFTscript.js0.8I secondi in cui la finestra viene disegnata: righe, contorno, carta e parole.
BOUNCEscript.js0.6Quanto le righe vanno oltre il loro posto prima di fermarsi, da 0 a 1.
OVERSHOOTscript.js28Quanto le linee di costruzione azzurre continuano oltre gli angoli, in pixel.
PUT_AWAYscript.js0.42I secondi in cui la finestra viene cancellata.
DIMscript.js0.24Quanto si scurisce la pagina dietro la finestra, da 0 a 1.
HOLDscript.js2.4I secondi in cui Copied resta sotto il link.

Provali nel Playground

Quando usarla

Per condividere un progetto, una cartella, una tavola o un documento con altre persone in uno strumento di lavoro: uno studio di architettura o di design, un programma di disegno, un archivio di file. Il disegno a tecnigrafo sta bene dove il prodotto parla di misure e di progetti; tolto il gesto, resta una finestra di condivisione completa e accessibile.

Sul telefono

A 390 pixel la finestra è larga 358, a 16 pixel dai lati, e le crocette si accorciano per non toccare il bordo dello schermo. L’indirizzo sta su una riga sua, il permesso e Invite sotto; la colonna dei permessi si stringe per lasciare spazio ai nomi, e Copy link tiene solo l’icona (le parole restano per chi usa un lettore di schermo) così il link si legge intero. I campi sono a 16 pixel, così Safari non ingrandisce la pagina, e la chiusura è alta 44. Se le persone sono tante la finestra arriva all’altezza dello schermo e dentro scorre.

Con il movimento ridotto

Niente righe che corrono, niente contorno che si disegna, niente tratteggio: il pulsante Share svanisce e la finestra compare già disegnata con una dissolvenza, e se ne va allo stesso modo. La persona invitata compare con una dissolvenza e la finestra prende subito la misura nuova; la quota del link compare già disegnata; il campo sbagliato diventa rosso senza tremare e i pulsanti non si schiacciano.

Trappole

  • Il pulsante Share sta proprio sotto la finestra: mentre la carta si riempiva di tratteggio si vedeva attraverso le righe bianche, un rettangolo nero a strisce sotto le parole. Se la finestra lo copre, il pulsante svanisce prima che arrivi la carta e torna solo quando la carta se n’è andata.
  • Il quadrato della persona nuova si disegnava subito, mentre la sezione del link ci stava ancora scivolando sopra: per un fotogramma le sue righe tagliavano la scritta Link to the drawings. Ora le sue linee restano trasparenti finché non è il loro turno, e la riga resta vuota finché il link non è passato.
  • Chiudendo, il tratteggio si apriva mentre le parole stavano ancora svanendo, e le lettere si vedevano sopra le strisce. Ora le parole se ne vanno tutte prima che la carta cominci ad aprirsi.
  • Far svanire con opacity l’SVG grande quanto lo schermo, o la finestra intera con la sua ombra sfumata, mostrava in Chromium il riquadro del livello come un rettangolo più scuro intorno alla finestra. Ora svaniscono le singole linee e i singoli strati (ombra, carta, contenuto), mai il gruppo.
  • L’evento close del dialog arriva un momento dopo la chiusura: se intanto la finestra era già stata riaperta (l’anteprima clicca anche in fretta), lo script la rimetteva a riposo mentre era aperta e l’anteprima perdeva il passo. Ora l’evento viene ignorato se il dialog è di nuovo aperto.
  • Al telefono il link e il nome della proprietaria venivano tagliati coi puntini. La colonna dei permessi si stringe a 108 pixel e Copy link tiene solo l’icona, con le parole nascoste per i lettori di schermo.
  • Invitando qualcuno mentre la finestra si stava ancora disegnando, lo script fermava tutte le animazioni delle righe per farle scivolare, comprese le loro dissolvenze d’entrata: le persone già presenti e il link restavano invisibili. Ora si fermano solo l’altezza e lo scivolamento, e le dissolvenze finiscono.
  • Il video della scheda dura 6,4 secondi a partire dal poster, con la finestra aperta: con un giro solo (apri, invita, copia, chiudi) mostrava l’invito e la copia ma mai la finestra che si disegna. I giri dell’anteprima ora si alternano, uno semplice (apri e chiudi) e uno completo, così nel video la finestra si cancella e si ridisegna.
  • Il fondo della finestra deve muoversi insieme a quello che c’è sotto la riga nuova: l’altezza e lo scivolamento del link usano la stessa durata e la stessa curva back.out, e il fondo si rilegge a ogni fotogramma mentre cresce, così le righe azzurre e il contorno lo seguono senza staccarsi.

Librerie

GSAP 3.15.0, Jost (font variabile) 5.3.0.

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