1. Zanim zaczniesz
Animacje przewijane pozwalają kontrolować odtwarzanie animacji na podstawie pozycji przewijania kontenera przewijania. Oznacza to, że podczas przewijania w górę lub w dół animacja przesuwa się do przodu lub do tyłu. Dodatkowo w przypadku animacji przewijanych możesz sterować animacją na podstawie pozycji elementu w jego kontenerze przewijania. Pozwala to tworzyć interesujące efekty, takie jak obraz tła z paralaksą, paski postępu przewijania i obrazy, które odsłaniają się, gdy się pojawią.
Nowością w Chrome 115 jest obsługa zestawu klas JavaScriptu i właściwości CSS, które umożliwiają łatwe tworzenie deklaratywnych animacji przewijanych. Te nowe interfejsy API działają w połączeniu z dotychczasowymi interfejsami Web Animations i CSS Animations.
Dzięki temu ćwiczeniu w Codelabs dowiesz się, jak za pomocą CSS tworzyć animacje oparte na przewijaniu. Po ukończeniu tego ćwiczenia w programie poznasz wiele nowych właściwości CSS wprowadzonych w tej ciekawej funkcji, takich jak scroll-timeline
, view-timeline
, animation-timeline
i animation-range
.
Czego się nauczysz
- Jak utworzyć efekt paralaksy w tle za pomocą osi czasu przewijania w CSS.
- Jak utworzyć pasek postępu za pomocą osi czasu przewijania w CSS.
- Jak utworzyć efekt odkrywania obrazu za pomocą widoku osi czasu w CSS.
- Jak kierować reklamy na różne typy zakresów na osi czasu wyświetlania w CSS.
Czego potrzebujesz
Jedna z tych kombinacji urządzeń:
- najnowszą wersję Chrome (115 lub nowszą) w systemie ChromeOS, macOS lub Windows z „eksperymentalnymi funkcjami platformy internetowej”. flaga ustawiona na „Enabled” (Włączono).
- Podstawowa znajomość języka HTML
- Podstawowa wiedza o kodzie CSS, w szczególności w zakresie animacji
2. Konfiguracja
Wszystko, czego potrzebujesz w tym projekcie, jest dostępne w repozytorium GitHub. Na początek skopiuj kod i otwórz go w swoim ulubionym środowisku programistycznym.
- Otwórz nową kartę przeglądarki i wejdź na stronę https://github.com/googlechromelabs/io23-scroll-driven-animations-codelab.
- Skopiuj repozytorium.
- Otwórz kod w preferowanym IDE.
- Uruchom
npm install
, aby zainstalować zależności. - Uruchom
npm start
i wejdź na stronę http://localhost:3000/. - Jeśli usługa npm nie jest zainstalowana, możesz też otworzyć plik
src/index.html
w Chrome.
3. Więcej informacji o osiach czasu animacji
Domyślnie animacja dołączana do elementu jest wyświetlana na osi czasu dokumentu. Oznacza to, że po załadowaniu strony animacja przesuwa się do przodu w miarę upływu czasu. To jest domyślna oś czasu animacji, a do tej pory była to jedyna oś czasu animacji, do której masz dostęp.
Animacje przewijane oferują dostęp do 2 nowych typów osi czasu:
- Oś czasu przewijania
- Wyświetl oś czasu postępów
W CSS te osie czasu można dołączyć do animacji za pomocą właściwości animation-timeline
. Zobacz, co oznaczają nowe oś czasu i czym różnią się od siebie.
Oś czasu przewijania
Oś czasu przewijania to oś czasu animacji powiązana z postępem w pozycji przewijania kontenera przewijania – nazywanego też obszarem przewijania lub przewijaną – wzdłuż konkretnej osi. Konwertuje pozycję w zakresie przewijania na procent postępu na osi czasu.
Początkowa pozycja przewijania reprezentuje 0% postępu, a końcowa pozycja przewijania – cały postęp. Na tej wizualizacji widać, że postęp jest zliczany od 0% do 100% podczas przewijania w dół.
Wyświetl oś czasu postępów
Ten typ osi czasu jest powiązany ze względnym postępem określonego elementu w kontenerze przewijania. Tak jak w przypadku osi czasu postępu przewijania, śledzenie przesunięcia przewijania jest liczone. W przeciwieństwie do osi czasu postępu przewijania o postępy decyduje względna pozycja obiektu w tym przewijaniu. Jest to porównywalne ze stanem IntersectionObserver
, który śledzi, jak bardzo element jest widoczny w obszarze przewijania. Jeśli element nie jest widoczny w komponencie do przewijania, oznacza to, że nie ma części wspólnej. Jeśli jest widoczny wewnątrz elementu przewijania, nawet w przypadku jego najmniejszej części, oznacza, że element krzyżuje się.
Oś czasu wyświetlania rozpoczyna się w momencie, gdy obiekt zaczyna krzyżować się z elementem przewijania, a kończy się, gdy obiekt przestanie przecinać obszar przewijania. Na tej wizualizacji zauważ, że postęp zaczyna zliczać od 0%, gdy obiekt znajdzie się w kontenerze przewijania, i osiągnąć 100% w momencie opuszczenia kontenera przewijania.
Domyślnie animacja połączona z osią czasu wyświetlania jest dołączana do całego jej zakresu. Zaczyna się od momentu, gdy obiekt znajdzie się w obszarze przewijania, a kończy w momencie, gdy go opuści.
Możesz też powiązać go z konkretną częścią osi czasu wyświetlania postępu, określając zakres, do którego powinna zostać przypisana. Może to być na przykład tylko wtedy, gdy temat jest otwierany w obszarze przewijania. W poniższej wizualizacji postęp zaczyna się liczyć od 0%, gdy obiekt znajdzie się w kontenerze przewijania, ale osiągnie 100% stopnia od momentu całkowitego przecięcia się z obiektem.
Możliwe zakresy widoku osi czasu, na które możesz kierować reklamy, to cover
, contain
, entry
, exit
, entry-crossing
i exit-crossing
. Zakresy zostały objaśnione w dalszej części tego ćwiczenia w Codelabs, ale jeśli nie możesz się doczekać, skorzystaj z narzędzia dostępnego na stronie https://goo.gle/view-timeline-range-tool.
4. Tworzenie efektu w tle z efektem paralaksy
Pierwszym efektem, który możesz dodać do strony, jest efekt paralaksy w głównym obrazie tła. Podczas przewijania strony w dół obraz tła powinien się przesuwać, ale z różną prędkością. W tym celu polegasz na osi czasu postępu przewijania.
Aby wdrożyć to ustawienie, musisz wykonać 2 czynności:
- Utwórz animację, która zmienia pozycję obrazu tła.
- Połącz animację z postępem przewijania dokumentu.
Tworzenie animacji
- Aby utworzyć animację, użyj zwykłego zestawu klatek kluczowych. Zmień w niej położenie 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;
}
Po użyciu tego kodu animacja move-background
jest dodawana do elementu Body. Właściwość animation-duration
jest ustawiona na 1 sekundę i używa wygładzania linear
.
Połącz animację z postępem przewijania w katalogu głównym, korzystając z anonimowej osi czasu postępu przewijania
Najłatwiejszym sposobem utworzenia osi czasu przewijania jest użycie funkcji scroll()
. Spowoduje to utworzenie anonimowej osi czasu przewijania, którą możesz ustawić jako wartość właściwości animation-timeline
.
Funkcja scroll()
akceptuje argumenty <scroller>
i <axis>
.
Akceptowane wartości dla argumentu <scroller>
:
nearest
Wykorzystuje kontener przewijania do najbliższego 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 dla argumentu <axis>
:
block
Wykorzystuje pomiar postępu wzdłuż osi bloku kontenera przewijania (domyślnie).inline
Używa pomiaru postępu wzdłuż wbudowanej osi kontenera przewijania.y
Korzysta z miary postępu wzdłuż osi Y kontenera przewijania.x
Określa postęp na osi X kontenera przewijania.
Aby połączyć animację z głównym elementem przewijania na osi bloku, do elementu scroll()
należy przekazywać wartości root
i block
. Łączna wartość to scroll(root block)
.
- Ustaw
scroll(root block)
jako wartość właściwościanimation-timeline
treści. - Poza tym funkcja
animation-duration
wyrażona w sekundach nie ma sensu, dlatego ustaw czas trwania naauto
. Jeśli nie określisz wartościanimation-duration
, zostanie użyta domyślna wartośćauto
.
src/styles.css
body {
animation: linear move-background;
animation-duration: auto;
animation-timeline: scroll(root block);
}
Główny element przewijający jest również najbliższym nadrzędnym elementem przewijającym elementu body, więc możesz też użyć wartości nearest
:
src/styles.css
body {
animation: linear move-background;
animation-duration: auto;
animation-timeline: scroll(nearest block);
}
nearest
i block
to wartości domyślne, więc możesz je nawet pominąć. W takim przypadku kod można uprościć do następującego:
src/styles.css
body {
animation: linear move-background;
animation-duration: auto;
animation-timeline: scroll();
}
Weryfikowanie zmian
Jeśli wszystko przebiegło pomyślnie, kod powinien wyglądać tak:
Jeśli nie, sprawdź gałąź solution-step-1
kodu.
5. Utwórz pasek postępu dla galerii obrazów
Na stronie znajduje się pozioma karuzela. Pasek postępu powinien wskazywać, które zdjęcie aktualnie oglądasz.
Znaczniki karuzeli wyglądają 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 na pasku postępu są już na swoim miejscu i wyglądają tak:
src/styles.css
@keyframes adjust-progress {
from {
transform: scaleX(calc(1 / var(--num-images)));
}
to {
transform: scaleX(1);
}
}
Tę animację należy dołączyć do pliku .Element gallery__progress
z osią postępu przewijania. Jak pokazano w poprzednim kroku, możesz to osiągnąć, tworząc anonimową oś czasu przewijania za pomocą funkcji scroll()
:
src/styles.css
.gallery__progress {
animation: linear adjust-progress;
animation-duration: auto;
animation-timeline: scroll(nearest inline);
}
Chociaż fragment kodu może się wydawać, że zadziała, nie jest to spowodowane tym, jak działają automatyczne wyszukiwanie kontenerów przewijania za pomocą funkcji nearest
. Podczas wyszukiwania najbliższego elementu przewijania element bierze pod uwagę tylko te elementy, które mogą mieć wpływ na jego pozycję. Element .gallery__progress
ma pozycję bezwzględną, więc pierwszym elementem nadrzędnym, który określa jego pozycję, jest element .gallery
, ponieważ ma on zastosowany element position: relative
. Oznacza to, że element .gallery__scrollcontainer
– czyli element przewijający, na który należy ustawić kierowanie – nie jest w ogóle brany pod uwagę podczas tego automatycznego wyszukiwania.
Aby obejść ten problem, utwórz w elemencie .gallery__scrollcontainer
nazwaną oś czasu przewijania i połącz z nią element .gallery__progress
, używając tej nazwy.
Utwórz i połącz z nazwą osi czasu postępu przewijania
Aby utworzyć w elemencie nazwaną oś czasu przewijania, ustaw odpowiednią wartość właściwości CSS scroll-timeline-name
w kontenerze przewijania. Wartość musi zaczynać się od --
.
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()
.
Na koniec, aby połączyć animację z osią czasu przewijania, ustaw właściwość animation-timeline
elementu, który ma być animowany, na tę samą wartość co identyfikator używany w przypadku elementu scroll-timeline-name
.
- Zmień plik
styles.css
, dodając do niego te dane:
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, kod powinien wyglądać tak:
Jeśli nie, sprawdź gałąź solution-step-2
kodu.
6. Animuj obrazy w galerii, gdy otwierają i znikają z obszaru przewijania
Rozjaśnianie obrazów w galerii
Skonfiguruj anonimową oś czasu wyświetlania postępów
Miłym efektem jest zanikanie obrazów w galerii, gdy pojawią się w widoku. W tym celu możesz skorzystać z osi czasu wyświetlania postępów.
Aby utworzyć oś czasu wyświetlania postępu, możesz użyć funkcji view()
. Jej akceptowane argumenty to <axis>
i <view-timeline-inset>
.
- Wartość
<axis>
jest taka sama jak oś czasu postępu przewijania i określa, którą oś śledzić. <view-timeline-inset>
pozwala określić przesunięcie (dodatnie lub ujemne), co pozwala dostosować granice w przypadku, gdy element jest uznawany za widoczny lub nie.
- Klatki kluczowe są już na swoim miejscu, więc musisz je tylko dołączyć. Aby to zrobić, utwórz oś czasu wyświetlania postępów dla każdego elementu
.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);
}
Ogranicz zakres osi czasu postępu wyświetlania
Jeśli zapiszesz kod CSS i wczytasz stronę, elementy wyłaniają się, ale coś nie będzie wyglądało. Zaczynają się od przezroczystości 0
, gdy są całkowicie niewidoczne, a kończą jako nieprzezroczystość 1
po zamknięciu.
Wynika to z faktu, że domyślny zakres osi czasu procesu wyświetlania to pełny zakres. Jest to tzw. zakres cover
.
- Jeśli chcesz kierować reklamy tylko na zakres
entry
tematu, użyj właściwości CSSanimation-range
, by ograniczyć czas trwania animacji.
src/styles.css
.gallery__entry {
animation: linear fade-in;
animation-duration: auto;
animation-timeline: view(inline);
animation-range: entry 0% entry 100%;
}
Animacja zaczyna się od entry 0%
(temat jest za chwilę przesuwany w stronę paska przewijania) do entry 100%
(obiekt w pełni przeszedł do obszaru przewijania).
Możliwe zakresy widoku osi czasu:
cover
Reprezentuje pełny zakres osi czasu postępu wyświetlania.entry
Reprezentuje zakres, w którym pole podmiotu zabezpieczeń wchodzi w zakres widoczności postępu wyświetlania.exit
Reprezentuje zakres, w którym pole podmiotu zabezpieczeń wychodzi z zakresu widoczności postępu wyświetlania.entry-crossing
Reprezentuje zakres, w którym pole podmiotu zabezpieczeń przekracza końcową krawędź.exit-crossing
Reprezentuje zakres, w którym pole podmiotu zabezpieczeń przekracza początkową krawędź.contain
Reprezentuje zakres, w którym pole podmiotu zabezpieczeń jest w pełni zawarte lub pokrywa zakres widoczności postępu wyświetlania w obszarze przewijania. Zależy to od tego, czy obiekt jest wyższy czy krótszy od przewijania.
Skorzystaj z narzędzia dostępnego na stronie https://goo.gle/view-timeline-range-tool, aby zobaczyć, co oznacza każdy z zakresów i jak wartości procentowe wpływają na pozycję początkową i końcową.
- Zakresy początkowy i końcowy są tutaj takie same oraz użyte domyślne przesunięcia, więc uprość pole
animation-range
, tworząc jedną nazwę zakresu animacji:
src/styles.css
.gallery__entry {
animation: linear animate-in;
animation-duration: auto;
animation-timeline: view(inline);
animation-range: entry;
}
Rozjaśnianie obrazów z galerii
- Aby zanikać obrazy po wyjściu z paska przewijania, możesz zrobić to samo co w animacji, ale ustawić inny zakres.
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, kod powinien wyglądać tak:
Jeśli nie, sprawdź gałąź solution-step-3
kodu.
7. Używaj jednego zestawu klatek kluczowych, aby animować obrazy z galerii w momencie, gdy otwierają i znikają w obszarze przewijania.
Przypadek jednego zestawu klatek kluczowych
Zamiast dołączać dwie animacje do różnych zakresów, możesz utworzyć jeden 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 {
...
}
}
- Łącz klatki kluczowe rozjaśniania i zanikania 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%);
}
}
- Gdy w klatkach kluczowych znajdują się informacje o zakresie, nie musisz już osobno określać elementu
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łąź solution-step-4
kodu.
8. Gratulacje!
To już ćwiczenia z programowania i teraz wiesz, jak tworzyć osie czasu postępu przewijania i wyświetlać oś czasu postępów w CSS.
Więcej informacji
Zasoby: