Оркестровка анимаций с обещаниями, повышение производительности с помощью заменяемых анимаций, более плавная анимация с помощью составных режимов и многое другое.
Опубликовано: 27 мая 2020 г.
При правильном использовании анимация улучшает восприятие и запоминание вашего бренда пользователями , направляет действия пользователей и помогает им ориентироваться в вашем приложении, предоставляя контекст в цифровом пространстве.
API веб-анимации — это инструмент, позволяющий разработчикам писать императивные анимации с помощью JavaScript . Он был написан для поддержки как CSS-анимации, так и реализаций переходов, а также позволяет разрабатывать будущие эффекты, а также составлять и синхронизировать существующие эффекты.
В то время как Firefox и Safari уже реализовали полный набор функций спецификации, Chromium 84 добавляет в Chrome и Edge множество ранее неподдерживаемых функций, обеспечивая кроссбраузерную совместимость.

Начиная
Создание анимации с помощью API веб-анимации должно показаться вам очень знакомым, если вы использовали правила @keyframe
. Сначала вам нужно создать объект Keyframe. Вот как это может выглядеть в CSS:
@keyframes openAnimation {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
В JavaScript это будет выглядеть так :
const openAnimation = [
{ transform: 'scale(0)' },
{ transform: 'scale(1)' },
];
Где задаются параметры анимации в CSS:
.modal {
animation: openAnimation 1s 1 ease-in;
}
вы бы установили в JS:
document.querySelector('.modal').animate(
openAnimation, {
duration: 1000, // 1s
iterations: 1, // single iteration
easing: 'ease-in' // easing function
}
);
Количество кода примерно такое же, но с JavaScript вы получаете пару суперспособностей, которых нет с одним только CSS. Это включает в себя возможность упорядочивать эффекты и улучшенный контроль над их состояниями воспроизведения.
Помимо element.animate()
Однако с обновлением API веб-анимации больше не ограничивается анимациями, созданными с помощью element.animate()
. Мы также можем управлять анимациями и переходами CSS.
getAnimations()
— это метод, который возвращает все анимации элемента независимо от того, был ли он создан с помощью element.animate()
или с помощью правил CSS (анимация или переход CSS). Вот пример того, как это выглядит:
Сначала вы "get"
ключевые кадры для перехода, чтобы определить, откуда мы переходим. Затем вы создаете две новые анимации непрозрачности, включающие эффект перекрестного затухания. После завершения перекрестного затухания вы удаляете копию.
Как организовать анимацию с помощью обещаний
В Chromium 84 теперь есть два метода, которые можно использовать с обещаниями: animation.ready
и animation.finished
.
-
animation.ready
позволяет дождаться вступления в силу отложенных изменений (то есть переключения между методами управления воспроизведением, такими как воспроизведение и пауза). -
animation.finished
предоставляет средства для выполнения пользовательского кода JavaScript после завершения анимации.
Продолжая наш пример, создадим организованную цепочку анимации с помощью animation.finished
. Здесь у вас есть вертикальное преобразование ( scaleY
), за которым следует горизонтальное преобразование ( scaleX
), за которым следует изменение непрозрачности дочернего элемента:
const transformAnimation = modal.animate(openModal, openModalSettings);
transformAnimation.finished.then(() => { text.animate(fadeIn, fadeInSettings)});
Мы связали эти анимации с помощью animation.finished.then()
перед выполнением следующего набора анимаций в цепочке. Таким образом, анимации появляются по порядку, и вы даже применяете эффекты к разным целевым элементам с разными наборами параметров (такими как скорость и простота).
В CSS это было бы обременительно для воссоздания, особенно при применении уникальных, но последовательных анимаций к нескольким элементам. Вам пришлось бы использовать @keyframe
, отсортировать правильные проценты времени для размещения анимаций и использовать animation-delay
перед запуском анимаций в последовательности.
Пример: воспроизведение, пауза и перемотка назад
Что может открываться, должно закрываться! К счастью, начиная с Chromium 39 , API веб-анимации предоставил нам возможность воспроизводить, приостанавливать и отменять анимацию.
Вы можете взять ранее показанную анимацию и придать ей плавную, обратную анимацию при повторном нажатии кнопки с помощью .reverse()
. Таким образом, вы можете создать более плавное и контекстное взаимодействие для нашего модального окна.
Что вы можете сделать, так это создать две анимации с ожиданием воспроизведения ( openModal
и встроенное преобразование непрозрачности), а затем приостановить одну из анимаций, отложив ее до завершения другой. Затем вы можете использовать обещания, чтобы дождаться завершения каждой из них перед воспроизведением. Наконец, вы можете проверить, установлен ли флаг, а затем отменить каждую анимацию.
Пример: Динамическое взаимодействие с частичными ключевыми кадрами
selector.animate([{transform: `translate(${x}px, ${y}px)`}],
{duration: 1000, fill: 'forwards'});
В этом примере есть только один ключевой кадр и не указано начальное положение. Это пример использования частичных ключевых кадров . Обработчик мыши делает здесь несколько вещей: он устанавливает новое конечное положение и запускает новую анимацию. Новое начальное положение выводится из текущего базового положения.
Новые переходы могут быть запущены во время выполнения существующих. Это означает, что текущий переход прерывается и создается новый.
Улучшения производительности с заменяемыми анимациями
При создании анимаций на основе событий, таких как 'mousemove'
, каждый раз создается новая анимация, что может быстро потреблять память и снижать производительность. Для решения этой проблемы в Chromium 83 были введены заменяемые анимации, позволяющие автоматическую очистку, когда готовые анимации помечаются как заменяемые и автоматически удаляются, если заменяются другой готовой анимацией. Рассмотрим следующий пример:
elem.addEventListener('mousemove', evt => {
rectangle.animate(
{ transform: translate(${evt.clientX}px, ${evt.clientY}px) },
{ duration: 500, fill: 'forwards' }
);
});
Каждый раз, когда мышь движется, браузер пересчитывает положение каждого шара в следе кометы и создает анимацию для этой новой точки. Теперь браузер знает, что нужно удалить старые анимации (разрешая замену), когда:
- Анимация завершена.
- Выше в композитном порядке есть одна или несколько анимаций, которые также завершены.
- Новые анимации анимируют те же свойства.
Вы можете точно узнать, сколько анимаций было заменено, подсчитав счетчик для каждой удаленной анимации, используя anim.onremove
для запуска счетчика.
Есть несколько дополнительных свойств и методов, которые позволят вам еще лучше управлять анимацией:
-
animation.replaceState
предоставляет средства отслеживания того, является ли анимация активной, сохраненной или удаленной. -
animation.commitStyles()
обновляет стиль элемента на основе базового стиля вместе со всеми анимациями элемента в составном порядке. -
animation.persist()
помечает анимацию как незаменяемую.
Более плавная анимация с композитными режимами
С API веб-анимации теперь можно задать составной режим анимаций, то есть они могут быть аддитивными или накопительными, в дополнение к режиму по умолчанию «replace». Составные режимы позволяют разработчикам писать отдельные анимации и контролировать, как комбинируются эффекты. Теперь поддерживаются три составных режима: 'replace'
(режим по умолчанию), 'add'
и 'accumulate'
.
При компоновке анимаций разработчик может написать короткие, отдельные эффекты и увидеть их объединенными вместе. В следующем примере мы применяем поворот и масштабирование ключевого кадра к каждому блоку, с единственной настройкой — композитным режимом, добавленным в качестве опции:
В стандартном композитном режиме 'replace'
финальная анимация заменяет свойство transform и заканчивается на rotate(360deg) scale(1.4)
. Для 'add'
composite добавляется вращение и умножается масштаб, что приводит к конечному состоянию rotate(720deg) scale(1.96)
. 'accumulate'
объединяет преобразования, что приводит к rotate(720deg) scale(1.8)
. Для получения дополнительной информации о тонкостях этих композитных режимов ознакомьтесь с перечислениями CompositeOperation и CompositeOperationOrAuto из спецификации Web Animations.
Взгляните на следующий пример элемента пользовательского интерфейса:
Здесь две top
анимации объединены. Первая — макроанимация, которая перемещает раскрывающийся список на всю высоту самого меню как эффект слайда сверху страницы, а вторая — микроанимация, которая применяет небольшой отскок при ударе о дно. Использование композитного режима 'add'
обеспечивает более плавный переход.
const dropDown = menu.animate(
[
{ top: `${-menuHeight}px`, easing: 'ease-in' },
{ top: 0 }
], { duration: 300, fill: 'forwards' });
dropDown.finished.then(() => {
const bounce = menu.animate(
[
{ top: '0px', easing: 'ease-in' },
{ top: '10px', easing: 'ease-out' },
{ ... }
], { duration: 300, composite: 'add' });
});
Что ждет API веб-анимации дальше?
Все это захватывающие дополнения к возможностям анимации в современных браузерах, и еще больше дополнений на подходе. Ознакомьтесь с этими будущими спецификациями для дальнейшего чтения о том, что будет дальше: