Web Animation API позволяет определять и управлять анимациями на веб-странице. Для создания анимации у элементов веб-страницы вызывается метод animate()
animate(keyframes, options)
Первый параметр - keyframes представляет определения ключевых кадров. Второй параметр представляет конфигурационные настройки анимации в виде объекта со следующими
свойствами:
delay: задержка (в миллисекундах), после которой запускается анимация
endDelay: задержка (в миллисекундах), после которой завершается анимация
fill: поведение заполнения анимации (возможные значения: none, forwards, backwards, both, auto)
iterationStart: определяет итерацию, в которой активируется определенный эффект анимации
iterations: количество повторений (для бесконечного повторения анимации передается значение infinity)
duration: длительность анимации в миллисекундах
direction: направление анимации (возможные значения: alternate, normal, reverse, alternate-reverse)
easing: поведение анимации (возможные значения: ease, ease-in, ease-out, ease-in-out, cubic-bezier)
Результатом метода animate() является анимация в виде объекта Animation
Настройки, которые можно выполнить с помощью этих двух параметров, аналогичны настройкам анимации в коде CSS. Например, возьмем примитивную анимацию CSS:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>METANIT.COM</title>
<style>
@keyframes frames {
0% {
transform: scale(2);
opacity: 0.2;
}
30% {
transform: scale(3);
opacity: 0.4;
}
60% {
transform: scale(4);
opacity: 0.6;
}
100% {
transform: scale(5);
opacity: 0.8;
}
}
#circle {
width:50px;
height: 50px;
opacity: 0.2;
background-color: red;
margin: 100px;
border-radius: 25px;
animation: frames 500ms ease-in-out 10ms infinite alternate both;
}
</style>
</head>
<body>
<div id="circle"></div>
</body>
</html>
здесь пока нет никакого кода JavaScript, вся анимация задана целиком в CSS. Анимация состоит из отдельных фреймов или состояний, а вся суть анимации заключается в переходе от одного из таких состояний к другому.
Для установки фреймов применяется слово @keyframes. В данном случае набор фреймов называется frames и содержит 4 фрейма, каждый из которых описывает
значения свойств translation и opacity. Например, возьмем следующий фрейм:
30% {
transform: scale(3);
opacity: 0.4;
}
Процентные доли - 30% указывают, что данный фрейм будет выполняться, после прохождения анимацией 30% времени. В данном фрейм к анимируемому элементу применяется
настройка scale(3) - элемент увеличивается в 3 раза. Кроме того с помощью свойства opacity: 0.4 для элемента устанавливается прозрачность в 0.4
Для применения анимации у элемента применяется свойство animation
#circle {
.............
animation: frames 500ms ease-in-out 10ms infinite alternate both;
}
Через стилевое свойство animation устанавливаем фреймы анимации - frames и дополнительные параметры:
500ms: время анимации - 500 миллисекунд (параметр duration)
ease-in-out: поведение анимации (параметр easing)
10ms: задержка при старте анимации - 10 миллисекунд (параметр delay)
Infinity: количество повторений - бесконечно (параметр iterations)
alternate: направление анимации (параметр direction)
both: "заполнение" анимации - 500 миллисекунд (параметр fill)
Таким образом, мы получим пульсирующий круг, который меняет размеры и прозрачность:
Теперь используем Web Animation API и определим ту же самую анимацию в коде JavaScript:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>METANIT.COM</title>
<style>
#circle {
width:50px;
height: 50px;
opacity: 0.2;
background-color: red;
margin: 100px;
border-radius: 25px;
}
</style>
</head>
<body>
<div id="circle"></div>
<script>
const circle = document.getElementById("circle");
// определяем кадры анимации
const frames = [{
transform: "scale(2)",
opacity: 0.2,
offset: 0
},{
transform: "scale(3)",
opacity: 0.4,
offset: 0.3
},{
transform: "scale(4)",
opacity: 0.6,
offset: 0.6
},{
transform: "scale(5)",
opacity: 1.0,
offset: 1
}];
// параметры анимации
const config = {
duration: 500, // время анимации в миллисекундах
easing: "ease-in-out", // поведение анимации
delay: 10, // задержка в миллисекундах
iterations: Infinity, // кол-во повторений
direction: "alternate", // направление анимации
fill: "both" // заполнение поведения анимации
};
// выполняем анимацию
circle.animate(frames, config);
</script>
</body>
</html>
Здесь кадры/фреймы анимации заданы массивом frames, каждый элемент которого имеет три свойства. Например:
{
transform: "scale(3)",
opacity: 0.4,
offset: 0.3
}
Первые два свойства (transform и opacity) - это те же стилевые свойства элемента, которые устанавливались в CSS. Третье свойство - offset
задает момент времени, когда данный кадр должен отображаться в анимации. Так, offset: 0.3 соответствует 30% в CSS.
Если это свойство опущено, отдельные ключевые кадры распределяются равномерно в течение определенной продолжительности.
Второй параметр функции animate() аналогичен дополнительным параметрам анимации, которые устанавливаются в CSS.
Метод animate() возвращает объект Animation, который позволяет управлять анимацией с помощью ряда методов:
pause(): приостанавливает анимацию
play(): возобновляет анимацию
cancel(): отменяет анимацию
finish(): завершает анимацию
Кроме того, с помощью свойства playbackRate можно управлять скоростью анимации. Например:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>METANIT.COM</title>
<style>
#rect {
width:50px;
height: 50px;
background-color: green;
margin-top: 20px;
}
</style>
</head>
<body>
<div>
<button id="pause">Pause</button>
<button id="play">Play</button>
<button id="cancel">Cancel</button>
<button id="faster">Faster</button>
<button id="slower">Slower</button>
</div>
<div id="rect"></div>
<script>
// анимируемый элемент
const rect = document.getElementById("rect");
// фреймы анимации
const frames = [{
marginLeft: "50px",
offset: 0
},{
marginLeft: "100px",
offset: 0.3
},{
marginLeft: "150px",
offset: 0.6
},{
marginLeft: "200px",
offset: 1
}];
// параметры анимации
const config = {
duration: 600,
easing: "ease-in-out",
iterations: Infinity,
direction: "alternate"
};
const animation = rect.animate(frames, config);
document.getElementById("pause").addEventListener("click", () => animation.pause());
document.getElementById("play").addEventListener("click", () => animation.play());
document.getElementById("cancel").addEventListener("click", () => animation.cancel());
// увеличиваем скорость в 2 раза
document.getElementById("faster").addEventListener("click", () => animation.playbackRate *= 2);
// уменьшаем скорость в 2 раза
document.getElementById("slower").addEventListener("click", () => animation.playbackRate /= 2);
</script>
</body>
</html>
В данном случае с помощью набора кадров изменяем свойство "margin-left" у элемента div, который стилизован под зеленный квадрат. А с помощью кнопок управляем его анимацией: