Vai al contenuto
animorio
EN
Tutti i componenti

La fisarmonica del punto interrogativo

Fisarmoniche, SVG, FisicaGSAPImpegnativaPeso compresso: Demo 8,7 KBGSAP 28 KBGratisScarica lo zip

Le domande di un abbonamento a rompicapi per posta, ognuna con un punto interrogativo a matita nel margine. Aprendone una, il punto interrogativo si raddrizza in un punto esclamativo d’inchiostro: il ricciolo si stende, il punto cade come un peso e tira giù la risposta, le domande sotto scendono con lui e lui atterra schiacciandosi con un piccolo rimbalzo. Richiusa, il tratto risale e si arriccia di nuovo in una domanda.

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 question-mark accordion</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/schibsted-grotesk@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the questions of a puzzles-by-post subscription, one answer open at a time. In the margin of each question a
         pencil question mark; opening it, the question mark straightens into an exclamation mark in ink, its dot drops
         like a weight and pulls the answer open, and the questions below ride down on it. The marks are drawn by the
         script -->
    <div class="faq" data-faq>
      <div class="faq__item" data-item>
        <h3 class="faq__head"><button class="faq__q" type="button" id="faq-q1" aria-expanded="false" aria-controls="faq-a1"><span class="faq__text">When does a new puzzle arrive?</span></button></h3>
        <div class="faq__a" id="faq-a1" role="region" aria-labelledby="faq-q1" hidden><div class="faq__inner"><p>Every other Friday, in a flat envelope that fits any letterbox: one big puzzle for the weekend and three small ones for the week.</p></div></div>
        <svg class="faq__mark" aria-hidden="true" focusable="false"><g><path class="faq__stroke"/><rect class="faq__dot"/></g></svg>
      </div>
      <div class="faq__item" data-item>
        <h3 class="faq__head"><button class="faq__q" type="button" id="faq-q2" aria-expanded="false" aria-controls="faq-a2"><span class="faq__text">What if I get stuck?</span></button></h3>
        <div class="faq__a" id="faq-a2" role="region" aria-labelledby="faq-q2" hidden><div class="faq__inner"><p>Every puzzle comes with three sealed hints, each a little less subtle than the last. Open them in order, or hold out: the solutions arrive with the next pack.</p></div></div>
        <svg class="faq__mark" aria-hidden="true" focusable="false"><g><path class="faq__stroke"/><rect class="faq__dot"/></g></svg>
      </div>
      <div class="faq__item" data-item>
        <h3 class="faq__head"><button class="faq__q" type="button" id="faq-q3" aria-expanded="false" aria-controls="faq-a3"><span class="faq__text">How hard are the puzzles?</span></button></h3>
        <div class="faq__a" id="faq-a3" role="region" aria-labelledby="faq-q3" hidden><div class="faq__inner"><p>Each pack starts gentle and ends tough. Most people crack the big one in an evening, alone or round a table with friends.</p></div></div>
        <svg class="faq__mark" aria-hidden="true" focusable="false"><g><path class="faq__stroke"/><rect class="faq__dot"/></g></svg>
      </div>
      <div class="faq__item" data-item>
        <h3 class="faq__head"><button class="faq__q" type="button" id="faq-q4" aria-expanded="false" aria-controls="faq-a4"><span class="faq__text">Can I pause my subscription?</span></button></h3>
        <div class="faq__a" id="faq-a4" role="region" aria-labelledby="faq-q4" hidden><div class="faq__inner"><p>Yes, for up to three months, from your account page. Paused packs are never charged, and you can start again whenever you like.</p></div></div>
        <svg class="faq__mark" aria-hidden="true" focusable="false"><g><path class="faq__stroke"/><rect class="faq__dot"/></g></svg>
      </div>
      <div class="faq__item" data-item>
        <h3 class="faq__head"><button class="faq__q" type="button" id="faq-q5" aria-expanded="false" aria-controls="faq-a5"><span class="faq__text">Can I give it as a gift?</span></button></h3>
        <div class="faq__a" id="faq-a5" role="region" aria-labelledby="faq-q5" hidden><div class="faq__inner"><p>Choose three, six or twelve packs and add a note. The first one goes out in a plain envelope, so the surprise holds.</p></div></div>
        <svg class="faq__mark" aria-hidden="true" focusable="false"><g><path class="faq__stroke"/><rect class="faq__dot"/></g></svg>
      </div>
    </div>
  </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.

24 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 fisarmonica del punto interrogativo» da Animorio e adattala al mio sito

Cosa fa

Su un fondo bianco, da sola al centro, una lista di cinque domande separate da righe sottili: When does a new puzzle arrive?, What if I get stuck?, How hard are the puzzles?, Can I pause my subscription?, Can I give it as a gift?. Nel margine a destra di ognuna c’è un grande punto interrogativo grigio, come scritto a matita. All’arrivo i punti interrogativi si scrivono uno dopo l’altro, dalla punta del ricciolo giù fino al gambo, e il loro punto compare con un piccolo scatto; poi si apre la seconda domanda. Aprendo una domanda il suo punto interrogativo si raddrizza: il ricciolo si stende verso l’alto mentre il colore passa dal grigio matita al blu inchiostro, il punto si stacca e cade con la gravità, tirando giù la risposta, che si scopre riga per riga mentre lui ci passa accanto; le domande sotto scendono con lui. Il punto atterra sulla linea di base dell’ultima riga della risposta, si schiaccia e fa un piccolo rimbalzo, che le domande sotto seguono; resta un punto esclamativo alto quanto la domanda e la sua risposta, largo in cima e sottile vicino al punto. Mentre cade, il tratto si assottiglia un poco, come tirato. Aprendone un’altra, quella aperta si richiude nello stesso momento: il tratto risale come un metro che si riavvolge, il ricciolo si riforma quando il gambo è ancora lungo, come un bastone da passeggio, e si arriccia un filo oltre la sua forma prima di posarsi. Sotto il mouse, o col fuoco della tastiera, un punto interrogativo si inclina verso la domanda, curioso, e si scurisce; premuto, si schiaccia.

Come funziona

Un punto interrogativo fatto di angoli

La linea del punto interrogativo, una curva di Bézier che dal gambo entra in un arco di cerchio di 202 gradi, è ricampionata in 40 passi uguali, e di ogni passo si tiene solo la direzione. Si disegna a ogni fotogramma partendo dal fondo del gambo e salendo un passo alla volta: così la forma non è un disegno fisso ma una lista di angoli da cui ricostruirla.

Raddrizzarsi

Per raddrizzarlo, ogni direzione si avvicina alla verticale moltiplicando il suo scarto per (1 − p), e il ricciolo si accorcia da 33,8 a 16 unità: a p = 1 la linea è dritta e arriva in cima alla scatola. p sta su una molla svelta (STRAIGHTEN) quando si apre e su una più lenta e più elastica quando si chiude, che riporta il ricciolo un poco oltre la sua forma. Il tratto non è uno stroke ma una forma piena con una larghezza in ogni punto: uguale lungo il punto interrogativo, a cuneo nel punto esclamativo (0,62 tratti vicino al punto, 1,45 in cima), e più sottile quando cade veloce.

Il punto che cade

Aprendo, il punto parte con una spinta di 280 pixel al secondo e accelera con GRAVITY; quando arriva all’altezza della risposta rimbalza con una parte della sua velocità (BOUNCE) e si schiaccia dal fondo, su una molla che lo fa tornare quadrato. L’altezza della risposta è proprio la sua caduta: la risposta si apre dall’alto riga per riga e le domande sotto, che stanno nel flusso normale della pagina, scendono e rimbalzano con lui senza mai sovrapporsi. I conti si fanno a passi di 1/240 di secondo, col fotogramma limitato a 1/30.

Sulla linea di base

Il punto atterra sulla linea di base dell’ultima riga della risposta, non sul suo bordo: la linea si misura con una sonda di misura zero, uno span inline-block aggiunto in fondo al testo e tolto subito, e il punto scende in proporzione alla risposta, così arriva lì quando lei è tutta aperta. Le misure si rifanno quando cambia la larghezza e quando arrivano i caratteri.

Chiudere, tastiera e riposo

Chiudendo, la risposta torna a zero su una molla senza rimbalzo (FOLD), il testo svanisce in 0,14 secondi e sotto il mezzo pixel la risposta torna hidden. Le domande sono button dentro un h3 con aria-expanded e aria-controls, le risposte regioni con aria-labelledby; frecce, Home e End passano da una domanda all’altra, e l’anello del fuoco abbraccia la domanda. Il colore dei segni è un color-mix in CSS fra matita, inchiostro e nero, guidato da due variabili che lo script scrive. Il ciclo gira sul ticker di GSAP solo mentre qualcosa si muove; la lista ha un’altezza fissa, così la sua cima non si sposta mai. La domanda dopo quella aperta ha data-autoclic per l’anteprima.

Valori da cambiare

NomeFileDi partenzaCosa cambia
FIRSTscript.js1La domanda aperta all’apertura della pagina, da 0; −1 per nessuna.
ONLY_ONEscript.jstrueAprendo una domanda si chiude quella aperta; con false se ne possono aprire tante.
GRAVITYscript.js5200Quanto forte cade il punto, in pixel al secondo al quadrato: più è alta, più la risposta si apre in fretta.
BOUNCEscript.js0.3Quanto rimbalza il punto quando atterra, come parte della sua velocità (0 per niente).
STRAIGHTENscript.js0.22I secondi che il punto interrogativo ci mette a raddrizzarsi (per riarricciarsi quasi il doppio).
FOLDscript.js0.32I secondi di una risposta che si richiude.
TILTscript.js12Quanto si inclina un punto interrogativo sotto il mouse, in gradi; 0 per niente.
STROKEscript.js4Lo spessore dei segni, in pixel.

Provali nel Playground

Quando usarla

Per le domande frequenti di un servizio, di un abbonamento, di un gioco o di un evento, dove il sito ha un tono vivace e un po’ spiritoso: il punto esclamativo nel margine dice da lontano quale risposta è aperta e quanto è lunga, e la domanda che trova la sua risposta si vede.

Sul telefono

La lista è larga al massimo 560 pixel e sul telefono si stringe allo schermo, con 16 pixel di margine per lato (358 su un telefono di 390). Le righe chiuse sono alte 76 pixel sul computer e 64 sul telefono, le domande scendono a 18 pixel e i segni a 28 pixel d’altezza, in un margine di 48. I tocchi aprono e chiudono come i clic, e un dito che preme una domanda schiaccia il suo punto interrogativo.

Con il movimento ridotto

Niente caduta, niente rimbalzi e niente inclinazioni: la risposta si apre e si chiude di colpo, il punto interrogativo diventa subito punto esclamativo e il testo della risposta compare in dissolvenza. All’apertura la lista compare in dissolvenza con la seconda domanda già aperta; sotto il mouse il segno si scurisce soltanto.

Trappole

  • La prima versione spostava solo il fondo del gambo: tutto il segno scivolava giù intero, con un punto esclamativo corto in fondo alla risposta. Il tratto dritto del gambo deve allungarsi quanto la caduta, così la cima resta accanto alla domanda.
  • Raddrizzato, il punto esclamativo pendeva di tredici gradi: la direzione del primo passo della curva non è proprio verticale, perché la Bézier gira subito verso destra. Il riferimento ora è la verticale esatta, non il primo passo.
  • Una linea lunga e uniforme con un puntino in fondo si leggeva come una barra di scorrimento, non come un punto esclamativo. È diventata un cuneo, largo in cima e sottile vicino al punto, e il punto cresce del 30 per cento.
  • Atterrando sul bordo della risposta il punto finiva una quindicina di pixel sotto l’ultima riga, sul suo margine: ora atterra sulla linea di base, misurata con una sonda, e la caduta del segno è in proporzione a quella della risposta.
  • La gravità parte da velocità zero, cioè come un ease-in: nei primi fotogrammi non si muoveva quasi niente e il clic sembrava in ritardo. Il punto parte con una spinta di 280 pixel al secondo.
  • Chiudendo una domanda col mouse sopra, il segno si inclinava subito mentre il gambo era ancora lungo, e la sua cima spazzava di lato. Ora si inclina solo quando è di nuovo un punto interrogativo corto.
  • Una molla senza rimbalzo arriva a zero molto lentamente: la risposta chiusa restava visibile ai lettori di schermo per quasi un secondo. Sotto il mezzo pixel si chiude di colpo e torna hidden.
  • L’anello del fuoco intorno a tutto il pulsante usciva dalla lista e toccava la risposta sotto: ora abbraccia solo il testo della domanda, e il punto interrogativo si inclina come sotto il mouse.

Librerie

GSAP 3.15.0, Schibsted Grotesk (font variabile) 5.3.0.

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