Понимание временной шкалы анимации

В основе анимации лежит управление временем: когда начинается эффект, как долго он длится, с какой скоростью изменяются параметры и как синхронизируются несколько анимаций. В библиотеке mo.js временная шкала реализуется через объект Timeline, который позволяет объединять и координировать множество анимационных сущностей.

Временная шкала — это контейнер, управляющий последовательностью и параллельным выполнением анимаций, обеспечивающий контроль над запуском, паузой, повторением и синхронизацией.


Объект Timeline

mojs.Timeline представляет собой управляющую структуру, в которую добавляются отдельные анимации (Tween, Shape, Burst и др.).

Базовое создание

const timeline = new mojs.Timeline();

После создания временная шкала пуста и не выполняет никаких действий, пока в неё не добавлены элементы.


Добавление анимаций

Анимации добавляются методом add:

const circle = new mojs.Shape({
  shape: 'circle',
  radius: { 0: 50 },
  duration: 1000
});

timeline.add(circle);

Особенности:

  • Можно добавлять несколько анимаций одновременно
  • Порядок добавления не влияет на порядок выполнения (если не используются задержки)
  • Все добавленные элементы запускаются синхронно по умолчанию

Параллельное выполнение

По умолчанию все анимации внутри Timeline выполняются одновременно:

timeline.add(circle1, circle2, circle3);

Все три анимации стартуют в один момент времени.


Последовательность через delay

Для создания последовательности используется параметр delay:

const first = new mojs.Shape({
  delay: 0,
  duration: 500
});

const second = new mojs.Shape({
  delay: 500,
  duration: 500
});

Добавляя такие элементы в Timeline, можно выстроить цепочку:

timeline.add(first, second);

Управление воспроизведением

Запуск

timeline.play();

Пауза

timeline.pause();

Перезапуск

timeline.replay();

Остановка

timeline.stop();

Повторение анимации

Timeline поддерживает циклическое воспроизведение:

const timeline = new mojs.Timeline({
  repeat: 3
});

Бесконечный цикл

const timeline = new mojs.Timeline({
  repeat: 9999
});

Управление скоростью

Скорость воспроизведения регулируется параметром speed:

timeline.speed(2); // в 2 раза быстрее
timeline.speed(0.5); // в 2 раза медленнее

Смещение времени (offset)

Каждый элемент может иметь смещение относительно начала Timeline:

timeline.add(
  new mojs.Shape({ duration: 500 }),
  new mojs.Shape({ duration: 500 }).then({ delay: 300 })
);

Также можно использовать shift:

circle.tune({ delay: 200 });

Общая длительность Timeline

Общая длительность определяется автоматически на основе:

  • длительности всех анимаций
  • их задержек (delay)
  • повторений (repeat)

Получение длительности:

console.log(timeline._props.duration);

Синхронизация анимаций

Timeline решает ключевую задачу — синхронизацию:

Пример синхронизации

const scale = new mojs.Shape({
  scale: { 0: 1 },
  duration: 1000
});

const fade = new mojs.Shape({
  opacity: { 0: 1 },
  duration: 1000
});

timeline.add(scale, fade);

Обе анимации идут строго одновременно.


Вложенные Timeline

Временные шкалы можно вкладывать друг в друга:

const childTimeline = new mojs.Timeline();
childTimeline.add(circle1, circle2);

const mainTimeline = new mojs.Timeline();
mainTimeline.add(childTimeline);

Возможности:

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

Связь с Tween

Tween — низкоуровневый инструмент, который также может использоваться внутри Timeline:

const tween = new mojs.Tween({
  duration: 1000,
  onUpdate: (progress) => {
    console.log(progress);
  }
});

timeline.add(tween);

Контроль прогресса

Timeline позволяет вручную управлять прогрессом:

timeline.setProgress(0.5);

Где:

  • 0 — начало
  • 1 — конец

Это используется для:

  • синхронизации со скроллом
  • интерактивных интерфейсов
  • пользовательского управления

Связка с пользовательскими событиями

Timeline удобно использовать в обработчиках событий:

button.addEventListener('click', () => {
  timeline.replay();
});

Продвинутые техники

Комбинирование с then()

const shape = new mojs.Shape({
  x: { 0: 100 },
  duration: 500
}).then({
  x: { 100: 0 },
  duration: 500
});

Такие цепочки автоматически учитываются Timeline.


Управление несколькими Timeline

const t1 = new mojs.Timeline();
const t2 = new mojs.Timeline();

const master = new mojs.Timeline();
master.add(t1, t2);

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


Асинхронное управление

Timeline может использоваться вместе с промисами:

timeline.play();

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

Практический пример

const circle = new mojs.Shape({
  shape: 'circle',
  fill: 'red',
  radius: { 0: 40 },
  duration: 600
});

const square = new mojs.Shape({
  shape: 'rect',
  fill: 'blue',
  x: { 0: 100 },
  delay: 300,
  duration: 600
});

const timeline = new mojs.Timeline();
timeline.add(circle, square);

timeline.play();

Что происходит:

  • круг начинает расти сразу
  • квадрат начинает движение через 300 мс
  • обе анимации синхронизированы через Timeline

Архитектурные преимущества Timeline

  • централизованное управление временем
  • удобная синхронизация сложных сцен
  • модульность (вложенные Timeline)
  • гибкость в настройке задержек и повторов
  • возможность интеграции с пользовательским вводом

Распространённые ошибки

1. Отсутствие delay при ожидании последовательности → все анимации запускаются одновременно

2. Попытка управлять отдельными анимациями вместо Timeline → приводит к рассинхронизации

3. Игнорирование repeat и duration → неверная оценка длительности сцены


Рекомендации по использованию

  • использовать один главный Timeline для сцены
  • разбивать сложные анимации на вложенные Timeline
  • явно задавать delay для последовательностей
  • применять setProgress для интерактивности
  • контролировать duration и repeat на этапе проектирования

Внутренний принцип работы

Timeline:

  1. собирает все дочерние анимации
  2. вычисляет общую временную шкалу
  3. управляет прогрессом каждой анимации
  4. синхронно обновляет состояния на каждом кадре

Фактически это координатор, который связывает независимые анимации в единое временное пространство.