1. Прежде чем начать
Анимации, управляемые прокруткой, позволяют управлять воспроизведением анимации в зависимости от положения прокрутки контейнера прокрутки. Это означает, что при прокрутке вверх или вниз анимация перемещается вперед или назад. Кроме того, с помощью анимации, управляемой прокруткой, вы также можете управлять анимацией в зависимости от положения элемента внутри его контейнера прокрутки. Это позволяет создавать интересные эффекты, такие как фоновое изображение параллакса, индикаторы выполнения прокрутки и изображения, которые проявляются при появлении.
Новым в Chrome 115 является поддержка набора классов JavaScript и свойств CSS, которые позволяют легко создавать декларативную анимацию, управляемую прокруткой. Эти новые API работают в сочетании с существующими API-интерфейсами веб-анимации и CSS-анимации.
В этой лаборатории кода вы узнаете, как создавать анимацию, управляемую прокруткой, с помощью CSS. Выполнив эту лабораторную работу, вы познакомитесь со многими новыми свойствами CSS, представленными этой замечательной функцией, такими как scroll-timeline
, view-timeline
, animation-timeline
и animation-range
.
Что вы узнаете
- Как создать фоновый эффект параллакса с помощью временной шкалы прокрутки в CSS.
- Как создать индикатор выполнения с помощью шкалы времени прокрутки в CSS.
- Как создать эффект раскрытия изображения с помощью временной шкалы просмотра в CSS.
- Как настроить таргетинг на различные типы диапазонов временной шкалы просмотра в CSS.
Что вам понадобится
Одна из следующих комбинаций устройств:
- Последняя версия Chrome (115 или новее) для ChromeOS, macOS или Windows с включенным флагом «Экспериментальные функции веб-платформы».
- Базовое понимание HTML
- Фундаментальное понимание CSS, особенно анимации в CSS.
2. Настройте
Все, что вам нужно для этого проекта, доступно в репозитории GitHub. Для начала клонируйте код и откройте его в любимой среде разработки.
- Откройте новую вкладку браузера и перейдите по адресу https://github.com/googlechromelabs/io23-scroll-driven-animations-codelab .
- Клонируйте репозиторий.
- Откройте код в предпочитаемой вами IDE.
- Запустите
npm install
, чтобы установить зависимости. - Запустите
npm start
и посетите http://localhost:3000/ . - Альтернативно, если у вас не установлен npm, откройте файл
src/index.html
в Chrome.
3. Узнайте о сроках анимации.
По умолчанию анимация, прикрепленная к элементу, запускается на временной шкале документа. Это означает, что когда страница загружается, анимация продвигается вперед с течением времени. Это временная шкала анимации по умолчанию, и до сих пор это была единственная временная шкала анимации, к которой у вас был доступ.
Благодаря анимации, управляемой прокруткой, вы получаете доступ к двум новым типам временных шкал:
- Прокрутка временной шкалы прогресса
- Посмотреть график прогресса
В CSS эти временные шкалы можно прикрепить к анимации с помощью свойства animation-timeline
. Взгляните, что означают эти новые сроки и чем они отличаются друг от друга.
Прокрутка временной шкалы прогресса
Временная шкала прогресса прокрутки — это временная шкала анимации, которая связана с прогрессом в положении прокрутки контейнера прокрутки, также называемого портом прокрутки или скроллером, вдоль определенной оси. Он преобразует позицию в диапазоне прокрутки в процент прогресса на временной шкале.
Начальная позиция прокрутки представляет прогресс 0%, а конечная позиция прокрутки представляет прогресс 100%. Обратите внимание, что на следующей визуализации прогресс увеличивается от 0% до 100% по мере прокрутки скроллера вниз.
Посмотреть график прогресса
Этот тип временной шкалы связан с относительным прогрессом конкретного элемента в контейнере прокрутки. Как и в случае с временной шкалой прогресса прокрутки, отслеживается смещение прокрутки скроллера. В отличие от временной шкалы прогресса прокрутки, прогресс определяется относительным положением объекта внутри этого скроллера. Это сравнимо с IntersectionObserver
, который отслеживает, насколько элемент виден в скроллере. Если элемент не виден в скроллере, он не пересекается. Если он виден внутри скроллера – даже в самой маленькой его части – он пересекается.
Временная шкала прогресса просмотра начинается с момента, когда объект начинает пересекаться со скроллером, и заканчивается, когда объект перестает пересекать скроллер. Обратите внимание, что на следующей визуализации прогресс начинает отсчитываться от 0 %, когда субъект входит в контейнер прокрутки, и достигает 100 % к моменту выхода из контейнера прокрутки.
По умолчанию анимация, связанная с временной шкалой просмотра прогресса, прикрепляется ко всему ее диапазону. Это начинается с момента, когда субъект входит в область прокрутки, и заканчивается, когда субъект покидает область прокрутки.
Также можно связать его с определенной частью временной шкалы просмотра прогресса, указав диапазон, к которому он должен быть прикреплен. Это может быть, например, только тогда, когда субъект входит в скроллер. В следующей визуализации прогресс начинает отсчитываться от 0%, когда объект входит в контейнер прокрутки, но уже достигает 100% с момента его полного пересечения.
Возможные диапазоны просмотра временной шкалы, на которые вы можете настроить таргетинг, — это cover
, contain
, entry
, exit
, entry-crossing
и exit-crossing
. Эти диапазоны объяснены позже в этой лаборатории кода, но если вам не терпится узнать, воспользуйтесь инструментом, расположенным по адресу https://goo.gle/view-timeline-range-tool , чтобы увидеть, что представляет каждый диапазон.
4. Создайте фоновый эффект параллакса
Первый эффект, который нужно добавить на страницу, — это фоновый эффект параллакса на основном фоновом изображении. При прокрутке страницы вниз фоновое изображение должно двигаться, хотя и с другой скоростью. Для этого вы полагаетесь на временную шкалу прогресса прокрутки.
Для реализации этого необходимо сделать два шага:
- Создайте анимацию, которая перемещает положение фонового изображения.
- Свяжите анимацию с прогрессом прокрутки документа.
Создайте анимацию
- Для создания анимации используйте обычный набор ключевых кадров. В нем переместите положение фона с 0% по вертикали до 100%:
src/styles.css
@keyframes move-background {
from {
background-position: 50% 0%;
}
to {
background-position: 50% 100%;
}
}
- Теперь прикрепите эти ключевые кадры к элементу body:
src/styles.css
body {
animation: 1s linear move-background;
}
С помощью этого кода к элементу body добавляется анимация move-background
. Его свойство animation-duration
установлено на одну секунду и использует linear
замедление.
Свяжите анимацию с прогрессом прокрутки корня, используя анонимную временную шкалу прогресса прокрутки.
Самый простой способ создать временную шкалу прогресса прокрутки — использовать функцию scroll()
. При этом создается анонимная временная шкала прогресса прокрутки, которую можно установить в качестве значения свойства animation-timeline
.
Функция scroll()
принимает аргументы <scroller>
и <axis>
.
Допустимые значения аргумента <scroller>
:
-
nearest
. Использует контейнер прокрутки ближайшего предка (по умолчанию). -
root
. Использует область просмотра документа в качестве контейнера прокрутки. -
self
. Использует сам элемент в качестве контейнера прокрутки.
Допустимые значения аргумента <axis>
:
-
block
. Использует меру прогресса вдоль оси блока контейнера прокрутки (по умолчанию). -
inline
. Использует меру прогресса вдоль встроенной оси контейнера прокрутки. -
y
. Использует меру прогресса по оси Y контейнера прокрутки. -
x
. Использует меру прогресса по оси X контейнера прокрутки.
Чтобы связать анимацию с корневым скроллером на оси блока, в scroll()
нужно передать значения root
и block
. В совокупности значение равно scroll(root block)
.
- Установите
scroll(root block)
в качестве значения свойстваanimation-timeline
в теле. - Более того, поскольку
animation-duration
выраженная в секундах, не имеет смысла, установите для нее значениеauto
. Если вы не укажетеanimation-duration
, по умолчанию будет установлено значениеauto
.
src/styles.css
body {
animation: linear move-background;
animation-duration: auto;
animation-timeline: scroll(root block);
}
Поскольку корневой скроллер также является ближайшим родительским скроллером для элемента body, вы также можете использовать значение nearest
:
src/styles.css
body {
animation: linear move-background;
animation-duration: auto;
animation-timeline: scroll(nearest block);
}
Поскольку значения nearest
и block
являются значениями по умолчанию, вы можете даже опустить их. В этом случае код можно упростить до следующего:
src/styles.css
body {
animation: linear move-background;
animation-duration: auto;
animation-timeline: scroll();
}
Подтвердите свои изменения
Если все прошло хорошо, теперь у вас должно быть следующее:
Если нет, проверьте ветку кода solution-step-1
.
5. Создайте индикатор выполнения для галереи изображений.
На странице расположена горизонтальная карусель, в которой требуется индикатор выполнения, чтобы указать, какую фотографию вы сейчас просматриваете.
Разметка карусели выглядит следующим образом:
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>
Ключевые кадры для индикатора выполнения уже установлены и выглядят следующим образом:
src/styles.css
@keyframes adjust-progress {
from {
transform: scaleX(calc(1 / var(--num-images)));
}
to {
transform: scaleX(1);
}
}
Эту анимацию необходимо прикрепить к файлу . Элемент gallery__progress
с временной шкалой прокрутки. Как показано на предыдущем шаге, этого можно добиться, создав анонимную временную шкалу прогресса прокрутки с помощью функции scroll()
:
src/styles.css
.gallery__progress {
animation: linear adjust-progress;
animation-duration: auto;
animation-timeline: scroll(nearest inline);
}
Хотя может показаться, что этот фрагмент кода будет работать, это не так из-за того, что автоматический поиск контейнера прокрутки использует nearest
работу. При поиске ближайшего скроллера элемент будет учитывать только те элементы, которые могут повлиять на его положение. Поскольку .gallery__progress
является абсолютно позиционированным, первым родительским элементом, который будет определять его положение, является элемент .gallery
, поскольку к нему применено position: relative
. Это означает, что элемент .gallery__scrollcontainer
, который представляет собой скроллер, на который необходимо настроить таргетинг, вообще не учитывается во время автоматического поиска.
Чтобы обойти эту проблему, создайте именованную временную шкалу прогресса прокрутки в элементе .gallery__scrollcontainer
и свяжите с ней .gallery__progress
, используя это имя.
Создайте и свяжите именованную временную шкалу прогресса прокрутки.
Чтобы создать именованную временную шкалу прогресса прокрутки для элемента, установите для свойства CSS scroll-timeline-name
в контейнере прокрутки нужное значение. Значение должно начинаться с --
.
Поскольку галерея прокручивается горизонтально, вам также необходимо установить свойство scroll-timeline-axis
. Допустимые значения такие же, как и у аргумента <axis>
функции scroll()
.
Наконец, чтобы связать анимацию с временной шкалой выполнения прокрутки, установите для свойства animation-timeline
элемента, который необходимо анимировать, то же значение, что и идентификатор, используемый для scroll-timeline-name
.
- Измените
styles.css
, включив в него следующее:
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;
}
Подтвердите свои изменения
Если все прошло хорошо, теперь у вас должно быть следующее:
Если нет, проверьте ветку кода solution-step-2
.
6. Анимируйте изображения галереи при их входе и выходе из области прокрутки.
Затухание изображений в галерее
Настройте анонимный просмотр временной шкалы прогресса
Хороший эффект — постепенное исчезновение изображений галереи по мере их появления. Для этого вы можете использовать временную шкалу просмотра прогресса.
Чтобы создать временную шкалу просмотра прогресса, вы можете использовать функцию view()
. Его приемлемыми аргументами являются <axis>
и <view-timeline-inset>
.
-
<axis>
аналогична временной шкале прогресса прокрутки и определяет, какую ось отслеживать. - С помощью
<view-timeline-inset>
вы можете указать смещение (положительное или отрицательное), чтобы настроить границы, когда элемент считается видимым или нет.
- Ключевые кадры уже на месте, поэтому вам нужно только прикрепить их. Для этого создайте временную шкалу просмотра прогресса для каждого элемента
.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);
}
Ограничить диапазон просмотра временной шкалы прогресса
Если вы сохраните CSS и загрузите страницу, вы увидите, что элементы исчезают, но что-то кажется не так. Они начинаются с непрозрачности 0
, когда полностью находятся вне поля зрения, и заканчиваются непрозрачностью 1
только тогда, когда полностью выходят из поля зрения.
Это связано с тем, что диапазон по умолчанию для временной шкалы просмотра прогресса — полный диапазон. Это известно как диапазон cover
.
- Чтобы настроить таргетинг только на диапазон
entry
объекта, используйте свойство CSSanimation-range
, чтобы ограничить время запуска анимации.
src/styles.css
.gallery__entry {
animation: linear fade-in;
animation-duration: auto;
animation-timeline: view(inline);
animation-range: entry 0% entry 100%;
}
Анимация теперь выполняется от entry 0%
(субъект вот-вот войдет в скроллер) до entry 100%
(субъект полностью вошел в скроллер).
Возможные диапазоны просмотра временной шкалы:
-
cover
. Представляет полный диапазон временной шкалы прогресса просмотра. -
entry
. Представляет диапазон, в течение которого основное поле входит в диапазон видимости прогресса просмотра. -
exit
. Представляет диапазон, в течение которого основной блок выходит из диапазона видимости прогресса просмотра. -
entry-crossing
. Представляет диапазон, в течение которого основной блок пересекает край конечной границы. -
exit-crossing
. Представляет диапазон, в течение которого основной блок пересекает границу начальной границы. -
contain
. Представляет диапазон, в течение которого основной блок либо полностью содержится, либо полностью покрывает диапазон видимости прогресса просмотра в области прокрутки. Это зависит от того, выше или короче объект скроллера.
Используйте инструмент, расположенный по адресу https://goo.gle/view-timeline-range-tool , чтобы увидеть, что представляет собой каждый диапазон и как проценты влияют на начальную и конечную позиции.
- Поскольку начальный и конечный диапазоны здесь одинаковы и используются смещения по умолчанию, упростите
animation-range
до одного имени диапазона анимации:
src/styles.css
.gallery__entry {
animation: linear animate-in;
animation-duration: auto;
animation-timeline: view(inline);
animation-range: entry;
}
Затухание изображений галереи
- Чтобы затемнить изображения при выходе из скроллера, вы можете сделать то же самое, что и при анимации, но выбрать другой диапазон.
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;
}
Ключевые кадры animate-in
будут применены к диапазону entry
, а ключевые кадры animate-out
— к диапазону exit
.
Подтвердите свои изменения
Если все прошло хорошо, теперь у вас должно быть следующее:
Если нет, проверьте ветку кода solution-step-3
.
7. Анимируйте изображения галереи при их входе и выходе из области прокрутки, используя один набор ключевых кадров.
Случай для одного набора ключевых кадров
Вместо прикрепления двух анимаций к разным диапазонам можно создать один набор ключевых кадров, который уже содержит информацию о диапазоне.
Форма ключевых кадров выглядит следующим образом:
@keyframes keyframes-name {
range-name range-offset {
...
}
range-name range-offset {
...
}
}
- Объедините ключевые кадры появления и исчезновения следующим образом:
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%);
}
}
- Когда информация о диапазоне присутствует в ключевых кадрах, вам больше не нужно указывать
animation-range
отдельно. Прикрепите ключевые кадры как свойствоanimation
.
src/styles.css
.gallery__entry {
animation: linear animate-in-and-out both;
animation-duration: auto;
animation-timeline: view(inline);
}
Подтвердите свои изменения
Если все прошло хорошо, вы должны получить тот же результат, что и на предыдущем шаге. Если нет, проверьте ветку кода solution-step-4
.
8. Поздравляем!
Вы завершили эту лабораторную работу и теперь знаете, как создавать временные шкалы прогресса прокрутки и просматривать временные шкалы прогресса в CSS!
Узнать больше
Ресурсы: