Ранее в этом году Chrome 36 представил метод element.animate как часть более широкой спецификации веб-анимации . Это позволяет создавать эффективные, нативные анимации, написанные императивно, предоставляя разработчикам возможность создавать свои анимации и переходы с наиболее подходящим для них подходом.
Для быстрого освежения знаний вот как можно анимировать облако на экране, выполнив обратный вызов по завершении:
var player = cloud.animate([
{transform: 'translateX(' + start + 'px)'},
{transform: 'translateX(' + end + 'px)'}
], 5000);
player.onfinish = function() {
console.info('Cloud moved across the screen!');
startRaining(cloud);
};
Это само по себе невероятно просто и заслуживает рассмотрения как часть вашего инструментария при создании анимаций или переходов императивно. Однако в Chrome 39 функции управления воспроизведением были добавлены в объект AnimationPlayer
, возвращаемый element.animate
. Ранее, после создания анимации, вы могли только вызвать cancel()
или прослушивать событие finish.
Эти дополнения к воспроизведению открывают новые возможности веб-анимации, превращая анимацию в универсальный инструмент, а не в предписывающий переходы, т. е. «фиксированную» или предопределенную анимацию.
Пауза, перемотка назад или изменение скорости воспроизведения
Начнем с обновления приведенного выше примера, чтобы приостанавливать анимацию при нажатии на облако:
cloud.addEventListener('mousedown', function() {
player.pause();
});
Вы также можете изменить свойство playbackRate
:
function changeWindSpeed() {
player.playbackRate *= (Math.random() * 2.0);
}
Вы также можете вызвать метод reverse()
, который обычно эквивалентен инвертированию текущего playbackRate
(умножению на -1). Однако есть несколько особых случаев:
Если изменение, вызванное методом
reverse()
, приведет к фактическому завершению текущей анимации,currentTime
также инвертируется — например, если отменяется воспроизведение совершенно новой анимации, вся анимация будет воспроизводиться в обратном порядке.Если проигрыватель поставлен на паузу, начнется воспроизведение анимации.
Очистка плеера
AnimationPlayer
теперь позволяет изменять currentTime
во время выполнения анимации. Обычно это значение увеличивается со временем (или уменьшается, если playbackRate
отрицательный). Это может позволить управлять положением анимации извне, возможно, посредством взаимодействия с пользователем. Это обычно называется очисткой .
Например, если ваша HTML-страница представляет небо и вы хотите, чтобы жест перетаскивания изменил положение текущего воспроизводимого облака, вы можете добавить в документ несколько обработчиков:
var startEvent, startEventTime;
document.addEventListener('touchstart', function(event) {
startEvent = event;
startEventTime = players.currentTime;
player.pause();
});
document.addEventListener('touchmove', function(event) {
if (!startEvent) return;
var delta = startEvent.touches[0].screenX -
event.changedTouches[0].screenX;
player.currentTime = startEventTime + delta;
});
При перетаскивании по документу currentTime
будет меняться, чтобы отражать расстояние от вашего исходного события. Вы также можете захотеть возобновить воспроизведение анимации после завершения жеста:
document.addEventListener('touchend', function(event) {
startEvent = null;
player.play();
});
Это можно даже объединить с обратным поведением, в зависимости от того, в каком месте страницы была отведена мышь ( комбинированная демонстрация ).
Вместо того чтобы очищать AnimationPlayer
в ответ на взаимодействие с пользователем, его currentTime
можно также использовать для отображения прогресса или статуса: например, для отображения статуса загрузки.
Полезность здесь в том, что AnimationPlayer
позволяет задать значение и заставить базовую нативную реализацию позаботиться о визуализации его прогресса. В случае загрузки длительность анимации может быть установлена на общий размер загрузки, а currentTime
— на текущий загруженный размер ( demo ).
Переходы и жесты пользовательского интерфейса
Мобильные платформы уже давно стали сферой распространенных жестов: перетаскивание, скольжение, бросание и т. п. Эти жесты, как правило, имеют общую тему: перетаскиваемый компонент пользовательского интерфейса, такой как «потянуть для обновления» в представлении списка или боковая панель, создаваемая с левой стороны экрана.
С помощью веб-анимации подобный эффект очень легко воспроизвести здесь, в сети — на десктопе или на мобильном устройстве. Например, когда жест, управляющий currentTime
завершается:
var steps = [ /* animation steps */ ];
var duration = 1000;
var player = target.animate(steps, duration);
player.pause();
configureStartMoveListeners(player);
var setpoints = [0, 500, 1000];
document.addEventListener('touchend', function(event) {
var srcTime = player.currentTime;
var dstTime = findNearest(setpoints, srcTime);
var driftDuration = dstTime - srcTime;
if (!driftDuration) {
runCallback(dstTime);
return;
}
var driftPlayer = target.animate(steps, {
duration: duration,
iterationStart: Math.min(srcTime, dstTime) / duration,
iterations: Math.abs(driftDuration) / duration,
playbackRate: Math.sign(driftDuration)
});
driftPlayer.onfinish = function() { runCallback(dstTime); };
player.currentTime = dstTime;
});
Это создает дополнительную анимацию, которая выполняет «дрейф». Это воспроизводится между тем местом, где жест был завершен, и нашей известной хорошей целью.
Это работает, поскольку анимации имеют приоритет, основанный на порядке их создания: в этом случае, driftPlayer
будет иметь приоритет над player. Когда driftPlayer
завершится, он и его эффекты исчезнут. Однако его конечное время будет соответствовать currentTime базового player, поэтому ваш пользовательский интерфейс останется согласованным.
Наконец, если вам нравятся котята, есть демо-приложение , которое демонстрирует эти жесты. Оно дружелюбно к мобильным устройствам и использует полифил для обратной совместимости, так что попробуйте загрузить его на свое мобильное устройство!
Идите вперед и элемент.анимируйте
Метод element.animate
сейчас просто великолепен — используете ли вы его для простых анимаций или используете возвращаемый им AnimationPlayer
другими способами.
Эти две функции также полностью поддерживаются в других современных браузерах через легковесный полифилл . Этот полифилл также выполняет обнаружение функций, поэтому по мере того, как поставщики браузеров реализуют спецификацию, эта функция будет становиться только быстрее и лучше с течением времени.
Спецификация Web Animations также продолжит развиваться. Если вам интересно поиграться с будущими функциями, они также доступны в более подробном полифилле: web-animations-next .