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 scorrevole. Ciò significa che, mentre scorri verso l'alto o verso il basso, l'animazione viene riprodotta avanti o indietro. Inoltre, con le animazioni basate sullo scorrimento puoi anche 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.
Una novità di Chrome 115 è il supporto di un insieme di classi JavaScript e proprietà CSS che ti 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 il CSS. Completando questo codelab, acquisirai familiarità con le numerose nuove proprietà CSS introdotte da questa interessante funzionalità, come scroll-timeline
, view-timeline
, animation-timeline
e animation-range
.
Obiettivi didattici
- Come creare un effetto di sfondo con parallasse 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 visualizzazione di un'immagine con una sequenza temporale della 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 successive) su ChromeOS, macOS o Windows con l'opzione "Funzionalità sperimentali della piattaforma web" impostata su Abilitato.
- Conoscenza di base dell'HTML
- Conoscenza di base del 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.
- Apri una nuova scheda del browser e vai alla pagina https://github.com/googlechromelabs/io23-scroll-driven-animations-codelab.
- Clona il repository.
- Apri il codice nell'IDE che preferisci.
- Esegui
npm install
per installare le dipendenze. - Esegui
npm start
e visita la pagina http://localhost:3000/. - 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 associata 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. Si tratta della sequenza temporale di animazione predefinita e, finora, era l'unica a cui avevi accesso.
Con le animazioni basate sullo scorrimento, puoi accedere a due nuovi tipi di schemi temporali:
- Scorrere la cronologia dell'avanzamento
- Visualizza cronologia avanzamento
In CSS, queste tracce temporali possono essere associate a un'animazione utilizzando la proprietà animation-timeline
. Dai un'occhiata al significato di queste nuove tempistiche e a come differiscono tra loro.
Scorrere la cronologia dell'avanzamento
Una sequenza temporale di avanzamento dello scorrimento è una sequenza temporale dell'animazione collegata all'avanzamento della posizione di scorrimento di un contenitore di scorrimento, chiamato anche scrollport o scroller, 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 stato di avanzamento pari allo 0%, mentre la posizione di scorrimento finale rappresenta lo stato di avanzamento pari al 100%. Nella seguente visualizzazione, tieni presente che l'avanzamento viene conteggiato dal 0% al 100% mentre scorri verso il basso lo scorrevole.
Visualizza sequenza temporale dei progressi
Questo tipo di sequenza temporale è collegato all'avanzamento relativo di un determinato elemento all'interno di un contenitore scorrevole. Come per una cronologia di avanzamento dello scorrimento, viene monitorato l'offset dello scorrimento di uno scorrevole. 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 nello scorrevole. Se l'elemento non è visibile nello scorrevole, non è in intersezione. Se è visibile all'interno del cursore, anche per la parte più piccola, è incrociato.
Una sequenza temporale dell'avanzamento della visualizzazione inizia dal momento in cui un soggetto inizia a intersecarsi con lo scorrevole e termina quando il soggetto smette di intersecarsi con lo scorrevole. Nella seguente visualizzazione, tieni presente che l'avanzamento inizia a essere conteggiato dal 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 dell'avanzamento della visualizzazione si applica all'intero intervallo. Questo inizia dal momento in cui l'oggetto entra nello scrollport e termina quando l'oggetto esce dallo scrollport.
È anche possibile collegarlo a una parte specifica della sequenza temporale di avanzamento della visualizzazione specificando l'intervallo a cui deve essere collegato. Ad esempio, può accadere solo quando l'oggetto entra nello scorrevole. Nella seguente visualizzazione, l'avanzamento inizia a conteggiare dal 0% quando l'oggetto entra nel contenitore di scorrimento, ma raggiunge già il 100% dal momento in cui è completamente intersecato.
I possibili intervalli di Spostamenti che puoi scegliere come target sono cover
, contain
, entry
, exit
, entry-crossing
e exit-crossing
. Questi intervalli sono spiegati più avanti in questo codelab, ma se non vedi l'ora di saperne di più, utilizza lo strumento all'indirizzo https://goo.gle/view-timeline-range-tool per scoprire cosa rappresenta ogni intervallo.
4. Creare un effetto di sfondo con parallasse
Il primo effetto da aggiungere alla pagina è un effetto di sfondo parallattico sull'immagine di sfondo principale. Quando scorri verso il basso la pagina, l'immagine di sfondo dovrebbe muoversi, anche se a una velocità diversa. Per farlo, devi utilizzare una sequenza temporale di avanzamento dello scorrimento.
Per implementare questa funzionalità, devi seguire due passaggi:
- Crea un'animazione che sposta la posizione dell'immagine di sfondo.
- Collega l'animazione alla progressione dello scorrimento del documento.
Creare l'animazione
- Per creare l'animazione, utilizza un normale insieme di fotogrammi chiave. Al suo interno, sposta la posizione dello sfondo dal 0% al 100% in verticale:
src/styles.css
@keyframes move-background {
from {
background-position: 50% 0%;
}
to {
background-position: 50% 100%;
}
}
- Ora collega questi fotogrammi chiave all'elemento body:
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 un'attenuazione linear
.
Collega l'animazione alla progressione dello scorrimento della radice utilizzando una sequenza temporale di avanzamento dello scorrimento anonima
Il modo più semplice per creare una sequenza temporale di avanzamento dello scorrimento è utilizzare la funzione scroll()
. Viene creata una sequenza temporale anonima di 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 dell'antenato più vicino (valore predefinito).root
. Utilizza l'area visibile 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 (valore predefinito).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 complessivo è 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 suauto
. Se non specifichi unanimation-duration
, il valore predefinito saràauto
.
src/styles.css
body {
animation: linear move-background;
animation-duration: auto;
animation-timeline: scroll(root block);
}
Poiché lo scorrimento principale è anche lo scorrimento principale più vicino per l'elemento body, puoi anche utilizzare un 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();
}
Verifica le modifiche
Se è andato tutto bene, dovresti vedere quanto segue:
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 richiede una barra di avanzamento per indicare la foto che stai visualizzando.
Il markup del 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à presenti 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 collegata 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 funzionare, non lo fa a causa del funzionamento delle ricerche dei contenitori di scorrimento automatico che utilizzano nearest
. Quando cerca lo scorrevole 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 principale che ne determina la posizione è l'elemento .gallery
, in quanto ha position: relative
applicato. Ciò significa che l'elemento .gallery__scrollcontainer
, ovvero lo scorrevole che deve essere scelto come target, non viene considerato durante questa ricerca automatica.
Per risolvere il problema, crea una sequenza temporale di avanzamento dello scorrimento denominata nell'elemento .gallery__scrollcontainer
e collegalo a .gallery__progress
utilizzando quel nome.
Crea e collega una sequenza temporale di avanzamento dello scorrimento denominata
Per creare una sequenza temporale di avanzamento dello scorrimento denominata in 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 anche impostare 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 che deve essere animato allo stesso valore dell'identificatore utilizzato per scroll-timeline-name
.
- Modifica il file
styles.css
in modo da 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;
}
Verifica le modifiche
Se è andato tutto bene, dovresti vedere quanto segue:
In caso contrario, controlla il ramo solution-step-2
del codice.
6. Animare le immagini della galleria quando entrano ed escono dallo scrollport
Appaiono le immagini della galleria
Configurare una cronologia di avanzamento della visualizzazione anonima
Un bell'effetto da aggiungere è l'attenuazione delle immagini della galleria man mano che vengono visualizzate. A questo scopo, puoi utilizzare una sequenza temporale dell'avanzamento della visualizzazione.
Per creare una cronologia di avanzamento della visualizzazione, puoi utilizzare la funzione view()
. Gli argomenti accettati sono <axis>
e <view-timeline-inset>
.
<axis>
è lo stesso parametro della cronologia 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 è considerato visibile o meno.
- I keyframe sono già presenti, quindi devi solo collegarli. A tale scopo, crea una visualizzazione della cronologia dell'avanzamento in 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 dell'avanzamento della visualizzazione
Se salvi il CSS e carichi la pagina, vedi gli elementi che appaiono gradualmente, ma qualcosa sembra non funzionare. Iniziano con un'opacità 0
quando sono completamente nascosti e terminano con un'opacità 1
solo quando sono completamente fuori.
Questo perché l'intervallo predefinito per una sequenza temporale di avanzamento della visualizzazione è l'intervallo completo. Questo intervallo è noto come intervallo cover
.
- Per scegliere come target solo l'intervallo
entry
dell'oggetto, utilizza la proprietà CSSanimation-range
per limitare il momento in cui deve essere eseguita l'animazione.
src/styles.css
.gallery__entry {
animation: linear fade-in;
animation-duration: auto;
animation-timeline: view(inline);
animation-range: entry 0% entry 100%;
}
Ora l'animazione va da entry 0%
(l'oggetto sta per entrare nello scorrevole) a entry 100%
(l'oggetto è completamente entrato nello scorrevole).
I possibili intervalli di visualizzazione della cronologia sono i seguenti:
cover
. Rappresenta l'intervallo completo della sequenza temporale dell'avanzamento della 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 casella principale attraversa il bordo del bordo di fine.exit-crossing
. Rappresenta l'intervallo durante il quale la casella principale attraversa il bordo del bordo iniziale.contain
. Rappresenta l'intervallo durante il quale la casella principale è completamente contenuta o copre completamente l'intervallo di visibilità dell'avanzamento della visualizzazione all'interno dell'area di scorrimento. Questo dipende da se il soggetto è più alto o più basso dello scorrevole.
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 di fine.
- Poiché gli intervalli iniziale e finale 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;
}
Disattivare l'effetto svanimento delle immagini della galleria
- Per attenuare le immagini quando escono dallo scorrevole, puoi fare la stessa cosa dell'animazione di animazione, ma scegliere come target 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
.
Verifica le modifiche
Se è andato tutto bene, dovresti vedere quanto segue:
In caso contrario, controlla il ramo solution-step-3
del codice.
7. Anima le immagini della galleria quando entrano ed escono dallo scrollport utilizzando un insieme di fotogrammi chiave
Il caso di un insieme di fotogrammi chiave
Anziché associare due animazioni a intervalli diversi, è possibile creare un set di keyframe 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 {
...
}
}
- Combina i fotogrammi chiave di dissolvenza in entrata e in uscita come segue:
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%);
}
}
- Quando le informazioni sull'intervallo sono presenti nei fotogrammi chiave, non è più necessario specificare
animation-range
separatamente. Collega 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);
}
Verifica le modifiche
Se tutto è andato a buon fine, 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 scollamenti di avanzamento e visualizzazioni di avanzamento in CSS.
Scopri di più
Risorse: