Vai al contenuto
animorio
EN
Torna alla libreria

La foto messa a fuoco

Immagini, HoverGSAP, CanvasImpegnativaPeso compresso: Demo 11 KBGSAP 28 KBGratisScarica lo zip

Nello stile minimal: una foto sfocata e un mirino sottile a croce che segue il puntatore su una molla. Intorno al mirino la foto va a fuoco a cerchi, il più nitido al centro; quando il mirino si ferma, la messa a fuoco va un filo oltre e torna, il mirino si stringe di un pixel e diventa arancione, e l’obiettivo si chiude scatto per scatto, da f/2.8 a f/8, mentre il numero sotto la foto perde peso.

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 photo brought into focus</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/roboto-flex@5.3.0/standard.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage" data-stage>
    <header class="top">
      <p class="mark">Vellum</p>
      <p class="title" data-title>Still life, north light</p>
    </header>

    <!-- the plate: the photo on a canvas, sharp only round the crosshair -->
    <figure class="plate" data-plate role="img" aria-label="Still life, north light">
      <canvas class="photo" data-photo aria-hidden="true"></canvas>
      <i class="tick tick--x" data-tick-x aria-hidden="true"></i>
      <i class="tick tick--y" data-tick-y aria-hidden="true"></i>
      <div class="cross" data-cross aria-hidden="true">
        <i class="arm arm--n" data-arm></i>
        <i class="arm arm--e" data-arm></i>
        <i class="arm arm--s" data-arm></i>
        <i class="arm arm--w" data-arm></i>
      </div>

      <figcaption class="read" aria-hidden="true">
        <span class="stop"><span class="stop__f" data-f>f/</span><span class="stop__n" data-stop>2.8</span></span>
        <span class="scale" data-scale>
          <i class="scale__mark" data-scale-mark></i>
        </span>
      </figcaption>
    </figure>
  </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 foto messa a fuoco» da Animorio e adattala al mio sito

Cosa fa

Una pagina nera, con in alto a sinistra il nome di uno studio di fotografia inventato, Vellum, e a destra il titolo della foto, Still life, north light, piccolo e grigio. Al centro una foto, fatta dallo script su una canvas: una natura morta davanti a un muro di lino, una bottiglia verde salvia rigata, una ciotola di terracotta con righe chiare dipinte, una tazza bianca con una fascia blu e un cartoncino stampato appoggiato al muro. La foto entra sfocata del tutto, e dal punto in cui guarda il mirino escono quattro righe sottili, una per lato, con un piccolo spazio vuoto in mezzo. Lì la foto va a fuoco: la nitidezza si allarga a cerchi, il più nitido al centro e poi anelli sempre più morbidi, e prima di fermarsi va un filo oltre e torna, come un obiettivo che cerca il fuoco. In quel momento il mirino si stringe di un pixel con un piccolo elastico e passa dal bianco all’arancione, e l’obiettivo si chiude uno scatto alla volta: f/4, f/5.6, f/8. A ogni scatto i cerchi nitidi crescono con una molla, il numero sotto la foto cambia allargandosi per un attimo e tornando, e diventa più sottile: il peso del numero dice quanta luce passa. A destra una scala coi sei diaframmi, da 2.8 a 16, e una tacca arancione che scivola su quello in uso. Due tacche piccole fuori dalla foto, sul bordo in alto e su quello a sinistra, dicono dov’è il fuoco. Muovendo il mouse sulla foto il mirino lo segue su una molla: mentre si muove l’obiettivo torna tutto aperto, f/2.8, e il fuoco si stringe in un cerchio piccolo; appena il mouse si ferma la messa a fuoco si assesta e l’obiettivo si richiude. Sul telefono il mirino segue il dito. Quando nessuno punta, il mirino gira da solo sulla ciotola, la tazza, la bottiglia e il cartoncino.

Come funziona

La sfocatura fatta una volta sola

All’inizio lo script disegna la foto sulla canvas alla misura dello schermo e ne fa cinque copie, dalla nitida alla più sfocata (BLUR pixel), con ctx.filter = 'blur()'. Intorno a ogni copia c’è una cornice della foto stessa stirata, così la sfocatura non tira dentro il nero della pagina. Ogni fotogramma non sfoca niente: mescola soltanto le cinque copie già pronte.

Il fuoco a cerchi

A ogni fotogramma la foto più sfocata copre tutta la canvas; sopra, dalla meno nitida alla più nitida, ogni copia viene incollata solo in un cerchio intorno al mirino, ritagliata con un gradiente radiale in destination-in che sfuma il bordo. I cerchi sono multipli del cerchio nitido (RINGS): la sfocatura cala ad anelli verso il centro. Si ridisegna solo quando il mirino o il cerchio sono cambiati.

Il mirino su una molla

Il mirino non va dove punta il mouse: ci arriva con una molla vera (SPRING, rigidità e freno), calcolata a passi piccoli dentro il ticker di GSAP. Con il freno poco sotto il critico arriva, passa di un pixel o due e si posa. Le quattro righe sono div di un pixel; GSAP non le tocca, il ticker scrive la loro posizione.

La messa a fuoco che si assesta

Il cerchio nitido dipende da due numeri: q, quanto è a fuoco, e s, il diaframma. Quando il mirino si ferma (o arriva su un punto del giro) una timeline porta q a 1,08, poi a 0,97 e infine a 1: la messa a fuoco va oltre e torna. Insieme pinch porta le righe un pixel più vicine con elastic.out e il colore passa all’accento; poi s sale di uno alla volta con back.out, uno scatto ogni 0,27 s, fino a REST_STOP. Il cerchio cresce di 2 alla s/4: un quarto di raddoppio a ogni scatto.

Il numero che perde peso

Il numero sotto la foto è in Roboto Flex, un carattere variabile. Il ticker scrive font-variation-settings a ogni fotogramma: wght va da 780 a f/2.8 a 230 a f/16, seguendo s. Quando il diaframma cambia, il testo cambia e wdth parte da 126 e torna a 100 con un elastico. Mentre il mirino corre, q scende a WIDE e s torna a zero: il numero conta all’indietro fino a 2.8 e torna pesante.

Valori da cambiare

NomeFileDi partenzaCosa cambia
IMAGEscript.js''La foto: un indirizzo, o un file caricato nel Playground. Vuoto, la foto la disegna lo script. La cornice prende le proporzioni della foto.
BLURscript.js14Quanto è sfocata la foto lontano dal mirino, in pixel.
FOCUSscript.js0.13Il cerchio nitido a obiettivo tutto aperto (f/2.8), come parte del lato corto della foto. Chiudendo il diaframma cresce.
REST_STOPscript.js8Fino a che diaframma si chiude l’obiettivo quando il mirino è fermo: 2.8, 4, 5.6, 8, 11 o 16. Più alto, più scatti e più foto a fuoco.
SPRINGscript.js[170, 22]La molla del mirino: quanto è rigida e quanto è frenata (meno freno, più oscilla).
POINTSscript.js[[0.56, 0.64], [0.75, 0.58], [0.34, 0.38], [0.2, 0.55]]I punti che il mirino visita da solo, come parti della larghezza e dell’altezza della foto. Con una foto tua vanno spostati sulle sue cose.
HOLDscript.js1.2Quanti secondi il mirino resta su ogni punto, a fuoco.
TOURscript.jstrueSe il mirino gira da solo quando nessuno punta. Con false resta sul primo punto finché non arriva il mouse o il dito.

Provali nel Playground

Quando usarla

Per una foto da guardare con calma: l’apertura del portfolio di un fotografo, la pagina di un prodotto da scoprire nei dettagli, la copertina di un reportage, la foto di un piatto o di una camera d’albergo, il sito di un negozio di fotocamere o di un corso di fotografia. Funziona con qualunque foto, anche caricata nel Playground.

Sul telefono

La stessa animazione con le misure adattate: la foto è larga quasi quanto lo schermo e un poco tagliata ai lati, il mirino è più piccolo e segue il dito; quattro secondi dopo che il dito si alza, il mirino riprende il suo giro.

Con il movimento ridotto

Niente si muove: la foto compare in dissolvenza già a fuoco sul primo punto, a f/8, col mirino arancione. Un clic o un tocco sposta il fuoco di colpo, senza molla né giro.

Trappole

  • Sulla ciotola di terracotta il mirino arancione quasi spariva: le righe hanno un velo d’ombra di un pixel (filter: drop-shadow sul contenitore del mirino) e il primo punto del giro sta sull’interno scuro dell’orlo, non sulle righe dipinte.
  • Quando il mouse se ne andava a pochi pixel da un punto del giro, il mirino ripartiva verso quello stesso punto: si sbloccava e si rimetteva a fuoco lì, fermo. Ora se è già vicino a un punto (un ottavo della foto) riparte verso il punto dopo.
  • Il numero si ingrandiva con una tween che aveva overwrite: true su tutto lo stato: uccideva anche la messa a fuoco e il diaframma. L’elastico del numero ha un oggetto suo.
  • Sul telefono una foto larga 3:2 diventava una striscia: lì la cornice si ferma a 1,25 e la foto è tagliata ai lati (cover). I punti del giro e il mirino sono parti della foto intera, non della cornice, così restano sulle stesse cose.
  • Il giro si ripete identico (fromTo fra punti fissi e repeat: -1), mai con valori letti al momento: così il video dell’anteprima capisce dove finisce un giro.

Librerie

GSAP 3.15.0, Roboto Flex (font variabile) 5.3.0.

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

Tutte le animazioni