1. Zanim zaczniesz
Animacje sterowane przewijaniem pozwalają kontrolować odtwarzanie animacji na podstawie pozycji przewijania kontenera przewijania. Oznacza to, że podczas przewijania w górę lub w dół animacja będzie przewijana do przodu lub do tyłu. Animacje oparte na przewijaniu umożliwiają też sterowanie animacją na podstawie pozycji elementu w kontenerze przewijania. Umożliwia to tworzenie ciekawych efektów, takich jak obraz tła z efektem paralaksy, paski postępu przewijania i obrazy, które pojawiają się w miarę przewijania.
Nowością w Chrome 115 jest obsługa zestawu klas JavaScript i właściwości CSS, które umożliwiają łatwe tworzenie deklaratywnych animacji opartych na przewijaniu. Te nowe interfejsy API działają w połączeniu z dotychczasowymi interfejsami Web Animations i CSS Animations API.
Z tego ćwiczenia w Codelabs dowiesz się, jak tworzyć animacje oparte na przewijaniu za pomocą CSS. Po ukończeniu tego kursu poznasz wiele nowych właściwości CSS wprowadzonych przez tę ciekawą funkcję, takich jak scroll-timeline, view-timeline, animation-timeline i animation-range.
Czego się nauczysz
- Jak utworzyć efekt paralaksy tła za pomocą osi czasu przewijania w CSS.
- Jak utworzyć pasek postępu z osią czasu przewijania w CSS.
- Jak utworzyć efekt odsłaniania obrazu za pomocą osi czasu widoku w CSS.
- Jak kierować reklamy na różne typy zakresów osi czasu wyświetlenia w CSS.
Czego potrzebujesz
Jedna z tych kombinacji urządzeń:
- Najnowsza wersja Chrome (115 lub nowsza) na urządzeniu z ChromeOS, macOS lub Windows z włączoną flagą „Eksperymentalne funkcje platformy internetowej”.
- Podstawowa znajomość HTML
- podstawową znajomość CSS, zwłaszcza animacji w CSS;
2. Konfiguracja
Wszystko, czego potrzebujesz do tego projektu, jest dostępne w repozytorium GitHub. Aby rozpocząć, sklonuj kod i otwórz go w ulubionym środowisku programistycznym.
- Otwórz nową kartę przeglądarki i wejdź na stronę https://github.com/googlechromelabs/io23-scroll-driven-animations-codelab.
- Sklonuj repozytorium.
- Otwórz kod w wybranym IDE.
- Uruchom
npm install, aby zainstalować zależności. - Uruchom
npm starti otwórz stronę http://localhost:3000/. - Jeśli nie masz zainstalowanego npm, otwórz plik
src/index.htmlw Chrome.
3. Więcej informacji o osiach czasu animacji
Domyślnie animacja dołączona do elementu jest odtwarzana na osi czasu dokumentu. Oznacza to, że gdy strona się wczytuje, animacja jest odtwarzana w miarę upływu czasu. Jest to domyślna oś czasu animacji i do tej pory była to jedyna oś czasu animacji, do której miałeś(-aś) dostęp.
Animacje oparte na przewijaniu zapewniają dostęp do 2 nowych rodzajów osi czasu:
- Przewijanie osi czasu postępu
- Wyświetlanie osi czasu postępu
W CSS te osie czasu można dołączyć do animacji za pomocą właściwości animation-timeline. Sprawdź, co oznaczają te nowe terminy i czym się od siebie różnią.
Przewijanie osi czasu postępu
Oś czasu postępu przewijania to oś czasu animacji, która jest powiązana z postępem w pozycji przewijania kontenera przewijania (zwanego też obszarem przewijania lub przewijarką) wzdłuż określonej osi. Przekształca pozycję w zakresie przewijania na procent postępu na osi czasu.
Początkowa pozycja przewijania oznacza 0% postępu, a końcowa pozycja przewijania – 100% postępu. Na poniższej wizualizacji widać, że w miarę przewijania paska przewijania postęp rośnie od 0% do 100%.
Wyświetlanie osi czasu postępu
Ten typ osi czasu jest powiązany ze względnym postępem określonego elementu w kontenerze przewijania. Podobnie jak w przypadku osi czasu postępu przewijania śledzone jest przesunięcie przewijania paska przewijania. W przeciwieństwie do osi czasu postępu przewijania o postępie decyduje względna pozycja elementu w przewijarce. Jest to porównywalne z wartością IntersectionObserver, która śledzi, jak bardzo element jest widoczny w przewijanej sekcji. Jeśli element nie jest widoczny w przewijanej sekcji, nie przecina się z nią. Jeśli jest widoczny w przewijanej sekcji, nawet w najmniejszej części, oznacza to, że się z nią przecina.
Oś czasu postępu wyświetlenia rozpoczyna się w momencie, gdy element zaczyna przecinać przewijarkę, a kończy się, gdy przestaje ją przecinać. Na poniższej wizualizacji widać, że postęp zaczyna się od 0%, gdy element wchodzi do kontenera przewijania, i osiąga 100%, gdy go opuszcza.
Domyślnie animacja połączona z osią czasu postępu widoku jest do niej dołączona w całym zakresie. Rozpoczyna się w momencie, gdy element wchodzi do obszaru przewijania, a kończy, gdy go opuszcza.
Możesz też połączyć go z określoną częścią osi czasu postępu, podając zakres, do którego ma być dołączony. Może to być na przykład tylko wtedy, gdy obiekt wchodzi na przewijany obszar. Na poniższej wizualizacji postęp zaczyna się od 0%, gdy element wchodzi do kontenera przewijania, ale osiąga 100% od momentu, gdy w całości się z nim przecina.
Dostępne zakresy osi czasu, na które możesz kierować reklamy, to cover, contain, entry, exit, entry-crossing i exit-crossing. Zakresy te zostaną wyjaśnione w dalszej części tego kursu, ale jeśli nie możesz się doczekać, skorzystaj z narzędzia dostępnego na stronie https://goo.gle/view-timeline-range-tool, aby sprawdzić, co oznacza każdy zakres.
4. Tworzenie efektu tła z paralaksą
Pierwszym efektem, który należy dodać do strony, jest efekt paralaksy tła na głównym obrazie tła. Gdy przewijasz stronę w dół, obraz tła powinien się przesuwać, ale z inną prędkością. W tym celu użyj osi czasu postępu przewijania.
Aby to zrobić, wykonaj 2 kroki:
- Utwórz animację, która zmienia położenie obrazu tła.
- Połącz animację z przewijaniem dokumentu.
Tworzenie animacji
- Aby utworzyć animację, użyj zwykłego zestawu klatek kluczowych. Przesuń w nim pozycję tła z 0% w pionie na 100%:
src/styles.css
@keyframes move-background {
from {
background-position: 50% 0%;
}
to {
background-position: 50% 100%;
}
}
- Teraz dołącz te klatki kluczowe do elementu body:
src/styles.css
body {
animation: 1s linear move-background;
}
Dzięki temu kodowi animacja move-background zostanie dodana do elementu body. Właściwość animation-duration jest ustawiona na 1 sekundę, a element używa funkcji linear.
Połącz animację z postępem przewijania elementu głównego za pomocą anonimowej osi czasu postępu przewijania.
Najprostszym sposobem utworzenia osi czasu postępu przewijania jest użycie funkcji scroll(). Spowoduje to utworzenie anonimowej osi czasu postępu przewijania, którą możesz ustawić jako wartość właściwości animation-timeline.
Funkcja scroll() przyjmuje argumenty <scroller> i <axis>.
Akceptowane wartości argumentu <scroller> to:
nearest. Używa najbliższego kontenera przewijania elementu nadrzędnego (domyślnie).root. Używa widocznego obszaru dokumentu jako kontenera przewijania.self. Używa samego elementu jako kontenera przewijania.
Akceptowane wartości argumentu <axis> to:
block. Używa miary postępu wzdłuż osi bloku kontenera przewijania (domyślnie).inline. Używa miary postępu wzdłuż osi wbudowanej kontenera przewijania.y. Wykorzystuje miarę postępu wzdłuż osi Y kontenera przewijania.x. Używa miary postępu wzdłuż osi X kontenera przewijania.
Aby połączyć animację z głównym elementem przewijanym na osi bloku, wartości, które należy przekazać do parametru scroll(), to root i block. Łączna wartość to scroll(root block).
- Ustaw wartość
scroll(root block)we właściwościanimation-timelinew treści. - Ponadto, ponieważ
animation-durationwyrażone w sekundach nie ma sensu, ustaw czas trwania naauto. Jeśli nie określiszanimation-duration, domyślnie zostanie użyta wartośćauto.
src/styles.css
body {
animation: linear move-background;
animation-duration: auto;
animation-timeline: scroll(root block);
}
Ponieważ główny element przewijany jest też najbliższym elementem przewijanym nadrzędnym dla elementu body, możesz też użyć wartości nearest:
src/styles.css
body {
animation: linear move-background;
animation-duration: auto;
animation-timeline: scroll(nearest block);
}
Ponieważ nearest i block to wartości domyślne, możesz je pominąć. W takim przypadku kod można uprościć do tej postaci:
src/styles.css
body {
animation: linear move-background;
animation-duration: auto;
animation-timeline: scroll();
}
Weryfikowanie zmian
Jeśli wszystko przebiegło pomyślnie, powinna pojawić się taka informacja:
Jeśli nie, sprawdź gałąź kodu solution-step-1.
5. Tworzenie paska postępu dla galerii obrazów
Na stronie znajduje się karuzela pozioma, która wymaga paska postępu, aby wskazywać, które zdjęcie jest aktualnie wyświetlane.
Kod znaczników karuzeli wygląda tak:
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>
Klatki kluczowe paska postępu są już na miejscu i wyglądają tak:
src/styles.css
@keyframes adjust-progress {
from {
transform: scaleX(calc(1 / var(--num-images)));
}
to {
transform: scaleX(1);
}
}
Ta animacja musi być dołączona do elementu .Element gallery__progress z osią czasu postępu przewijania. Jak pokazano w poprzednim kroku, możesz to zrobić, tworząc anonimową oś czasu postępu przewijania za pomocą funkcji scroll():
src/styles.css
.gallery__progress {
animation: linear adjust-progress;
animation-duration: auto;
animation-timeline: scroll(nearest inline);
}
Ten fragment kodu może wydawać się działający, ale tak nie jest ze względu na sposób, w jaki działają automatyczne wyszukiwania kontenerów przewijania za pomocą nearest. Podczas wyszukiwania najbliższego elementu przewijanego element będzie uwzględniać tylko te elementy, które mogą wpływać na jego pozycję. Ponieważ element .gallery__progress ma pozycję bezwzględną, pierwszym elementem nadrzędnym, który określi jego pozycję, będzie element .gallery, ponieważ ma zastosowaną właściwość position: relative. Oznacza to, że element .gallery__scrollcontainer, czyli pasek przewijania, który ma być celem, nie jest w ogóle brany pod uwagę podczas tego automatycznego wyszukiwania.
Aby to obejść, utwórz nazwaną oś czasu postępu przewijania w elemencie .gallery__scrollcontainer i połącz z nią element .gallery__progress, używając tej nazwy.
Tworzenie i łączenie nazwanej osi czasu postępu przewijania
Aby utworzyć nazwaną oś czasu postępu przewijania w elemencie, ustaw właściwość CSS scroll-timeline-name w kontenerze przewijania na wybraną wartość. Wartość musi zaczynać się od znaku --.
Galeria przewija się w poziomie, więc musisz też ustawić właściwość scroll-timeline-axis. Dozwolone wartości są takie same jak argument <axis> funkcji scroll().
Aby połączyć animację z osią czasu postępu przewijania, ustaw właściwość animation-timeline elementu, który ma być animowany, na tę samą wartość co identyfikator użyty w przypadku scroll-timeline-name.
- Zmień plik
styles.css, aby zawierał te elementy:
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;
}
Weryfikowanie zmian
Jeśli wszystko przebiegło pomyślnie, powinna pojawić się taka informacja:
Jeśli nie, sprawdź gałąź kodu solution-step-2.
6. Animowanie obrazów w galerii, gdy pojawiają się w obszarze przewijania i z niego znikają
Płynne pojawianie się obrazów w galerii
Konfigurowanie anonimowej osi czasu postępu oglądania
Dobrym efektem jest stopniowe pojawianie się obrazów w galerii. Możesz w tym celu użyć osi czasu postępu.
Aby utworzyć oś czasu postępu wyświetlania, możesz użyć funkcji view(). Akceptowane argumenty to <axis> i <view-timeline-inset>.
- Wartość
<axis>jest taka sama jak na osi czasu postępu przewijania i określa, którą oś śledzić. - Za pomocą
<view-timeline-inset>możesz określić przesunięcie (dodatnie lub ujemne), aby dostosować granice, gdy element jest uznawany za widoczny lub niewidoczny.
- Klatki kluczowe są już na miejscu, więc wystarczy je dołączyć. Aby to zrobić, utwórz oś czasu postępu wyświetlania na każdym elemencie
.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);
}
Ograniczanie zakresu osi czasu postępu oglądania
Jeśli zapiszesz CSS i wczytasz stronę, zobaczysz, że elementy pojawiają się stopniowo, ale coś jest nie tak. Zaczynają się od przezroczystości 0, gdy są całkowicie poza widokiem, a kończą na przezroczystości 1, gdy całkowicie znikną.
Dzieje się tak, ponieważ domyślny zakres osi czasu postępu wyświetlania to pełny zakres. Jest to tzw. cover zakres.
- Aby kierować reklamy tylko na zakres
entry, użyj właściwości CSSanimation-range, aby ograniczyć czas działania animacji.
src/styles.css
.gallery__entry {
animation: linear fade-in;
animation-duration: auto;
animation-timeline: view(inline);
animation-range: entry 0% entry 100%;
}
Animacja będzie teraz odtwarzana od entry 0% (obiekt ma wejść do przewijanej sekcji) do entry 100% (obiekt w całości wszedł do przewijanej sekcji).
Dostępne zakresy osi czasu to:
cover– reprezentuje pełny zakres osi czasu postępu wyświetlania.entryOznacza zakres, w którym główny boks wchodzi w zakres widoczności postępu wyświetlania.exit– zakres, w którym główny boks opuszcza zakres widoczności postępu wyświetlania.entry-crossing. Przedstawia zakres, w którym pole główne przekracza krawędź końcową.exit-crossing– zakres, w którym pole główne przekracza krawędź granicy początkowej.contain. Oznacza zakres, w którym główny boks jest w całości zawarty w zakresie widoczności postępu wyświetlania w obszarze przewijania lub w całości go obejmuje. Zależy to od tego, czy obiekt jest wyższy czy niższy od przewijanej treści.
Aby sprawdzić, co oznacza każdy zakres i jak procenty wpływają na pozycje początkowe i końcowe, użyj narzędzia dostępnego na stronie https://goo.gle/view-timeline-range-tool.
- Ponieważ zakresy początkowy i końcowy są w tym przypadku takie same i używane są domyślne przesunięcia, uprość
animation-rangedo pojedynczej nazwy zakresu animacji:
src/styles.css
.gallery__entry {
animation: linear animate-in;
animation-duration: auto;
animation-timeline: view(inline);
animation-range: entry;
}
Przyciemnianie obrazów w galerii
- Aby obrazy znikały podczas opuszczania przewijanej sekcji, możesz zastosować tę samą metodę co w przypadku animacji pojawiania się, ale w innym zakresie.
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;
}
Klatki kluczowe animate-in zostaną zastosowane do zakresu entry, a klatki kluczowe animate-out do zakresu exit.
Weryfikowanie zmian
Jeśli wszystko przebiegło pomyślnie, powinna pojawić się taka informacja:
Jeśli nie, sprawdź gałąź kodu solution-step-3.
7. Animuj obrazy w galerii, gdy pojawiają się w obszarze przewijania i z niego znikają, używając jednego zestawu klatek kluczowych.
Przypadek jednego zestawu klatek kluczowych
Zamiast dołączać 2 animacje do różnych zakresów, możesz utworzyć 1 zestaw klatek kluczowych, który zawiera już informacje o zakresie.
Kształt klatek kluczowych wygląda tak:
@keyframes keyframes-name {
range-name range-offset {
...
}
range-name range-offset {
...
}
}
- Połącz klatki kluczowe zanikania i pojawiania się w ten sposób:
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%);
}
}
- Jeśli informacje o zakresie są obecne w klatkach kluczowych, nie musisz już osobno określać
animation-range. Dołącz klatki kluczowe jako właściwośćanimation.
src/styles.css
.gallery__entry {
animation: linear animate-in-and-out both;
animation-duration: auto;
animation-timeline: view(inline);
}
Weryfikowanie zmian
Jeśli wszystko poszło dobrze, wynik powinien być taki sam jak w poprzednim kroku. Jeśli nie, sprawdź gałąź kodu solution-step-4.
8. Gratulacje!
To ćwiczenie z programowania zostało ukończone. Wiesz już, jak tworzyć w CSS osie czasu postępu przewijania i osie czasu postępu wyświetlania.
Więcej informacji
Zasoby: