Vai al contenuto
animorio
EN
Torna alla libreria

La sfera a retino

WebGL, 3DGSAP, WebGL, CanvasMediaPeso compresso: Demo 6,5 KBGSAP 28 KBGratisScarica lo zip

Animazione WebGL in stile minimal: una sola sfera disegnata a un bit, con punti d'inchiostro quadrati come un retino da giornale, illuminata da una luce che segue il puntatore. Paralleli e meridiani girano adagio, l'ombra scivola via dalla luce e solo il riflesso prende il blu.

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>Nadir</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>
  <!-- one sphere drawn in one bit: a WebGL shader lights it like a ball and an 8x8 Bayer matrix turns the light into
       big square dots of ink; the light follows the pointer, and when nobody moves it, it walks around the sphere -->
  <main class="pagina" data-pagina>
    <canvas class="tela" aria-hidden="true" data-tela></canvas>

    <header class="testa">
      <p class="marchio" data-entra>Nadir</p>
      <p class="testa__nota" data-entra>A study of light</p>
    </header>

    <p class="nota" data-entra data-nota>Move the light</p>
  </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.

16 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 sfera a retino» da Animorio e adattala al mio sito

Cosa fa

Su un foglio bianco caldo, al centro, c'è una sola sfera fatta di punti quadrati d'inchiostro, tutti uguali, come il retino di una foto stampata su un giornale: dove la sfera è in luce i punti si diradano, dove è in ombra si fanno fitti fino al nero pieno. All'apertura la sfera si sviluppa dal foglio come una stampa, i grigi scendono dal bianco e il raggio si posa con un filo di troppo; poi compaiono il nome, Nadir, e due righe piccole. La luce sta davanti alla sfera e la segue il puntatore: spostandolo, la parte chiara gira, il lato in ombra si allarga dall'altra parte e il riflesso, l'unico punto blu della pagina, scivola sulla superficie. Sulla sfera il retino disegna paralleli e meridiani sottili, scuri dove c'è luce e chiari dove c'è ombra, che ruotano adagio come un globo; sotto, sul piano, l'ombra ovale della sfera si sposta dalla parte opposta alla luce. La sfera respira appena, di forma e non di luce. Quando nessuno muove il puntatore, la luce torna da sola a girare intorno alla sfera in un giro di quattordici secondi che ricomincia uguale.

Come funziona

Un quadrato e uno shader

Tutta la pagina è un canvas WebGL con un solo quadrato che la copre (due triangoli in TRIANGLE_STRIP) e un fragment shader che decide il colore di ogni pixel. Il pixel non si calcola per sé: si arrotonda alla sua cella del retino, floor(gl_FragCoord.xy / u_dot), e si fa il conto al centro della cella. Così tutti i pixel di una cella escono uguali e i punti del retino sono quadrati grandi DOT pixel CSS, anche con il devicePixelRatio a 2.

La luce della palla

Nella cella si guarda la distanza dal centro della sfera in raggi: se è meno di uno, la normale della superficie è (x, y, radice di 1 meno x² meno y²). La luce è una direzione: il puntatore dà x e y in raggi della sfera e LIGHT_HEIGHT dà la z. La luce di Lambert è il prodotto scalare fra normale e luce, il riflesso è quello di Blinn-Phong, la normale contro la metà fra luce e occhio elevata a SHINE. Il grigio è un numero da 0 (nero) a 1 (carta).

Un bit con la matrice di Bayer

Il grigio diventa un punto sì o un punto no confrontandolo con una soglia che cambia da cella a cella secondo la matrice di Bayer 8x8, calcolata nello shader con una formula ricorsiva: bayer2 su a.x e a.y, poi bayer4 e bayer8 che sommano la stessa formula a metà scala. Con 64 soglie diverse un grigio medio diventa una scacchiera, uno chiaro un punto ogni tanto. Il riflesso più forte, sopra una soglia sua, diventa blu invece che carta.

Il globo e l'ombra

La normale si gira intorno all'asse verticale di un angolo che cresce col giro, e se ne prendono longitudine e latitudine: dove una delle due cade vicino a un multiplo intero c'è un filo. Il filo scurisce il grigio dove la sfera è in luce e lo schiarisce dove è in ombra, così si vede da tutte e due le parti. Fuori dalla sfera c'è un'ellisse schiacciata sotto di lei, spostata dalla parte opposta alla luce, che scurisce il foglio con una curva morbida: anche l'ombra passa dal retino.

La regia

Un oggetto di numeri, fase e nasce, è animato da GSAP: fase va da 0 a 1 in LIGHT_SPEED secondi in una timeline che si ripete, e da lì vengono il giro della luce quando nessuno muove il puntatore, la rotazione dei meridiani e il respiro del raggio, tutti con periodi che tornano interi. La luce vera insegue il suo punto con una molla misurata sul ticker di GSAP; dopo 2,4 secondi senza puntatore torna sul giro. Un IntersectionObserver spegne tutto quando la pagina non si vede. Senza WebGL lo stesso conto si fa in JavaScript su un canvas 2D.

Valori da cambiare

NomeFileDi partenzaCosa cambia
DOTscript.js4Il lato di un punto del retino, in px: più grande, più si vede la grana.
BAYER_SIZEscript.js8La matrice di Bayer, 2, 4 o 8: più grande, più toni di grigio.
RADIUSscript.js0.3Il raggio della sfera, in parte del lato più corto della pagina.
LIGHT_SPEEDscript.js14In quanti secondi la luce fa un giro intero da sola.
LIGHT_HEIGHTscript.js0.9Quanto la luce sta davanti alla sfera: più alta, meno ombra.
SHINEscript.js26Quanto è stretto il riflesso blu: più alto, più piccolo.
LINESscript.js12Quanti meridiani (i paralleli sono la metà).
BREATHscript.js0.012Quanto respira il raggio della sfera.
SHADOWscript.js0.5Quanto è scura l'ombra sotto la sfera.

Provali nel Playground

Quando usarla

Come apertura di un osservatorio, di un laboratorio, di uno studio di fotografia o di stampa, di un prodotto che parla di luce, di energia o di spazio; come pagina d'ingresso di un'app di dati o di uno strumento per sviluppatori quando si vuole un'immagine forte fatta con pochissimo; come fondo di una pagina di una conferenza sulla grafica.

Sul telefono

La stessa animazione: la sfera si misura sul lato più corto (un poco più grande negli schermi stretti), il dito che tocca e trascina muove la luce, e appena lo si alza la luce torna sul suo giro.

Con il movimento ridotto

La sfera è già sviluppata e ferma, con la luce in alto a sinistra: niente giro, niente respiro, niente meridiani che ruotano. Il nome e le righe piccole compaiono in dissolvenza.

Trappole

  • Il retino si calcola per cella e non per pixel: arrotondando gl_FragCoord alla cella e facendo il conto al centro, ogni punto è un quadrato pieno. Facendo il conto pixel per pixel i bordi dei punti si sfrangiano e il retino sembra rumore.
  • La matrice di Bayer non ha bisogno di una texture: la formula ricorsiva di bayer2, bayer4 e bayer8 si scrive in tre righe di GLSL e funziona anche in WebGL 1, dove gli array con indici variabili sono scomodi.
  • I meridiani scuri sul lato in ombra non si vedevano: lì il retino è già quasi nero. Ora il filo scurisce dove c'è luce e schiarisce dove c'è ombra, con una sfumatura in mezzo.
  • L'ombra con un bordo netto sembrava un tappeto: ora scende con una curva morbida (smoothstep) e il retino ne fa una sfumatura di punti.
  • L'entrata usa back.out, che porta il numero dell'entrata un poco oltre 1: il raggio fa l'overshoot che si vuole, ma il grigio va tenuto fermo a 1 con min(), altrimenti per un attimo la sfera diventa più scura.
  • Il canvas si ridimensiona a ogni resize, anche a metà giro, con il devicePixelRatio limitato a 2: la cella del retino si moltiplica per lo stesso numero, così i punti restano grandi uguali in pixel CSS.

Librerie

GSAP 3.15.0, Jost (font variabile) 5.3.0.

Compressi con gzip, i tre file della demo pesano 6,5 KB; le librerie: GSAP 28 KB.

Collaudo

Provata il 21 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.

Tutte le animazioni