Inizia a utilizzare le animazioni basate sullo scorrimento in CSS

1. Prima di iniziare

Le animazioni basate sullo scorrimento ti consentono di controllare la riproduzione di un'animazione in base alla posizione di scorrimento di un contenitore di scorrimento. Ciò significa che, mentre scorri verso l'alto o verso il basso, l'animazione scorre in avanti o indietro. Inoltre, con le animazioni basate sullo scorrimento puoi controllare un'animazione in base alla posizione di un elemento all'interno del relativo contenitore di scorrimento. In questo modo, puoi creare effetti interessanti come un'immagine di sfondo con parallasse, barre di avanzamento dello scorrimento e immagini che si rivelano man mano che vengono visualizzate.

La novità di Chrome 115 è il supporto di un insieme di classi JavaScript e proprietà CSS che consentono di creare facilmente animazioni dichiarative basate sullo scorrimento. Queste nuove API funzionano in combinazione con le API Web Animations e CSS Animations esistenti.

Questo codelab ti insegna a creare animazioni basate sullo scorrimento utilizzando i CSS. Completando questo codelab, acquisirai familiarità con le numerose nuove proprietà CSS introdotte da questa entusiasmante funzionalità, come scroll-timeline, view-timeline, animation-timeline e animation-range.

Obiettivi didattici

  • Come creare un effetto di parallasse dello sfondo con una sequenza temporale di scorrimento in CSS.
  • Come creare una barra di avanzamento con una sequenza temporale di scorrimento in CSS.
  • Come creare un effetto di rivelazione dell'immagine con una sequenza temporale di visualizzazione in CSS.
  • Come scegliere come target diversi tipi di intervalli di una cronologia delle visualizzazioni in CSS.

Che cosa ti serve

Una delle seguenti combinazioni di dispositivi:

  • Una versione recente di Chrome (115 o versioni successive) su ChromeOS, macOS o Windows con il flag "Funzionalità sperimentali della piattaforma web" impostato su attivato.
  • Conoscenza di base dell'HTML
  • Una conoscenza di base di CSS, in particolare delle animazioni in CSS

2. Configurazione

Tutto ciò che ti serve per questo progetto è disponibile in un repository GitHub. Per iniziare, clona il codice e aprilo nel tuo ambiente di sviluppo preferito.

  1. Apri una nuova scheda del browser e vai a https://github.com/googlechromelabs/io23-scroll-driven-animations-codelab.
  2. Clona il repository.
  3. Apri il codice nell'IDE che preferisci.
  4. Esegui npm install per installare le dipendenze.
  5. Esegui npm start e visita http://localhost:3000/.
  6. In alternativa, se non hai installato npm, apri il file src/index.html in Chrome.

3. Informazioni sulle tempistiche delle animazioni

Per impostazione predefinita, un'animazione allegata a un elemento viene eseguita nella sequenza temporale del documento. Ciò significa che quando la pagina viene caricata, l'animazione avanza con il passare del tempo. Questa è la sequenza temporale dell'animazione predefinita e, finora, era l'unica a cui avevi accesso.

Con le animazioni basate sullo scorrimento, hai accesso a due nuovi tipi di sequenze temporali:

  • Scorrere la cronologia di avanzamento
  • Visualizzare la cronologia dei progressi

In CSS, queste sequenze temporali possono essere associate a un'animazione utilizzando la proprietà animation-timeline. Scopri cosa significano queste nuove tempistiche e in che modo differiscono tra loro.

Scorrere la cronologia di avanzamento

Una sequenza temporale di avanzamento dello scorrimento è una sequenza temporale di animazione collegata all'avanzamento della posizione di scorrimento di un contenitore di scorrimento, chiamato anche area di scorrimento, lungo un determinato asse. Converte una posizione in un intervallo di scorrimento in una percentuale di avanzamento lungo una sequenza temporale.

La posizione di scorrimento iniziale rappresenta lo 0% di avanzamento, mentre quella finale il 100%. Nella visualizzazione seguente, nota che l'avanzamento aumenta dallo 0% al 100% man mano che scorri verso il basso il cursore.

Visualizzare la cronologia dei progressi

Questo tipo di sequenza temporale è collegato all'avanzamento relativo di un determinato elemento all'interno di un contenitore di scorrimento. Come in una cronologia di avanzamento dello scorrimento, viene monitorato l'offset di scorrimento di uno scroller. A differenza di una sequenza temporale di avanzamento dello scorrimento, è la posizione relativa di un soggetto all'interno dello scorrimento a determinare l'avanzamento. È paragonabile a IntersectionObserver, che monitora la visibilità di un elemento nel riquadro di scorrimento. Se l'elemento non è visibile nel cursore, non si interseca. Se è visibile all'interno dello scorrimento, anche per la parte più piccola, è in intersezione.

Una cronologia di avanzamento della visualizzazione inizia dal momento in cui un soggetto inizia a intersecarsi con lo scorrimento e termina quando il soggetto smette di intersecarsi con lo scorrimento. Nella visualizzazione seguente, tieni presente che l'avanzamento inizia a essere conteggiato da 0% quando il soggetto entra nel contenitore di scorrimento e raggiunge il 100% quando esce dal contenitore di scorrimento.

Per impostazione predefinita, un'animazione collegata alla sequenza temporale Visualizza avanzamento viene allegata all'intero intervallo. Inizia dal momento in cui il soggetto entra nel riquadro di scorrimento e termina quando il soggetto esce dal riquadro di scorrimento.

È anche possibile collegarlo a una parte specifica della sequenza temporale Visualizza avanzamento specificando l'intervallo a cui deve essere collegato. Ad esempio, solo quando il soggetto entra nello scorrimento. Nella visualizzazione seguente, il conteggio del progresso inizia da 0% quando il soggetto entra nel contenitore di scorrimento, ma raggiunge già il 100% dal momento in cui lo interseca completamente.

Gli intervalli di visualizzazione della sequenza temporale che puoi scegliere come target sono cover, contain, entry, exit, entry-crossing e exit-crossing. Questi intervalli verranno spiegati più avanti in questo codelab, ma se non riesci ad aspettare, utilizza lo strumento disponibile all'indirizzo https://goo.gle/view-timeline-range-tool per scoprire cosa rappresenta ogni intervallo.

4. Creare un effetto di sfondo parallasse

Il primo effetto da aggiungere alla pagina è un effetto di parallasse sullo sfondo dell'immagine di sfondo principale. Mentre scorri la pagina verso il basso, l'immagine di sfondo dovrebbe muoversi, anche se a una velocità diversa. Per questo, ti affidi a una cronologia di avanzamento dello scorrimento.

Per implementare questa funzionalità, devi eseguire due passaggi:

  1. Crea un'animazione che sposti la posizione dell'immagine di sfondo.
  2. Collega l'animazione alla progressione dello scorrimento del documento.

Crea l'animazione

  1. Per creare l'animazione, utilizza un insieme regolare di fotogrammi chiave. Sposta la posizione dello sfondo verticalmente dallo 0% al 100%:

src/styles.css

@keyframes move-background {
  from {
    background-position: 50% 0%;
  }
  to {
    background-position: 50% 100%;
  }
}
  1. Ora collega questi fotogrammi chiave all'elemento del corpo:

src/styles.css

body {
  animation: 1s linear move-background;
}

Con questo codice, l'animazione move-background viene aggiunta all'elemento body. La proprietà animation-duration è impostata su un secondo e utilizza una transizione linear.

Il modo più semplice per creare una sequenza temporale di avanzamento dello scorrimento è utilizzare la funzione scroll(). In questo modo viene creata una cronologia anonima dell'avanzamento dello scorrimento che puoi impostare come valore per la proprietà animation-timeline.

La funzione scroll() accetta un argomento <scroller> e un argomento <axis>.

