Scroll-linked и ScrollTimeline анимация

0 1

Мы рассмотрели некоторые варианты использования в предыдущем разделе, посвященном 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-анимацию, в которой полоса находится вверху страницы, и:

Изменяет цвет от красного до темно-красного

Scroll-linked и ScrollTimeline анимация

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();

1234567891011121314new 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’, } );

1234567891011document.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’), ], });

12345678const 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();

12345678new Animation(  new KeyframeEffect(    document.querySelector(‘#progress’),    { transform: [‘scaleX(0)’, ‘scaleX(1)’], },    { duration: 1, fill: ‘forwards’ }  ),  myScrollTimeline).play();

CodePen Embed Fallback

При использовании синтаксиса Element.animate() установите его как параметр timeline:

Scroll-linked и ScrollTimeline анимация

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

JavaScript document.querySelector(“#progress”).animate( { transform: [“scaleX(0)”, “scaleX(1)”] }, { duration: 1, fill: “forwards”, timeline: myScrollTimeline } );

12345678910document.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’;

1import ‘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 }, ], }), } );

123456789101112131415161718192021const $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

Оставьте ответ