Vai al contenuto
animorio
EN
Torna alla libreria

Le didascalie che leggono

Testo, ScrollGSAP, CanvasImpegnativaPeso compresso: Demo 16 KBGSAP + ScrollTrigger 45 KBGratisScarica lo zip

Scorri dentro l’anteprima

Un fumetto in quattro tavole incise. Quando una didascalia arriva sullo schermo il suo riquadro si srotola dal bordo sinistro e le righe entrano una dopo l’altra; poi un narratore la legge, una parola rossa alla volta, al passo di una voce vera, e aspetta se scorri in fretta.

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>Captions that read aloud</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/im-fell-english@5.3.0/index.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/im-fell-english@5.3.0/400-italic.css">
  <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>
  <header class="bar">
    <a class="brand" href="#">Tallow &amp; Ink</a>
    <nav class="bar__nav" aria-label="Sections">
      <a href="#">Books</a>
      <a href="#">Pre-order</a>
    </nav>
  </header>

  <main>
    <section class="intro">
      <p class="kicker">A graphic novel in six chapters</p>
      <h1 class="title" data-title>The Night Ferry</h1>
      <p class="lede">Scroll down slowly. The narrator reads each caption as it arrives, and waits whenever you hurry.</p>
    </section>

    <!-- the story: four panels drawn by the script as engravings, each with its caption; a caption unrolls from its
         left edge when it comes on screen, then the narrator reads it, one word at a time -->
    <section class="strip" aria-label="Chapter one">
      <figure class="panel panel--wide" data-panel="harbour">
        <canvas class="panel__art" data-art aria-hidden="true"></canvas>
        <figcaption class="caption caption--top" data-caption>Every night at eleven the last ferry leaves Corran harbour with its lamps lit and nobody aboard.</figcaption>
      </figure>

      <figure class="panel panel--right" data-panel="shore">
        <canvas class="panel__art" data-art aria-hidden="true"></canvas>
        <figcaption class="caption caption--bottom" data-caption>The ferryman counts the lights along the shore, one by one, until the fog has taken all of them.</figcaption>
      </figure>

      <figure class="panel panel--left" data-panel="bell">
        <canvas class="panel__art" data-art aria-hidden="true"></canvas>
        <figcaption class="caption caption--top caption--end" data-caption>Halfway across, a bell rings out where no buoy has ever been.</figcaption>
      </figure>

      <figure class="panel panel--wide" data-panel="answer">
        <canvas class="panel__art" data-art aria-hidden="true"></canvas>
        <figcaption class="caption caption--bottom" data-caption>He slows the engine and lifts his lantern. Far below, the water answers with a light of its own.</figcaption>
      </figure>
    </section>

    <section class="end">
      <p class="kicker">Chapter one is free to read</p>
      <h2 class="end__title">Out on 14&nbsp;November</h2>
      <div class="end__actions">
        <a class="button" href="#">Read chapter one</a>
        <a class="button button--ghost" href="#">Pre-order the book</a>
      </div>
    </section>
  </main>

  <!-- the narrator: what it is doing, and the switch for a real voice where the browser has one -->
  <aside class="narrator" data-narrator aria-live="off">
    <span class="narrator__bars" aria-hidden="true"><i></i><i></i><i></i><i></i></span>
    <span class="narrator__state" data-state>Narrator: quiet</span>
    <button class="narrator__voice" type="button" data-voice aria-pressed="false" hidden>
      <svg viewBox="0 0 20 20" width="16" height="16" aria-hidden="true"><path d="M3 7.5h3l4-3.5v12l-4-3.5H3z" fill="currentColor"/><path d="M13 7a4.2 4.2 0 0 1 0 6M15.4 4.8a7.4 7.4 0 0 1 0 10.4" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>
      <span data-voice-label>Read aloud</span>
    </button>
  </aside>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/ScrollTrigger.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.

41 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 «Le didascalie che leggono» da Animorio e adattala al mio sito

Cosa fa

