В модели воспроизведения Lottie Web анимация рассматривается как непрерывная временная шкала кадров, где каждый кадр соответствует состоянию композиции. Программная навигация по сегментам строится на управлении диапазонами этой шкалы, позволяя изолировать части анимации и воспроизводить их как самостоятельные сценарии.
Сегмент в контексте Lottie Web — это пара значений
[startFrame, endFrame], задающая диапазон кадров внутри
общей композиции. Работа с сегментами становится ключевым механизмом
построения интерфейсных состояний, микроанимаций и управляемых
переходов.
В основе сегментной навигации лежит дискретная шкала кадров:
totalFrames — общее количество кадров анимацииframeRate — частота кадров, определяющая временную
интерпретациюcurrentFrame — текущая позиция воспроизведенияКаждый сегмент опирается на эти значения и работает в пределах общей временной оси.
const animation = lottie.loadAnimation({
container: document.getElementById('anim'),
renderer: 'svg',
loop: false,
autoplay: false,
path: 'data.json'
});
Основной метод управления сегментами — playSegments. Он
принимает массив диапазонов или один диапазон и флаг принудительного
переключения.
animation.playSegments([10, 60], true);
В этом случае:
true принудительно сбрасывает текущую очередь
анимацииПри использовании нескольких сегментов возможно последовательное воспроизведение:
animation.playSegments([[0, 30], [30, 90]], true);
Каждый сегмент отрабатывает как независимый блок.
Сегменты не существуют как отдельные сущности внутри JSON-файла Lottie. Они формируются на уровне runtime. Это означает:
Такой подход позволяет создавать:
При экспорте из After Effects в JSON могут присутствовать маркеры (markers). Они позволяют задавать логические сегменты внутри композиции.
Типичная структура маркера:
"markers": [
{
"tm": 0,
"dr": 30,
"cm": "intro"
},
{
"tm": 30,
"dr": 60,
"cm": "loop"
}
]
tm — стартовый кадрdr — длительностьcm — имя сегментаХотя Lottie Web не предоставляет прямого API для работы с именами маркеров, они используются через внешнюю обработку:
const segments = {
intro: [0, 30],
loop: [30, 60],
exit: [60, 90]
};
animation.playSegments(segments.loop, true);
Такая схема часто применяется в архитектуре состояний.
Сегмент может воспроизводиться как вперёд, так и назад, если изменять направление через управление кадрами.
animation.setDirection(-1);
animation.playSegments([60, 10], true);
Обратный порядок кадров требует корректного задания диапазона.
Особенности:
start > end интерпретируется как обратное
воспроизведениеСегмент может быть зациклен через комбинацию loop и
повторного вызова playSegments.
animation.loop = true;
animation.playSegments([20, 50], true);
В этом случае цикл ограничивается диапазоном сегмента, а не всей композицией.
Альтернативный подход — ручной контроль:
animation.addEventListener('complete', () => {
animation.playSegments([20, 50], true);
});
Сегментная навигация часто связывается с UI-событиями:
button.addEventListener('mouseenter', () => {
animation.playSegments([0, 20], true);
});
button.addEventListener('mouseleave', () => {
animation.playSegments([20, 40], true);
});
Каждое состояние UI соответствует отдельному диапазону кадров.
Повторный вызов playSegments с true
обрывает текущую анимацию:
animation.playSegments([0, 100], true);
animation.playSegments([100, 140], true);
Первый сегмент будет остановлен и заменён вторым.
Если требуется мягкое переключение, используется очередь событий:
animation.queue = [[0, 100], [100, 140]];
(реализация очереди создаётся на уровне приложения, так как встроенного механизма нет)
Контроль позиции внутри сегмента выполняется через
currentFrame:
const frame = animation.currentFrame;
Для ограничения в пределах сегмента используется нормализация:
function clamp(frame, start, end) {
return Math.max(start, Math.min(end, frame));
}
Плавные переходы требуют ручного интерполирования между диапазонами:
function transitionTo(next) {
const current = animation.currentFrame;
animation.playSegments(
[current, next[1]],
true
);
}
Такая схема позволяет избежать резких скачков состояния.
Скорость воспроизведения влияет на восприятие сегмента:
animation.setSpeed(1.5);
animation.playSegments([10, 80], true);
При увеличении скорости:
Сегменты могут вычисляться на лету:
function buildSegment(progress, size) {
return [progress, progress + size];
}
animation.playSegments(buildSegment(20, 40), true);
Это позволяет создавать адаптивные анимации, зависящие от состояния приложения.
В больших анимациях сегментирование используется для:
Пример структуры:
const stateSegments = {
loading: [0, 45],
success: [45, 90],
error: [90, 130]
};
При работе с сегментами необходимо учитывать:
Сегменты остаются логическим слоем поверх временной шкалы, а не частью самой композиции.