Событие enterFrame является одним из ключевых механизмов
синхронизации логики с проигрыванием анимации в Lottie Web. Оно
вызывается на каждом шаге рендеринга кадра и позволяет привязывать
произвольное поведение к текущему состоянию анимации.
Внутри движка Lottie анимация работает через цикл обновления,
основанный на requestAnimationFrame. На каждом цикле
вычисляется текущий кадр, после чего происходит рендеринг композиции и
генерация событий. enterFrame эмитится непосредственно
после пересчёта состояния текущего кадра.
Основная характеристика события — высокая частота вызова. Оно срабатывает:
Событие регистрируется через стандартный механизм слушателей:
const animation = lottie.loadAnimation({
container: document.getElementById('anim'),
renderer: 'svg',
loop: true,
autoplay: true,
path: 'animation.json'
});
animation.addEventListener('enterFrame', function (event) {
console.log(event.currentFrame);
});
Каждый вызов обработчика содержит объект состояния текущего кадра.
Объект, передаваемый в обработчик enterFrame, содержит
данные о текущем положении анимации:
currentFrame — текущий кадр анимацииtotalFrames — общее количество кадров композицииdirection — направление воспроизведения (1 или -1)time или эквивалентное значение прогресса времениЭти данные отражают текущее состояние временной шкалы и позволяют синхронизировать внешнюю логику с анимацией.
Во время проигрывания анимации происходит последовательность операций:
enterFrameТаким образом, событие находится на границе между обновлением состояния и визуальным выводом.
На уровне интеграции с DOM enterFrame часто используется
для привязки интерфейсных элементов к анимации. Типовые сценарии:
Пример синхронизации прогресса:
animation.addEventListener('enterFrame', function (e) {
const progress = e.currentFrame / e.totalFrames;
document.querySelector('.progress').style.width = (progress * 100) + '%';
});
Высокая частота вызова делает enterFrame чувствительным
к нагрузке. Любая тяжёлая операция внутри обработчика напрямую влияет на
плавность анимации.
Типичные ограничения:
Оптимизация обычно строится на переносе вычислений в отдельные структуры состояния:
let cachedValue = 0;
animation.addEventListener('enterFrame', function (e) {
cachedValue = e.currentFrame * 2;
});
Поле direction позволяет учитывать режим проигрывания
анимации:
1 — прямое воспроизведение-1 — обратное воспроизведениеЭто особенно важно при реализации интерактивных сценариев, где анимация может перемещаться в обе стороны.
animation.addEventListener('enterFrame', function (e) {
if (e.direction === -1) {
console.log('обратное воспроизведение');
}
});
В отличие от событий вроде complete или
loopComplete, enterFrame не сигнализирует о
переходах состояния. Оно отражает непрерывный процесс движения временной
шкалы.
Ключевые отличия:
При управлении анимацией через внешний ввод (скролл, drag, pointer
movement) enterFrame используется как точка привязки для
пересчёта состояния:
Пример привязки к скроллу:
window.addEventListener('scroll', function () {
const scrollTop = window.scrollY;
const maxScroll = document.body.scrollHeight - window.innerHeight;
const frame = (scrollTop / maxScroll) * animation.totalFrames;
animation.goToAndStop(frame, true);
});
Даже при использовании внешнего управления событие
enterFrame продолжает отражать текущее состояние после
каждого обновления кадра.
Поведение события не зависит от выбранного рендерера, однако нагрузка различается:
enterFrameС точки зрения API событие остаётся идентичным, различается только стоимость его частого вызова.
При работе с несколькими экземплярами Lottie синхронизация часто строится через общий обработчик:
function sync(e) {
animation2.goToAndStop(e.currentFrame, true);
}
animation1.addEventListener('enterFrame', sync);
Такой подход позволяет выстраивать композиции из независимых анимаций с единым временным источником.
Из-за высокой частоты вызова enterFrame становится
критическим участком производительности. Основные ограничения:
При некорректном использовании возникает деградация плавности кадров и увеличение времени рендеринга каждого цикла анимации.