Последовательное выполнение

Таймлайн в mo.js выступает центральным механизмом, позволяющим выстраивать анимации в строгой или частично перекрывающейся последовательности. Базовая идея заключается в том, что отдельные анимационные объекты (tweens) не существуют изолированно, а объединяются в управляемую структуру, где порядок старта, длительность и смещение определяют итоговую динамику сцены.

Экземпляр mojs.Timeline служит контейнером для набора анимаций, которые могут исполняться как единое целое. В отличие от одиночных Tween, таймлайн обеспечивает координацию времени между несколькими элементами.

const timeline = new mojs.Timeline();

const circle = new mojs.Shape({
  shape: 'circle',
  radius: 30,
  fill: 'none',
  stroke: 'cyan',
  strokeWidth: 4,
  duration: 600
});

const square = new mojs.Shape({
  shape: 'rect',
  radius: 20,
  fill: 'none',
  stroke: 'magenta',
  strokeWidth: 4,
  duration: 600
});

timeline.add(circle, square);
timeline.play();

При добавлении нескольких анимаций без дополнительных параметров они начинают воспроизводиться одновременно, так как их временная ось совпадает с началом таймлайна.

Управление порядком через задержки

Последовательное выполнение чаще всего достигается через параметр delay. Он смещает старт анимации относительно начала таймлайна или предыдущих элементов.

const first = new mojs.Shape({
  shape: 'circle',
  radius: 20,
  stroke: 'orange',
  duration: 400
});

const second = new mojs.Shape({
  shape: 'circle',
  radius: 20,
  stroke: 'yellow',
  duration: 400,
  delay: 400
});

const third = new mojs.Shape({
  shape: 'circle',
  radius: 20,
  stroke: 'green',
  duration: 400,
  delay: 800
});

const timeline = new mojs.Timeline({ children: [first, second, third] });
timeline.play();

Такой подход создаёт жёстко выстроенную очередь, где каждый следующий элемент стартует после завершения предыдущего с учётом заданного смещения.

Согласование длительности и последовательного ритма

Последовательность в mo.js зависит не только от delay, но и от duration. При равных задержках и длительностях создаётся равномерный ритм исполнения, тогда как вариативность этих параметров формирует асимметричную динамику.

const a = new mojs.Shape({
  shape: 'circle',
  radius: 15,
  stroke: 'white',
  duration: 300
});

const b = new mojs.Shape({
  shape: 'circle',
  radius: 15,
  stroke: 'white',
  duration: 600,
  delay: 300
});

const c = new mojs.Shape({
  shape: 'circle',
  radius: 15,
  stroke: 'white',
  duration: 900,
  delay: 900
});

Различия длительности формируют эффект ускорения или замедления визуального потока без изменения структуры последовательности.

Использование смещения offset внутри таймлайна

При работе с Timeline важным механизмом становится управление временными координатами через offset. В отличие от delay, который задаётся внутри самого tween, offset определяет позицию элемента внутри временной шкалы таймлайна.

const timeline = new mojs.Timeline();

const first = new mojs.Shape({
  shape: 'circle',
  duration: 500
});

const second = new mojs.Shape({
  shape: 'rect',
  duration: 500,
  timelineOffset: 500
});

timeline.add(first, second);
timeline.play();

Использование смещения позволяет строить сложные композиции без изменения внутренних параметров анимаций, сохраняя их переиспользуемость.

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

Альтернативный способ выстраивания последовательности основан на событиях жизненного цикла анимации. Ключевым моментом выступает onComplete, позволяющий запускать следующую анимацию строго после завершения предыдущей.

const first = new mojs.Shape({
  shape: 'circle',
  duration: 400,
  onComplete() {
    second.play();
  }
});

const second = new mojs.Shape({
  shape: 'rect',
  duration: 400,
  onComplete() {
    third.play();
  }
});

const third = new mojs.Shape({
  shape: 'polygon',
  duration: 400
});

first.play();

Такой подход формирует линейную цепочку исполнения, где управление передаётся явно от одного элемента к другому. Это упрощает контроль состояния, но увеличивает связанность компонентов.

Вложенные таймлайны

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

const subTimeline = new mojs.Timeline();

subTimeline.add(
  new mojs.Shape({ shape: 'circle', duration: 300 }),
  new mojs.Shape({ shape: 'rect', duration: 300 })
);

const mainTimeline = new mojs.Timeline();

mainTimeline.add(
  new mojs.Shape({ shape: 'polygon', duration: 400 }),
  subTimeline,
  new mojs.Shape({ shape: 'circle', duration: 400 })
);

mainTimeline.play();

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

Синхронизация через общую временную ось

При объединении нескольких анимаций в один таймлайн ключевым фактором становится единая временная шкала. Каждый tween получает относительное положение, что позволяет точно выстраивать пересечения или строгие последовательности.

const t = new mojs.Timeline();

t.add(
  new mojs.Shape({
    shape: 'circle',
    duration: 600,
    delay: 0
  }),
  new mojs.Shape({
    shape: 'circle',
    duration: 600,
    delay: 200
  }),
  new mojs.Shape({
    shape: 'circle',
    duration: 600,
    delay: 400
  })
);

t.play();

Перекрытия возникают естественным образом при частичном совпадении интервалов, что позволяет создавать волновые или каскадные эффекты без дополнительных вычислений.

Повторное исполнение последовательностей

Последовательные анимации часто требуют цикличности. В mo.js это реализуется через параметр repeat, который применяется как к отдельным tween, так и к таймлайну целиком.

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

timeline.add(
  new mojs.Shape({ shape: 'circle', duration: 300 }),
  new mojs.Shape({ shape: 'rect', duration: 300, delay: 300 })
);

timeline.play();

Повторение влияет на всю структуру последовательности, сохраняя относительные временные зависимости между элементами.

Динамическое построение очередей

Последовательность может формироваться программно в процессе выполнения, когда следующий элемент определяется после завершения предыдущего. Такой подход используется при реактивных сценариях анимации.

function createStep(color) {
  return new mojs.Shape({
    shape: 'circle',
    stroke: color,
    duration: 400,
    onComplete() {
      next();
    }
  });
}

const sequence = ['red', 'blue', 'green'];
let index = 0;

function next() {
  if (index >= sequence.length) return;
  const anim = createStep(sequence[index]);
  index++;
  anim.play();
}

next();

Такая структура позволяет создавать нефиксированные последовательности, зависящие от состояния системы.

Комбинация последовательности и перекрытия

Сложные сцены часто требуют частичного наложения анимаций при сохранении логического порядка. Это достигается комбинацией delay, offset и управления таймлайном.

const timeline = new mojs.Timeline();

timeline.add(
  new mojs.Shape({ shape: 'circle', duration: 600 }),
  new mojs.Shape({ shape: 'rect', duration: 600, delay: 300 }),
  new mojs.Shape({ shape: 'polygon', duration: 600, delay: 600 })
);

timeline.play();

Такой подход создаёт ощущение непрерывного движения, несмотря на формально заданную последовательность стартов.

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

Таймлайн и tween поддерживают управление состоянием воспроизведения, что влияет на последовательное выполнение. Методы play, pause, replay позволяют управлять всей цепочкой без нарушения внутренней структуры.

const timeline = new mojs.Timeline();

timeline.add(
  new mojs.Shape({ shape: 'circle', duration: 500 }),
  new mojs.Shape({ shape: 'rect', duration: 500, delay: 500 })
);

timeline.play();
timeline.pause();
timeline.replay();

Состояние распространяется на все вложенные элементы, сохраняя синхронизацию последовательности без необходимости индивидуального контроля каждого tween.