Воспроизведение в обратном направлении

В библиотеке Lottie Web управление направлением анимации основано на внутреннем счётчике кадров и параметре направления проигрывания, который может принимать значения 1 (вперёд) и -1 (назад). Обратное воспроизведение не является отдельным режимом анимации — это изменение логики движения по временной шкале композиции.

Ключевой механизм реализован через метод:

animation.setDirection(direction);

где:

  • 1 — стандартное воспроизведение от начала к концу
  • -1 — воспроизведение от конца к началу

Базовая модель обратного воспроизведения

При обычном запуске анимация проходит кадры последовательно:

0 → 1 → 2 → 3 → ... → N

При обратном направлении:

N → N-1 → N-2 → ... → 0

Система не пересчитывает ключевые кадры, а лишь меняет инкремент индекса текущего кадра на отрицательный.


Запуск анимации в обратном направлении

Обратное воспроизведение требует установки начальной позиции на конец композиции:

const animation = lottie.loadAnimation({
  container: document.getElementById('anim'),
  renderer: 'svg',
  loop: false,
  autoplay: false,
  path: 'animation.json'
});

animation.goToAndStop(animation.totalFrames, true);
animation.setDirection(-1);
animation.play();

Особенность поведения

Если не установить стартовую позицию в конец, анимация начнёт движение назад из текущего кадра, что может привести к визуально непредсказуемому результату.


Управление направлением во время проигрывания

Направление можно изменять динамически без остановки анимации:

animation.setDirection(-1);

или обратно:

animation.setDirection(1);

После смены направления необходимо повторно вызвать play(), если анимация была остановлена.


Использование currentFrame как основы управления

Полный контроль обратного воспроизведения часто строится вокруг свойства:

animation.currentFrame

Пример логики ручного управления:

function reverseStep(anim) {
  anim.goToAndStop(anim.currentFrame - 1, true);

  if (anim.currentFrame <= 0) {
    anim.stop();
  }
}

Такой подход используется при необходимости синхронизации с внешним таймером или игровым циклом.


Скорость и отрицательные значения

Метод:

animation.setSpeed(speed);

принимает положительные значения. Однако обратное направление не реализуется через отрицательную скорость в Lottie Web. Попытка использовать:

animation.setSpeed(-1);

не даёт корректного результата, поскольку направление контролируется отдельно через setDirection.


Обратное воспроизведение с зацикливанием

При включённом loop: true поведение обратной анимации зависит от точки старта:

const animation = lottie.loadAnimation({
  container: document.getElementById('anim'),
  renderer: 'svg',
  loop: true,
  autoplay: false,
  path: 'animation.json'
});

Сценарий 1: старт с конца

animation.goToAndStop(animation.totalFrames, true);
animation.setDirection(-1);
animation.play();

Анимация будет циклически двигаться от конца к началу.

Сценарий 2: старт с начала

animation.goToAndStop(0, true);
animation.setDirection(-1);
animation.play();

В этом случае при достижении кадра 0 поведение зависит от внутреннего цикла — возможен резкий скачок в конец композиции.


События завершения при обратном воспроизведении

Lottie использует событие:

animation.addEventListener('complete', () => {});

При обратном направлении событие complete срабатывает при достижении первого кадра (0), а не последнего.

Пример:

animation.setDirection(-1);
animation.play();

animation.addEventListener('complete', () => {
  animation.stop();
});

Обратное воспроизведение сегментов

Метод:

animation.playSegments([start, end], forceFlag);

может использоваться вместе с направлением.

Прямой сегмент

animation.playSegments([0, 60], true);

Обратный сегмент

animation.setDirection(-1);
animation.playSegments([60, 0], true);

Важно учитывать, что сегмент должен быть задан в соответствии с направлением, иначе поведение становится нелогичным: Lottie интерпретирует диапазон как линейный путь, но направление влияет на шаг кадров.


Ручная реализация обратного проигрывания

В некоторых случаях встроенного setDirection(-1) недостаточно, особенно при сложных синхронизациях. Тогда используется ручной контроль кадров:

let frame = animation.totalFrames;

function reverseLoop() {
  frame--;

  animation.goToAndStop(frame, true);

  if (frame <= 0) {
    frame = animation.totalFrames;
  }

  requestAnimationFrame(reverseLoop);
}

reverseLoop();

Такой подход позволяет полностью контролировать:

  • скорость
  • паузы
  • нелинейные переходы
  • синхронизацию с внешними данными

Влияние renderer на обратное воспроизведение

SVG renderer

Наиболее предсказуемое поведение. Кадры перестраиваются как DOM-структура.

Canvas renderer

Обратное воспроизведение может быть менее плавным при сложных композициях из-за перерисовки холста.

HTML renderer

Редко используется, но при обратном проигрывании может возникать задержка из-за перерасчёта стилей.


Частые проблемы обратного направления

Резкий скачок в начало или конец

Возникает при отсутствии явной установки стартового кадра.

Решение:

animation.goToAndStop(animation.totalFrames, true);
animation.setDirection(-1);

Несинхронизированное событие complete

При быстром переключении направления событие может срабатывать неожиданно.

Решение — сброс обработчиков перед сменой направления:

animation.removeEventListener('complete');

Конфликт loop и setDirection

При активном loop и частой смене направления возможны «петли» без стабильной точки остановки. В таких сценариях управление лучше переводить на ручной контроль кадров.


Сочетание обратного воспроизведения и паузы

Обратное направление часто используется как «откат» состояния интерфейса:

animation.goToAndPlay(animation.totalFrames, true);
animation.setDirection(-1);

setTimeout(() => {
  animation.pause();
}, 500);

Также возможно точечное управление:

animation.pause();
animation.setDirection(-1);
animation.play();

Работа с несколькими состояниями анимации

При сложных UI-сценариях обратное воспроизведение комбинируется с состояниями:

  • открытие → прямое воспроизведение
  • закрытие → обратное воспроизведение
  • переключение вкладок → сегменты вперёд и назад

Пример:

function open() {
  animation.setDirection(1);
  animation.playSegments([0, 45], true);
}

function close() {
  animation.setDirection(-1);
  animation.playSegments([45, 0], true);
}

Особенности временной шкалы при реверсе

Lottie остаётся строго кадровой системой. Обратное воспроизведение не изменяет:

  • ключевые кадры
  • easing кривые
  • структуру анимации

Изменяется только направление итерации по уже рассчитанной временной шкале.

Это означает, что сложные easing-кривые при реверсе сохраняют форму, но визуально могут восприниматься иначе из-за инверсии скорости движения между ключевыми точками.


Практическое применение реверса

Обратное воспроизведение используется в интерфейсах:

  • анимации закрытия модальных окон
  • откат состояний интерфейса
  • индикация отмены действий
  • интерактивные переключатели
  • переходы между экранами

В таких сценариях важно учитывать момент остановки и точку синхронизации с UI-состоянием, так как Lottie не управляет логикой приложения, а лишь визуальным представлением.