L’anteprima di un fumetto inventato, The Night Ferry, di un editore inventato, Tallow & Ink. Il titolo arriva lettera per lettera dai due lati verso il centro, prima quelle di mezzo. Sotto ci sono quattro tavole: il traghetto che lascia il porto sotto la luna, le luci del paese che la nebbia si mangia, una boa con la campana in mezzo al mare, una lanterna alzata sull’acqua nera e una luce rossa che sale dal fondo. Le tavole sono incisioni disegnate dallo script, con linee che si ingrossano nell’ombra e si rompono in puntini nella luce; si ridisegnano otto volte al secondo con le linee mosse di poco, così il disegno sembra fatto a mano e vivo. Ogni tavola ha la sua didascalia: quando arriva poco sotto la metà dello schermo il riquadro si srotola dal suo bordo sinistro e le righe entrano da quel bordo, una dopo l’altra. Poi il narratore la legge: ogni parola diventa rossa un attimo prima di essere letta e torna nera subito dopo, ai tempi di una voce registrata, con le pause alle virgole e ai punti. Legge una didascalia alla volta, nell’ordine in cui sono arrivate, e comincia solo quando lo scorrimento si calma; il riquadro in basso dice se sta leggendo, se aspetta o se tace. Se una didascalia esce mentre la legge, sfuma e tocca alla prossima; quando ritorna si srotola e si legge di nuovo. Dove il browser sa parlare, «Read aloud» gli dà una voce, e le parole rosse la seguono.

Come funziona

Le tavole incise

Ogni scena è dipinta in grigi su tre tele nascoste: il tono, dal nero al bianco, l’angolo delle linee e quanto colore d’accento. Poi ogni pixel diventa inchiostro, carta o rosso confrontando il tono con un campo di linee ondulate distanti SPACING pixel, come nello shader del sito: sotto una prima soglia è inchiostro, sopra è il colore, sopra una seconda soglia è carta, e le linee spostano le due soglie, così i bordi delle ombre sono tratteggiati. Al buio metà di ogni linea è inchiostro, alla luce niente; in mezzo le linee si rompono in puntini.

Il disegno che ribolle

Ogni tavola si incide tre volte, con un piccolo tremolio diverso nelle linee e una cornice storta in un altro modo, e i tre disegni si danno il cambio BOIL volte al secondo. Si preparano quando la tavola è a uno schermo di distanza, un disegno alla volta, per non fermare la pagina.

Il riquadro si srotola

Quando il bordo alto della didascalia passa ENTER per cento dello schermo, il riquadro parte da FROM della sua larghezza e si srotola in UNROLL secondi con la curva cubic-bezier(0.45, 0.30, 0.16, 1) dell’originale, mentre tutta la didascalia arriva da SHIFT pixel a sinistra. Il riquadro si allarga con scaleX, il testo no: lo taglia un clip-path che segue il bordo del riquadro. Ogni riga entra dal bordo sinistro in SLIDE secondi (power3.out), STAGGER secondi dopo la precedente.

I tempi della voce

Ogni parola dura VOICE.perLetter secondi per lettera più VOICE.base, mai meno di VOICE.shortest; fra due parole passa VOICE.gap, dopo una virgola VOICE.comma, dopo un punto VOICE.stop. Sono le medie misurate sulle parole della voce narrante del sito. Una parola è rossa da LEAD secondi prima del suo inizio a LEAD dopo la sua fine, con uno smoothstep; PACE accelera o rallenta tutto.

Il narratore in coda

Le didascalie che arrivano si mettono in coda. Il narratore prende la prima solo se non sta già leggendo e se la pagina è rimasta sotto CALM pixel al fotogramma per WAIT secondi. Una didascalia che esce dallo schermo lascia la coda, o sfuma in 0,4 secondi se era quella letta; con REPLAY si riavvolge e si rilegge quando torna.

La voce vera

Con «Read aloud» il narratore usa la sintesi vocale del browser. A ogni parola che la voce raggiunge (l’evento boundary) l’orologio delle parole si rimette su quella, così il rosso segue la voce anche se va a un altro passo; dove l’evento non arriva, il rosso segue i tempi calcolati.

Valori da cambiare

