Scroll-linked и ScrollTimeline анимация
Мы рассмотрели некоторые варианты использования в предыдущем разделе, посвященном CSS-трюкам, все они управляются правилом CSS @scroll-timeline и свойством animation-timeline, эти варианты использования были созданы с использованием только HTML и CSS. Без JavaScript.
Помимо интерфейса CSS, который мы получаем со спецификацией scroll-connected Animations, в ней также описан интерфейс JavaScript для реализации scroll-linked анимаций. Давайте рассмотрим класс ScrollTimeline и то, как его использовать с API веб-анимации.
API веб-анимации: краткое резюме
Содержание статьи:
API веб-анимации (WAAPI) уже рассматривался в CSS-Tricks. Вкратце, этот API позволяет нам создавать анимации и управлять их воспроизведением с помощью JavaScript. Возьмем, к примеру, следующую CSS-анимацию, в которой полоса находится вверху страницы, и:
Изменяет цвет от красного до темно-красного
JavaScript. Быстрый старт
Изучите основы JavaScript на практическом примере по созданию веб-приложения
Изменяет ширину от нуля до полной ширины контейнера (путем масштабирования оси x).
CodePen Embed Fallback
При переводе анимации CSS в ее аналог WAAPI код становится следующим:
JavaScript new Animation( new KeyframeEffect( document.querySelector(‘.progressbar’), { backgroundColor: [‘red’, ‘darkred’], transform: [‘scaleX(0)’, ‘scaleX(1)’], }, { duration: 2500, fill: ‘forwards’, easing: ‘linear’, } ) ).play();
1234567891011121314 | new Animation( new KeyframeEffect( document.querySelector(‘.progressbar’), { backgroundColor: [‘red’, ‘darkred’], transform: [‘scaleX(0)’, ‘scaleX(1)’], }, { duration: 2500, fill: ‘forwards’, easing: ‘linear’, } )).play(); |
CodePen Embed Fallback
Или, в качестве альтернативы, используйте более краткий синтаксис с использованием Element.animate():
JavaScript document.querySelector(‘.progressbar’).animate( { backgroundColor: [‘red’, ‘darkred’], transform: [‘scaleX(0)’, ‘scaleX(1)’], }, { duration: 2500, fill: ‘forwards’, easing: ‘linear’, } );
1234567891011 | document.querySelector(‘.progressbar’).animate( { backgroundColor: [‘red’, ‘darkred’], transform: [‘scaleX(0)’, ‘scaleX(1)’], }, { duration: 2500, fill: ‘forwards’, easing: ‘linear’, }); |
CodePen Embed Fallback
В двух последних примерах мы можем выделить две вещи. Во-первых — объект, описывающий, какие свойства нужно анимировать:
JavaScript { backgroundColor: [‘red’, ‘darkred’], transform: [‘scaleX(0)’, ‘scaleX(1)’], }
1234 | { backgroundColor: [‘red’, ‘darkred’], transform: [‘scaleX(0)’, ‘scaleX(1)’],} |
Во-вторых – объект, который настраивает продолжительность анимации, замедление и т. д.:
JavaScript { duration: 2500, fill: ‘forwards’, easing: ‘linear’, }
12345 | { duration: 2500, fill: ‘forwards’, easing: ‘linear’,} |
Создание и прикрепление шкалы времени прокрутки
Чтобы анимация управлялась с помощью прокрутки, мы можем сохранить существующий код WAAPI, но необходимо расширить его, добавив к нему экземпляр класса ScrollTimeline.
Класс ScrollTimeline позволяет нам описывать AnimationTimeline, чьи значения времени определяются не продолжительностью времени, а прогрессом прокрутки в контейнере прокрутки. Его можно настроить с помощью нескольких опций:
source: Прокручиваемый элемент, прокрутка которого запускает активацию и управляет прогрессом временной шкалы. По умолчанию это document.scrollingElement (т. е. Контейнер прокрутки, который прокручивает весь документ).
orientation: Определяет направление прокрутки, которое запускает активацию и управляет прогрессом временной шкалы. По умолчанию равно vertical.
scrollOffsets: Значения, которые определяет эффективное смещение прокрутки, перемещаясь в направлении, указанном в свойстве orientation. Они представляют собой равноудаленные по ходу выполнения интервалы, в которых активна временная шкала.
Эти параметры передаются в конструктор. Например:
JavaScript const myScrollTimeline = new ScrollTimeline({ source: document.scrollingElement, orientation: ‘block’, scrollOffsets: [ new CSSUnitValue(0, ‘percent’), new CSSUnitValue(100, ‘percent’), ], });
12345678 | const myScrollTimeline = new ScrollTimeline({ source: document.scrollingElement, orientation: ‘block’, scrollOffsets: [ new CSSUnitValue(0, ‘percent’), new CSSUnitValue(100, ‘percent’), ],}); |
Не случайно эти параметры в точности совпадают с дескрипторами CSS @scroll-timeline. Оба подхода позволяют достичь одного и того же результата, разница лишь в использовании языка для их определения.
Чтобы добавить вновь созданный экземпляр ScrollTimeline к анимации, мы передаем его в качестве второго аргумента в конструктор Animation:
JavaScript new Animation( new KeyframeEffect( document.querySelector(‘#progress’), { transform: [‘scaleX(0)’, ‘scaleX(1)’], }, { duration: 1, fill: ‘forwards’ } ), myScrollTimeline ).play();
12345678 | new Animation( new KeyframeEffect( document.querySelector(‘#progress’), { transform: [‘scaleX(0)’, ‘scaleX(1)’], }, { duration: 1, fill: ‘forwards’ } ), myScrollTimeline).play(); |
CodePen Embed Fallback
При использовании синтаксиса Element.animate() установите его как параметр timeline:
JavaScript. Быстрый старт
Изучите основы JavaScript на практическом примере по созданию веб-приложения
JavaScript document.querySelector(“#progress”).animate( { transform: [“scaleX(0)”, “scaleX(1)”] }, { duration: 1, fill: “forwards”, timeline: myScrollTimeline } );
12345678910 | document.querySelector(“#progress”).animate( { transform: [“scaleX(0)”, “scaleX(1)”] }, { duration: 1, fill: “forwards”, timeline: myScrollTimeline }); |
CodePen Embed Fallback
С этим кодом анимация управляется нашим экземпляром ScrollTimelin, а не DocumentTimeline. Текущая экспериментальная реализация в Chromium использует scrollSource вместо source. Вот почему вы видите и source и scrollSource в примерах кода.
Несколько слов о совместимости браузеров
На момент написания статьи только браузер Chromium поддерживает класс ScrollTimeline. К счастью, есть полифил Scroll-Timeline от Роберта Флэка, который мы можем использовать для заполнения неподдерживаемых пробелов во всех других браузерах. Фактически, все демонстрации в этой статье, включают его.
Полифилл доступен в виде модуля и регистрирует себя, если поддержка не обнаружена. Чтобы включить его, добавьте в секцию import своего кода следующий оператор:
JavaScript import ‘https://flackr.github.io/scroll-timeline/dist/scroll-timeline.js’;
1 | import ‘https://flackr.github.io/scroll-timeline/dist/scroll-timeline.js’; |
Полифилл также регистрирует необходимые классы типизированной объектной модели CSS, если браузер не поддерживает их.
Продвинутая временная шкала прокрутки
Помимо абсолютных смещений, scroll-linked анимация также может работать со смещениями на основе элементов. С этим типом смещения, анимация основана на расположении элемента в контейнере прокрутки. Обычно это используется для анимации элемента, когда он входит в область прокрутки, пока он не покинет ее.
Смещение на основе элементов состоит из трех частей:
target: Отслеживаемый элемент DOM.
edge: То, за чем наблюдает ScrollTimeline.
threshold: Число в диапазоне от 0.0 до 1.0 которое указывает, какая часть target видна в области прокрутки edge.
CodePen Embed Fallback
Смещения на основе элементов также поддерживаются интерфейсом ScrollTimeline. Чтобы определить его, используйте обычный объект:
JavaScript { target: document.querySelector(‘#targetEl’), edge: ‘end’, threshold: 0.5, }
12345 | { target: document.querySelector(‘#targetEl’), edge: ‘end’, threshold: 0.5,} |
Обычно в свойство scrollOffsets передаются два из этих объектов.
JavaScript const $image = document.querySelector(‘#myImage’); $image.animate( { opacity: [0, 1], clipPath: [‘inset(45% 20% 45% 20%)’, ‘inset(0% 0% 0% 0%)’], }, { duration: 1, fill: “both”, timeline: new ScrollTimeline({ scrollSource: document.scrollingElement, timeRange: 1, fill: “both”, scrollOffsets: [ { target: $image, edge: ‘end’, threshold: 0.5 }, { target: $image, edge: ‘end’, threshold: 1 }, ], }), } );
123456789101112131415161718192021 | const $image = document.querySelector(‘#myImage’); $image.animate( { opacity: [0, 1], clipPath: [‘inset(45% 20% 45% 20%)’, ‘inset(0% 0% 0% 0%)’], }, { duration: 1, fill: “both”, timeline: new ScrollTimeline({ scrollSource: document.scrollingElement, timeRange: 1, fill: “both”, scrollOffsets: [ { target: $image, edge: ‘end’, threshold: 0.5 }, { target: $image, edge: ‘end’, threshold: 1 }, ], }), }); |
CodePen Embed Fallback
Вот еще несколько примеров, которые я приготовил.
Секция горизонтальной прокрутки
Пример основан на демонстрации Кэмерона Найта, в которой есть секция горизонтальной прокрутки. Она ведет себя аналогично, но использует ScrollTimeline вместо GSAP ScrollTrigger.
CodePen Embed Fallback
CoverFlow
Помните CoverFlow из iTunes? Что ж, вот версия, построенная на ScrollTimeline:
CodePen Embed Fallback
Эта демонстрация не работает должным образом в Chromium из-за ошибки. Проблема в том, что начальная и конечная позиции рассчитываются неправильно.
CSS или JavaScript?
Нет никакой реальной разницы в использовании CSS или JavaScript для Scroll-linked анимаций, за исключением используемого языка: оба используют одни и те же концепции и конструкции. В духе прогрессивного улучшения я бы выбрал CSS для такого рода эффектов.
Однако, как мы уже говорили ранее, поддержка реализации на основе CSS на момент написания статьи была довольно слабой:
Chromium имеет только экспериментальную реализацию.
Firefox только готовится для внедрения реализации на основе CSS.
Никаких сообщений от Safari пока нет.
Из-за этой плохой поддержки вы наверняка достигнете успеха с JavaScript прямо сейчас. Просто убедитесь, что ваш сайт можно просматривать и использовать при отключенном JavaScript.
Автор: Bramus
Источник: webformyself.com