Vai al contenuto
animorio
EN
Tutti i componenti

I permessi anneriti

Consenso, SVG, Testo, TransizioniGSAPImpegnativaPeso compresso: Demo 12 KBGSAP 28 KBGratisScarica lo zip

La scheda in cui un’app per la corsa chiede di leggere i tuoi dati di salute e mostra cosa vedrebbe: la corsa di domenica, il battito a riposo, il sonno, il peso. Quello che spegni viene annerito lì dove sta: le lettere si gonfiano, più pesanti e più larghe, e il loro inchiostro corre lungo le parole fino a farne una barra bagnata che poi si asciuga; riaccendendo, l’inchiostro rientra nelle lettere. Condividendo, il giallo dell’app passa come un evidenziatore sui valori che leggerà, e la pista nella sua icona si allunga di un tratto per ognuno.

Il codice

Una cartella che funziona da sola: index.html, style.css, script.js e le librerie da CDN.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
  <title>The redacted permissions</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">
    <!-- the card where a running coach app asks to read your health data. Each kind of data shows what the app
         would see; switched off, the words swell into a bar of wet ink that dries, switched on the ink draws back
         into the letters. Shared, the app's yellow runs like a highlighter over the values left in clear, the
         track in its icon grows, and the card says what was shared. The rows are made by script.js, from KINDS -->
    <section class="permit" aria-labelledby="permit-title" data-permit data-autoclic>
      <header class="permit__head">
        <span class="app" aria-hidden="true" data-app>
          <svg class="app__mark" viewBox="0 0 48 48" focusable="false">
            <g transform="rotate(-24 24 24)">
              <path class="app__lap app__lap--ghost" d="M24 36H30A12 12 0 0 0 30 12H18A12 12 0 0 0 18 36Z" />
              <path class="app__lane" d="M24 30.5H30A6.5 6.5 0 0 0 30 17.5H18A6.5 6.5 0 0 0 18 30.5Z" />
              <path class="app__lap" d="M24 36H30A12 12 0 0 0 30 12H18A12 12 0 0 0 18 36Z" data-route />
            </g>
          </svg>
        </span>
        <h2 class="permit__title" id="permit-title" data-title>Share your health data with <span data-app-name>Pacenote</span></h2>
        <p class="permit__text" data-text><span class="permit__line"><span data-app-name>Pacenote</span> plans your runs from what you share.</span> <span class="permit__line">What you keep stays on this phone, blacked out.</span></p>
      </header>

      <ul class="kinds" data-kinds></ul>

      <div class="actions" data-actions>
        <div class="actions__row">
          <button class="btn btn--quiet" type="button" data-needed>Only what’s needed</button>
          <button class="btn btn--quiet" type="button" data-all>Allow all</button>
        </div>
        <button class="btn btn--main" type="button" data-share><span>Share with <span data-app-name>Pacenote</span></span></button>
      </div>
      <div class="actions actions--done" hidden data-done>
        <p class="done__note">
          <svg class="done__mark" viewBox="0 0 20 20" aria-hidden="true" focusable="false"><path d="M5 10.5l3.2 3.2L15 6.6" /></svg>
          <span data-note>Shared just now. Change it any time.</span>
        </p>
        <button class="btn btn--quiet btn--big" type="button" data-change>Change what’s shared</button>
      </div>

      <p class="sr" role="status" aria-live="polite" aria-atomic="true" data-live></p>
    </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.

38 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 «I permessi anneriti» da Animorio e adattala al mio sito

Cosa fa

Su un fondo bianco una scheda bianca larga 404 pixel, con un’ombra morbida. In alto l’icona di Pacenote, un quadrato d’inchiostro con una pista d’atletica gialla vista di sbieco, e il titolo Share your health data with Pacenote; sotto, due righe: Pacenote plans your runs from what you share. What you keep stays on this phone, blacked out. Poi quattro righe di dati, ognuna col suo nome e quello che l’app vedrebbe, scritto grande: Workouts, 8.4 km run on Sunday, con l’etichetta Required; Heart rate, 58 bpm at rest; Sleep, 6 h 40 min last night; Body weight, 71.4 kg this morning, ognuna col suo interruttore. In fondo Only what’s needed e Allow all, e il pulsante nero Share with Pacenote. All’apertura la scheda sale piano e i tre valori che non servono vengono anneriti uno dopo l’altro: niente esce se non lo lasci uscire. Annerire è un gesto solo: le lettere si fanno più pesanti e più larghe, poi l’inchiostro si allarga intorno a ognuna e corre lungo il valore da sinistra a destra, chiudendo i buchi delle lettere e gli spazi fra le parole, finché resta una barra nera con le gobbe delle lettere alte e di quelle che scendono sotto la riga. L’inchiostro fresco è un po’ più chiaro e bluastro e ha un riflesso lungo il bordo di sopra, che si asciuga in poco più di un secondo; i bordi ondeggiano appena, come inchiostro sulla carta. Accendendo un interruttore (o toccando la riga) l’inchiostro rientra nelle lettere, sempre da sinistra, e le lettere si posano un filo più sottili prima di tornare normali; la levetta corre allungandosi e diventa d’inchiostro sul binario giallo. Only what’s needed annerisce tutto quello che non serve, una riga dopo l’altra; Allow all scopre tutto. Col mouse sopra una riga si vede cosa farebbe il clic: le parole in chiaro si appesantiscono un poco, come se l’inchiostro stesse per arrivare, e l’inchiostro sulle parole nascoste si ritira dai bordi senza lasciarle vedere. Share with Pacenote: gli interruttori si fanno da parte e il giallo dell’app passa come un evidenziatore dalla punta tagliata su ogni valore che leggerà, uno dopo l’altro; a ogni passata la pista nell’icona si allunga del suo tratto e l’icona sobbalza. Il titolo diventa Pacenote is connected, le righe dicono cosa legge e cosa resta annerito sul telefono, e in fondo Shared just now e Change what’s shared, che toglie il giallo e rimette gli interruttori.

Come funziona

Le lettere che si gonfiano

Ogni valore è un testo SVG con un tspan per lettera (il contorno del testo HTML, -webkit-text-stroke, ha gli angoli a punta e ingrossato mette le spine), e ogni lettera ha la sua quantità d’inchiostro, da 0 a 1. Nella prima metà la lettera prende peso (l’asse wght di Archivo da 600 a 900) e per tutta la corsa larghezza (wdth da 88 a 112), così le lettere dopo si spostano e l’inchiostro sembra allargarsi. L’inchiostro vero è il contorno della lettera, dello stesso colore, con gli angoli tondi (stroke-linejoin round): un contorno largo due raggi è la lettera ingrandita di un disco di quel raggio in ogni direzione, e cresciuto abbastanza chiude i buchi delle lettere e gli spazi.

Il corpo della barra

Sotto le lettere c’è una fascia nel mezzo delle minuscole, spessa a ogni lettera quanto quella lettera è annerita: i centri delle lettere vengono da getStartPositionOfChar e getEndPositionOfChar a ogni fotogramma (le lettere si allargano), e il bordo è una curva di Catmull-Rom chiusa, tonda alle punte. Mentre l’inchiostro corre la fascia si assottiglia verso il fronte; ferma, le lettere gonfie ne escono un poco dove sono alte o scendono sotto la riga, ed ecco le gobbe.

L’inchiostro bagnato

L’inchiostro fresco ha un colore fra --ink e --wet (WET dice quanto) e un riflesso: una linea bianca sfocata che segue il bordo di sopra della fascia, spezzata come il riflesso di una finestra; in DRY secondi si asciuga. Finché c’è inchiostro il gruppo passa per un filtro con feTurbulence a bassa frequenza e feDisplacementMap, di forza proporzionale all’inchiostro, che fa ondeggiare i bordi; le parole pulite si disegnano senza filtro.

Gli interruttori e le scelte

Gli interruttori sono pulsanti veri con role switch e aria-checked, chiamati col nome della riga, e tutta la riga si tocca. Spegnendo, le lettere si anneriscono in fila in SWEEP secondi con back.out; accendendo, l’inchiostro torna a zero con un back.out che lo fa scendere sotto lo zero, e le lettere passano un attimo sotto il loro peso. Only what’s needed e Allow all cambiano le righe una dopo l’altra, a 0,13 secondi; col mouse, sopra una riga in chiaro il peso sale di 110, sopra una annerita l’inchiostro scende a 0,9.

La conferma

Share: gli interruttori sfumano verso destra, e su ogni valore condiviso passa in MARK secondi una fascia gialla che va dall’inizio delle lettere fin dove è arrivata, un po’ irregolare e tagliata di sbieco alle punte come un evidenziatore, sotto le lettere. Alla fine di ogni passata la pista nell’icona (stroke-dashoffset) arriva alla parte di dati condivisi e l’icona si schiaccia e torna con elastic.out. Titolo e righe sfumano con un poco di sfocatura, cambiano, e la loro altezza scivola dalla vecchia alla nuova mentre sono invisibili, così la scheda non salta.

Tastiera, lettori di schermo e anteprima

Con Tab si va dagli interruttori ai pulsanti, Spazio o Invio accendono e spengono, e l’anello del focus si vede solo a chi usa i tasti. Ogni riga dice al lettore di schermo il suo valore, o che è annerito e resta sul telefono; la scelta finale e le scelte rapide si annunciano in una regione aria-live, e il focus passa a Change what’s shared e poi torna su Share. Il clic dell’anteprima (detail 0) scopre tutto, annerisce quello che non serve, accende il battito, condivide, riapre, e così via; se la scheda si sta ancora muovendo, il clic aspetta.

Valori da cambiare

NomeFileDi partenzaCosa cambia
APPscript.js'Pacenote'Il nome dell’app che chiede, nel titolo, nel pulsante e nella conferma.
KINDSscript.js[{ name: 'Workouts', value: '8.4 km run on Sunday', needed: true }, …]I dati che l’app chiede: il nome, quello che vedrebbe e se le serve per forza (needed: senza interruttore, mai annerito).
SWELLscript.js1Quanto si allarga l’inchiostro intorno alle lettere: 0,6 stretto, 1,6 a macchia.
SWEEPscript.js0.62I secondi in cui l’inchiostro corre lungo un valore, e in cui rientra.
WETscript.js0.75Quanto luccica l’inchiostro fresco (0: opaco da subito).
DRYscript.js1.3I secondi in cui l’inchiostro si asciuga.
MARKscript.js0.42I secondi in cui il giallo dell’app passa su un valore che leggerà.

Provali nel Playground

Quando usarla

Per ogni app che chiede di vedere dati personali: salute, contatti, calendario, posizione, foto, conti; per il collegamento fra due servizi che mostra cosa passerà dall’uno all’altro; per una pagina della privacy, o un modulo che lascia nascondere i campi delicati prima di inviarlo.

Sul telefono

La scheda prende la larghezza dello schermo meno i margini (358 pixel a 390) e resta uguale; tutta la riga è un bersaglio per il dito, gli interruttori sono di 48 per 30, e i due pulsanti piccoli stringono un poco le lettere (l’asse della larghezza) perché Only what’s needed stia in metà riga. Il suggerimento al passaggio c’è solo col mouse.

Con il movimento ridotto

La scheda non sale e l’inchiostro c’è già; accendendo o spegnendo, l’inchiostro compare o sparisce di colpo con una breve dissolvenza, senza correre, senza riflesso e senza la levetta che si allunga. Condividendo, il giallo compare sfumando su tutti i valori insieme, la pista nell’icona è subito al suo punto e le parole cambiano con una dissolvenza.

Trappole

  • Tenere fermo lo spazio delle righe di testo (min-height) perché la scheda non saltasse lasciava un buco sotto il titolo quando la conferma era più corta: l’altezza del titolo e delle righe scivola dalla vecchia alla nuova mentre le parole sono invisibili.
  • Il riflesso dell’inchiostro bagnato fatto con una luce (feSpecularLighting sull’alfa sfocata) ingrigiva tutta la barra: su una superficie piana la luce speculare non è mai zero. Il riflesso è una linea bianca sfocata disegnata lungo il bordo di sopra della barra, e si spegne asciugando.
  • Un rumore fitto nel feDisplacementMap rendeva i bordi pelosi; con una frequenza bassa (0,07 per 0,16) ondeggiano come inchiostro sulla carta.
  • Copie dei valori che volavano nell’icona passavano sopra il titolo e le righe, e per un attimo coprivano il testo: la conferma resta sui valori stessi (il giallo dell’evidenziatore) e sulla pista nell’icona.
  • In un pulsante inline-flex lo spazio prima di uno span sparisce (Share withPacenote): la scritta sta in uno span suo.
  • Il clic dell’anteprima arrivava mentre l’inchiostro dell’apertura correva ancora e andava perso: se la scheda si muove, il clic aspetta che sia ferma.

Librerie

GSAP 3.15.0, Archivo (font variabile) 5.3.0.

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