NomeFileDi partenzaCosa cambia
UNROLLscript.js0.8I secondi che il riquadro impiega a srotolarsi dal bordo sinistro.
FROMscript.js0.25Quanto del riquadro c’è già quando comincia a srotolarsi (da 0 a 1).
SHIFTscript.js40Da quanti pixel a sinistra arriva tutta la didascalia.
SLIDEscript.js2I secondi che ogni riga impiega a entrare dal bordo sinistro.
STAGGERscript.js0.2I secondi fra una riga e la successiva (tre quarti oltre quattro righe).
LEADscript.js0.4I secondi in cui una parola diventa rossa prima di essere letta, e torna nera dopo.
PACEscript.js1La velocità del narratore: 1 è il passo della voce registrata.
CALMscript.js15La velocità di scorrimento, in pixel al fotogramma, sotto la quale il narratore può cominciare.
WAITscript.js0.1I secondi di scorrimento calmo prima che il narratore legga la didascalia seguente.
ENTERscript.js62Dove arriva una didascalia: la sua altezza sullo schermo, dall’alto, in percentuale.
REPLAYscript.jstrueUna didascalia uscita dallo schermo si riavvolge e si rilegge quando torna.
BOILscript.js8Quante volte al secondo le incisioni cambiano disegno.
SPACINGscript.js4.2La distanza fra le linee delle incisioni, in pixel.
VOICEscript.js{ base: -0.036, perLetter: 0.076, shortest: 0.12, gap: 0.06, comma: 0.68, stop: 0.92, first: 0.23 }I tempi della voce, in secondi: la durata di una parola per lettera (perLetter, più base, mai sotto shortest), la pausa fra le parole, dopo le virgole e dopo i punti, e l’attesa prima della prima parola.

Provali nel Playground

Quando usarla

Per un racconto a pannelli: un fumetto, la storia di un marchio, una visita guidata, le didascalie di un video muto. Il narratore che aspetta funziona bene con didascalie brevi, di due o tre righe; le incisioni si possono sostituire con immagini vere senza toccare le didascalie.

Sul telefono

Le tavole diventano verticali (4:5) e le didascalie più strette, con lo stesso narratore e la stessa voce. Lo scorrimento col dito conta come quello della rotella: una spinta veloce mette il narratore in attesa finché la pagina non rallenta.

Con il movimento ridotto

Niente lettere che arrivano, niente riquadri che si srotolano e niente disegni che ribollono: le didascalie ci sono già e le tavole sono ferme. Il narratore legge lo stesso, perché il rosso che passa sulle parole cambia un colore, non muove niente.

Trappole

  • Se il testo si allargasse insieme al riquadro le lettere si schiaccerebbero: il riquadro si srotola con scaleX su un suo strato, e il testo si taglia con un clip-path che ne segue il bordo a ogni fotogramma.
  • Le righe si trovano dopo che il carattere è arrivato, perché con quello di riserva si va a capo in altri punti. Le parole restano gli stessi elementi e cambiano solo le righe che le contengono, così il rosso della lettura non si perde.
  • Calmo non vuol dire fermo: con una soglia a zero il narratore non partirebbe mai mentre si scorre piano per leggere. Conta la velocità in pixel al fotogramma, riportata a 60 fotogrammi al secondo.
  • In Safari la sintesi vocale parte solo dopo un gesto: il primo «Read aloud» è un clic, e da lì le letture partono anche dallo scorrimento. Con alcune voci Chrome non manda gli eventi boundary: per questo il rosso ha sempre anche i suoi tempi calcolati.
  • Le tre incisioni di una tavola si preparano una alla volta, un lavoro per giro di setTimeout, solo quando la tavola è vicina: tutte insieme fermerebbero la pagina per qualche decimo di secondo.

Librerie

GSAP 3.15.0, IM Fell English 5.3.0, Archivo (font variabile) 5.3.0.

Compressi con gzip, i tre file della demo pesano 16 KB; le librerie: GSAP + ScrollTrigger 45 KB.

Collaudo

Provata il 5 ottobre 2026

  • Computer: Fatto
  • Telefono: Fatto
  • Movimento ridotto: Fatto
  • Safari su iPhone: Fatto

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.

Tutte le animazioni