Vai al contenuto
animorio
EN
Tutti i componenti

Il caricamento che annerisce la frase

Caricamento, Testo, TransizioniGSAPImpegnativaPeso compresso: Demo 13 KBGSAP 28 KBGratisScarica lo zip

Nello stile minimal: l’esportazione di 248 foto in un archivio, e la barra di avanzamento è la frase stessa, Exporting 248 photos to your archive. Man mano che il lavoro avanza le lettere passano da un filo a tutto il peso una dopo l’altra, come se la frase si stampasse, su un’onda di peso sfumata su quattro lettere, senza che la frase si sposti di un pixel. Sotto, la percentuale su rulli che girano e una linea sottile. Pausa, ripresa, la connessione persa che toglie l’inchiostro da dove si è fermata, e alla fine la frase si ricompone in 248 photos archived con le sue stesse lettere.

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">
  <title>The sentence that prints itself</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 photo app exporting to an archive, and the progress bar is the sentence itself: as the work goes on its
         letters go from a hairline to full weight one after the other, as if it were being printed, on a weight wave
         a few letters soft. Under it the percentage on rolling figures and a thin line. Pause, resume, a lost
         connection that lifts the ink back off, and at the end the sentence sets itself again from its own letters -->
    <section class="ex" aria-label="Photo export" data-export>
      <p class="ex__phrase" aria-hidden="true" data-phrase></p>
      <p class="sr" data-words>Exporting 248 photos to your archive</p>

      <div class="ex__row">
        <span class="ex__pct" aria-hidden="true" data-pct></span>
        <span class="ex__count" aria-hidden="true" data-count>0 of 248</span>
      </div>

      <div class="ex__line" role="progressbar" aria-label="Export" aria-valuemin="0" aria-valuemax="100"
           aria-valuenow="0" aria-valuetext="Not started" data-line>
        <span class="ex__track" data-track></span>
        <span class="ex__fill" data-fill></span>
        <span class="ex__mark" data-mark></span>
        <span class="ex__head" data-head></span>
      </div>

      <div class="ex__foot">
        <span class="ex__swap" data-status>Originals · 2.6 GB</span>
        <button class="ex__btn" type="button" data-btn data-autoclic>
          <span class="ex__btnfill" aria-hidden="true"></span>
          <span class="ex__label" data-label>Export</span>
        </button>
      </div>

      <p class="sr" aria-live="polite" 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.

31 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 caricamento che annerisce la frase» da Animorio e adattala al mio sito

Cosa fa

Su un fondo nero, da solo al centro: una frase grande su tre righe, Exporting 248 photos to your archive, nel taglio più sottile e più largo di Archivo, grigio caldo; sotto, a sinistra 0% in cifre tabellari e a destra 0 of 248; una linea sottile; in fondo Originals · 2.6 GB e il pulsante a pillola Export, col bordo sottile. Entrando, le lettere salgono di pochi pixel una dopo l’altra e la linea si disegna da sinistra. Premuto Export, le lettere prendono inchiostro una dopo l’altra, dalla E in poi: diventano nere, cioè chiare sul nero, e pesanti, ma restano esattamente al loro posto, perché ognuna si stringe sull’asse della larghezza quanto serve per restare larga come era sottile. Il passaggio non è netto: le quattro lettere davanti all’onda sono a metà peso, e ogni lettera, quando l’inchiostro arriva, affonda di un pixel e torna su, e le due vicine sentono il colpo. Sotto, la percentuale gira come un contachilometri, le unità passano per ogni cifra, la linea si riempie e la sua testa è un trattino vermiglio; a destra il conto delle foto, in fondo i gigabyte arrivati. Pause ferma l’onda dov’è, a metà di una parola, la testa si spegne un poco e la riga dice Paused at 1.20 GB; Resume riparte. Una volta su due la connessione si perde: un trattino vermiglio resta dove si è fermata, la riga in vermiglio dice Connection lost · 124 photos kept, e l’inchiostro si toglie dalle lettere andando all’indietro fino alle foto tenute, mentre i rulli tornano giù; le lettere che si alleggeriscono salgono di un capello. Retry riparte da lì. A 100% le lettere che non servono, Exporting, to e your, perdono il peso e svaniscono salendo; photos scivola a destra per fare posto, poi 248 scorre lungo la prima riga e scende al suo posto: le parole si spostano intere, come i blocchi di piombo del tipografo, e mentre volano perdono un po’ d’inchiostro che riprendono quando si posano. Alla fine si stampa la d: 248 photos archived. Export again fa il giro al contrario, con la frase sottile che si ricompone, e riparte.

Come funziona

Ogni lettera nella sua cella

La frase è spezzata in parole (flex con l’a capo) e ogni lettera è una cella larga quanto la lettera nel taglio sottile, wght 100 e wdth 125, misurata in em: la frase va a capo una volta sola e nello stesso modo per tutto il caricamento. Il buco fra le parole è uno spazio dello stesso taglio, misurato come differenza fra «n n» e «nn». La cella è l’elemento che GSAP sposta; la lettera dentro è quella a cui lo script cambia peso, larghezza, tono e affondo, così le due trasformazioni non si cancellano.

Il peso che non sposta niente

Una lettera più pesante è più larga. All’avvio lo script misura, per ogni lettera delle due frasi e per diciassette pesi fra 100 e 900, la larghezza wdth a cui la lettera è larga esattamente quanto la sua cella: una bisezione di undici passi, fatta per tutte le lettere insieme (ognuna ha il suo wdth di prova, poi si leggono tutte le larghezze), così ogni passo costa un solo calcolo dell’impaginazione e non uno per lettera. Durante il caricamento il wdth di ogni lettera si legge da questa tabella, interpolando fra due pesi: la O nera si stringe fino a circa 100, la i non ci riesce del tutto e sfora di mezzo pixel, coperto dai suoi margini.

L’onda di peso e l’affondo

Il lavoro fatto, da 0 a 1, diventa un fronte che corre sulla frase: per la lettera i l’obiettivo è smoothstep((p·(n + SOFT) − i) / SOFT), quindi SOFT lettere stanno a metà strada. Ogni lettera insegue il suo obiettivo con una molla appena sotto lo smorzamento critico (0,74), integrata a ogni fotogramma con un passo di al massimo 1/30 di secondo. Quando l’inchiostro supera il 90% la lettera riceve una spinta verso il basso su una molla più morbida (0,42), le vicine un terzo e un decimo: affonda di PRESS pixel e torna su con un assestamento. Quando la connessione si perde e il peso torna sotto il 40%, la spinta è piccola e verso l’alto.

I rulli della percentuale

Ogni cifra è un rullo con 0-9 e di nuovo 0 in una finestra alta una cifra, sfumata sopra e sotto con una maschera. Il rullo delle unità segue il conto intero della percentuale, quello delle decine il conto diviso dieci, quello delle centinaia diviso cento, su una molla: lo spostamento è il conto modulo dieci, quindi il passaggio da 9 a 10 gira in avanti senza salti. Un salto di più di sei cifre (il ritorno a zero) si fa dalla parte più corta. Un rullo che non serve si chiude in larghezza con un piccolo rimbalzo.

La frase che si ricompone dalle sue lettere

Le lettere comuni alle due frasi si trovano come fa un diff (Ratcliff e Obershelp): la sequenza comune più lunga, 248photos, poi la stessa ricerca a sinistra e a destra, che trova archive. Le lettere che restano si raggruppano in parole e volano con la tecnica FLIP: si misurano prima, si rifà l’impaginazione con la frase nuova, si misurano dopo e si parte dalla differenza. Una parola parte solo quando le parole che stanno dove deve andare se ne sono andate (un piccolo ordinamento topologico sui rettangoli), e una parola che cambia riga viaggia sulla più alta delle due: scendendo prima scorre e poi cala, salendo prima sale e poi scorre. Le lettere che se ne vanno restano dov’erano, tolte dal flusso con una posizione assoluta, e svaniscono salendo; quelle nuove si stampano al loro posto.

Il giro dell’anteprima

Un clic da script sul pulsante (detail 0, senza tastiera) fa partire il giro intero, più veloce di PREVIEW: pausa al 46%, ripresa, connessione persa, Retry, la frase finale e il ritorno a riposo, con un finto tocco sul pulsante a ogni passo; i tempi fra un passo e l’altro sono delayedCall di GSAP e gli altri clic da script durante il giro sono ignorati. Un clic vero ferma il giro e prende il comando. Quando niente si muove il ciclo esce dal ticker di GSAP e non ridisegna niente.

Valori da cambiare

NomeFileDi partenzaCosa cambia
PHRASEscript.js'Exporting 248 photos to your archive'La frase mentre le foto vengono esportate: è lei la barra di avanzamento.
DONEscript.js'248 photos archived'La frase alla fine, ricomposta con le lettere che ha in comune con la prima.
PHOTOSscript.js248Quante foto vengono esportate (il conto sotto la frase).
SIZE_GBscript.js2.6Quanto pesa l’esportazione, in gigabyte.
SECONDSscript.js6Quanti secondi dura un’esportazione nella demo (una vera segue i suoi byte).
WEIGHTscript.js[100, 900]Il peso (wght) di una lettera non ancora stampata e di una stampata.
WIDTHscript.js125La larghezza (wdth) delle lettere sottili: quelle stampate si stringono quanto basta per restare al loro posto.
SOFTscript.js4Su quante lettere è sfumato il bordo dell’onda di peso.
PRESSscript.js1.2Di quanti pixel affonda una lettera quando arriva l’inchiostro.
FAIL_EVERYscript.js2Un’esportazione ogni quante perde la connessione (0 mai).
FAILscript.js[0.72, 0.5]Dove si perde la connessione e fin dove torna indietro l’inchiostro (le foto tenute), da 0 a 1.
PREVIEWscript.js[1.7, 0.46]Nel giro dell’anteprima: quante volte più veloce, e dove si mette in pausa.
LABELSscript.js['Export', 'Pause', 'Resume', 'Retry', 'Export again']Le parole del pulsante, stato per stato.
--inkstyle.css#f4f1eaLe lettere stampate, le cifre e la linea.
--lightstyle.css#a8a49cLe lettere non ancora stampate.
--accentstyle.css#ff5a2aLa testa della linea e quello che è andato storto.

Provali nel Playground

Quando usarla

Per un’esportazione, un caricamento o un backup in un’app di foto o di documenti, per la pubblicazione di un articolo, per l’invio di un ordine o di un modulo, per ogni attesa in cui la frase che dice cosa succede può essere essa stessa l’avanzamento.

Sul telefono

Il componente prende tutta la larghezza meno i margini (fino a 400 pixel) e la frase si rimpicciolisce col telefono, con le celle in em, quindi va a capo come sul computer e non si sposta mai; le animazioni sono le stesse. Il pulsante risponde al tocco come al mouse: si riempie e la scritta si allarga mentre il dito preme. Se la finestra cambia misura mentre la frase si ricompone, la ricomposizione salta alla fine.

Con il movimento ridotto

Niente si sposta: il peso delle lettere cambia lo stesso, perché è l’avanzamento, ma senza molla e senza affondo; le cifre cambiano senza girare, le righe cambiano in dissolvenza e la frase finale arriva in dissolvenza invece di ricomporsi a lettere in volo.

Trappole

  • La prima misura delle lettere dava a tutte la stessa larghezza, quella della pagina: la sonda era un blocco e si allargava quanto il suo contenitore. Ora ogni lettera della sonda è un inline-block e la sonda sta fuori dal flusso, con una posizione assoluta.
  • La bisezione lettera per lettera chiedeva un calcolo dell’impaginazione per ogni lettera, per ogni peso e per ogni passo: migliaia. Fatta per tutte le lettere insieme (prima si scrivono tutti i wdth di prova, poi si leggono tutte le larghezze) ne bastano 176.
  • Il primo abbinamento delle lettere comuni le faceva volare una per una con uno sfalsamento: le lettere di photos, andando a destra, si raggiungevano e si sovrapponevano. Ora volano a parole intere, e dentro la parola parte prima la lettera sul bordo che va avanti.
  • In volo diagonale 248 passava sopra photos, già arrivata. Una parola che cambia riga ora viaggia sulla riga più alta delle due, e parte solo quando chi sta nel suo posto se n’è andato (un ordinamento topologico sui rettangoli).
  • Le lettere che lasciano la frase non erano più nell’elenco che il ciclo disegna, quindi la d restava nera mentre il resto si alleggeriva: ora il ciclo disegna anche loro finché non sono svanite.
  • Un tocco dato mentre la frase entrava andava perso, perché il componente era ancora nello stato d’entrata: ora la frase si può usare appena è impaginata, anche a metà dell’entrata, e un tocco arrivato prima che il carattere sia caricato aspetta e parte subito dopo.

Librerie

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

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