I valori accettati per l'argomento <scroller> sono i seguenti:

  • nearest. Utilizza il contenitore di scorrimento principale più vicino (impostazione predefinita).
  • root. Utilizza la finestra del documento come contenitore di scorrimento.
  • self. Utilizza l'elemento stesso come contenitore di scorrimento.

I valori accettati per l'argomento <axis> sono i seguenti:

  • block. Utilizza la misura del progresso lungo l'asse del blocco del contenitore di scorrimento (impostazione predefinita).
  • inline. Utilizza la misura dell'avanzamento lungo l'asse in linea del contenitore di scorrimento.
  • y. Utilizza la misura dell'avanzamento lungo l'asse Y del contenitore di scorrimento.
  • x. Utilizza la misura dell'avanzamento lungo l'asse X del contenitore di scorrimento.

Per collegare l'animazione allo scroller principale sull'asse del blocco, i valori da passare a scroll() sono root e block. Il valore totale è scroll(root block).

  • Imposta scroll(root block) come valore per la proprietà animation-timeline nel corpo.
  • Inoltre, poiché un animation-duration espresso in secondi non ha senso, imposta la durata su auto. Se non specifichi un animation-duration, il valore predefinito sarà auto.

src/styles.css

body {
  animation: linear move-background;
  animation-duration: auto;
  animation-timeline: scroll(root block);
}

Poiché lo scroller principale è anche lo scroller principale più vicino per l'elemento body, puoi utilizzare anche il valore nearest:

src/styles.css

body {
  animation: linear move-background;
  animation-duration: auto;
  animation-timeline: scroll(nearest block);
}

Poiché nearest e block sono i valori predefiniti, puoi anche scegliere di ometterli. In questo caso, il codice può essere semplificato come segue:

src/styles.css

body {
  animation: linear move-background;
  animation-duration: auto;
  animation-timeline: scroll();
}

Verificare le modifiche

Se tutto è andato bene, ora dovresti avere questo:

In caso contrario, controlla il ramo solution-step-1 del codice.

5. Creare una barra di avanzamento per la galleria di immagini

Nella pagina è presente un carosello orizzontale che necessita di una barra di avanzamento per indicare la foto che stai visualizzando.

Il markup per il carosello ha il seguente aspetto:

src/index.html

<div class="gallery">
  <div class="gallery__scrollcontainer" style="--num-images: 3;">
    <div class="gallery__progress"></div>
    <div class="gallery__entry">
      ...
    </div>
    <div class="gallery__entry">
      ...
    </div>
    <div class="gallery__entry">
      ...
    </div>
  </div>
</div>

I fotogrammi chiave per la barra di avanzamento sono già in posizione e hanno il seguente aspetto:

src/styles.css

@keyframes adjust-progress {
  from {
    transform: scaleX(calc(1 / var(--num-images)));
  }
  to {
    transform: scaleX(1);
  }
}

Questa animazione deve essere allegata al file .Elemento gallery__progress con una sequenza temporale di avanzamento dello scorrimento. Come mostrato nel passaggio precedente, puoi farlo creando una sequenza temporale anonima di avanzamento dello scorrimento con la funzione scroll():

src/styles.css

.gallery__progress {
  animation: linear adjust-progress;
  animation-duration: auto;
  animation-timeline: scroll(nearest inline);
}

Sebbene questo frammento di codice possa sembrare funzionante, non lo è a causa del funzionamento delle ricerche automatiche dei contenitori di scorrimento tramite nearest. Quando cerca lo scroller più vicino, l'elemento prende in considerazione solo gli elementi che possono influire sulla sua posizione. Poiché .gallery__progress è posizionato in modo assoluto, il primo elemento padre che ne determinerà la posizione è l'elemento .gallery, a cui è applicato position: relative. Ciò significa che l'elemento .gallery__scrollcontainer, ovvero lo scorrimento da selezionare, non viene preso in considerazione durante questa ricerca automatica.

Per risolvere il problema, crea una sequenza temporale di avanzamento dello scorrimento denominata nell'elemento .gallery__scrollcontainer e collega .gallery__progress a quest'ultima utilizzando il nome.

Per creare una sequenza temporale di avanzamento dello scorrimento denominata su un elemento, imposta la proprietà CSS scroll-timeline-name sul contenitore di scorrimento su un valore a tua scelta. Il valore deve iniziare con --.

Poiché la galleria scorre orizzontalmente, devi impostare anche la proprietà scroll-timeline-axis. I valori consentiti sono gli stessi dell'argomento <axis> di scroll().

Infine, per collegare l'animazione alla sequenza temporale di avanzamento dello scorrimento, imposta la proprietà animation-timeline sull'elemento da animare sullo stesso valore dell'identificatore utilizzato per scroll-timeline-name.

  • Modifica il file styles.css per includere quanto segue:

src/styles.css

.gallery__scrollcontainer {
  /* Create the gallery-is-scrolling timeline */
  scroll-timeline-name: --gallery-is-scrolling;
  scroll-timeline-axis: inline;
}

.gallery__progress {
  animation: linear adjust-progress;
  animation-duration: auto;
  /* Set gallery-is-scrolling as the timeline */
  animation-timeline: --gallery-is-scrolling;
}

Verificare le modifiche

Se tutto è andato bene, ora dovresti avere questo:

In caso contrario, controlla il ramo solution-step-2 del codice.

6. Animare le immagini della galleria quando entrano ed escono dalla finestra di visualizzazione

Configurare una cronologia dei progressi di visualizzazione anonima

Un bell'effetto da aggiungere è la dissolvenza in entrata delle immagini della galleria quando vengono visualizzate. A questo scopo, puoi utilizzare una sequenza temporale di visualizzazione dell'avanzamento.

Per creare una cronologia Visualizza avanzamento, puoi utilizzare la funzione view(). Gli argomenti accettati sono <axis> e <view-timeline-inset>.

  • <axis> è uguale a quello della sequenza temporale di avanzamento dello scorrimento e definisce l'asse da monitorare.
  • Con <view-timeline-inset>, puoi specificare un offset (positivo o negativo) per regolare i limiti quando un elemento viene considerato in visualizzazione o meno.
  • I fotogrammi chiave sono già presenti, quindi devi solo allegarli. A questo scopo, crea una cronologia dell'avanzamento su ogni elemento .gallery__entry.

src/styles.css

@keyframes animate-in {
  from {
    opacity: 0;
    clip-path: inset(50% 0% 50% 0%);
  }
  to {
    opacity: 1;
    clip-path: inset(0% 0% 0% 0%);
  }
}

.gallery__entry {
  animation: linear animate-in;
  animation-duration: auto;
  animation-timeline: view(inline);
}

Limitare l'intervallo di una cronologia dello stato di visualizzazione

Se salvi il CSS e carichi la pagina, gli elementi vengono visualizzati in dissolvenza in entrata, ma qualcosa non va. Iniziano con un'opacità di 0 quando sono completamente fuori dalla visualizzazione e terminano con un'opacità di 1 solo quando sono usciti completamente.

Questo perché l'intervallo predefinito per una sequenza temporale di visualizzazione dell'avanzamento è l'intervallo completo. Questo è noto come intervallo cover.

  1. Per scegliere come target solo l'intervallo entry del soggetto, utilizza la proprietà CSS animation-range per limitare l'esecuzione dell'animazione.

src/styles.css

.gallery__entry {
  animation: linear fade-in;
  animation-duration: auto;
  animation-timeline: view(inline);
  animation-range: entry 0% entry 100%;
}

L'animazione ora viene eseguita da entry 0% (il soggetto sta per entrare nello scroller) a entry 100% (il soggetto è entrato completamente nello scroller).

I possibili intervalli di visualizzazione della cronologia sono i seguenti:

  • cover. Rappresenta l'intera gamma della sequenza temporale dei progressi di visualizzazione.
  • entry. Rappresenta l'intervallo durante il quale la casella principale entra nell'intervallo di visibilità dell'avanzamento della visualizzazione.
  • exit. Rappresenta l'intervallo durante il quale la casella principale esce dall'intervallo di visibilità dell'avanzamento della visualizzazione.
  • entry-crossing. Rappresenta l'intervallo durante il quale la scatola principale attraversa il bordo finale.
  • exit-crossing. Rappresenta l'intervallo durante il quale il riquadro principale attraversa il bordo iniziale.
  • contain. Rappresenta l'intervallo durante il quale la casella principale è completamente contenuta o copre completamente il suo intervallo di visibilità dell'avanzamento della visualizzazione all'interno della finestra di visualizzazione. Dipende se il soggetto è più alto o più basso dello scorrimento.

Utilizza lo strumento disponibile all'indirizzo https://goo.gle/view-timeline-range-tool per vedere cosa rappresenta ogni intervallo e in che modo le percentuali influiscono sulle posizioni di inizio e fine.

  1. Poiché gli intervalli di inizio e fine sono gli stessi e vengono utilizzati gli offset predefiniti, semplifica animation-range in un unico nome di intervallo di animazione:

src/styles.css

.gallery__entry {
  animation: linear animate-in;
  animation-duration: auto;
  animation-timeline: view(inline);
  animation-range: entry;
}
  • Per dissolvere le immagini mentre escono dallo scorrimento, puoi fare la stessa cosa dell'animazione di entrata, ma scegliendo un intervallo diverso.

src/styles.css

@keyframes animate-out {
  from {
    opacity: 1;
    clip-path: inset(0% 0% 0% 0%);
  }
  to {
    opacity: 0;
    clip-path: inset(50% 0% 50% 0%);
  }
}

.gallery__entry {
  animation: linear animate-in, linear animate-out;
  animation-duration: auto;
  animation-timeline: view(inline);
  animation-range: entry, exit;
}

I fotogrammi chiave animate-in verranno applicati all'intervallo entry e i fotogrammi chiave animate-out all'intervallo exit.

Verificare le modifiche

Se tutto è andato bene, ora dovresti avere questo:

In caso contrario, controlla il ramo solution-step-3 del codice.

7. Anima le immagini della galleria quando entrano ed escono dalla finestra di visualizzazione, utilizzando un set di fotogrammi chiave

Il caso di un solo set di fotogrammi chiave

Anziché allegare due animazioni a intervalli diversi, è possibile creare un set di fotogrammi chiave che contenga già le informazioni sull'intervallo.

La forma dei fotogrammi chiave è la seguente:

@keyframes keyframes-name {
  range-name range-offset {
    ...
  }
  range-name range-offset {
    ...
  }
}
  1. Combina i fotogrammi chiave di dissolvenza in entrata e in uscita in questo modo:

src/styles.css

@keyframes animate-in-and-out {
  entry 0% {
    opacity: 0;
    clip-path: inset(50% 0% 50% 0%);
  }
  entry 90% {
    opacity: 1;
    clip-path: inset(0% 0% 0% 0%);
  }

  exit 10% {
    opacity: 1;
    clip-path: inset(0% 0% 0% 0%);
  }
  exit 100% {
    opacity: 0;
    clip-path: inset(50% 0% 50% 0%);
  }
}
  1. Quando le informazioni sull'intervallo sono presenti nei fotogrammi chiave, non è più necessario specificare separatamente animation-range. Allega i fotogrammi chiave come proprietà animation.

src/styles.css

.gallery__entry {
  animation: linear animate-in-and-out both;
  animation-duration: auto;
  animation-timeline: view(inline);
}

Verificare le modifiche

Se tutto è andato bene, dovresti ottenere lo stesso risultato del passaggio precedente. In caso contrario, controlla il ramo solution-step-4 del codice.

8. Complimenti!

Hai completato questo codelab e ora sai come creare le sequenze temporali di avanzamento dello scorrimento e le sequenze temporali di avanzamento della visualizzazione in CSS.

Scopri di più

Risorse: