Параллельное выполнение анимаций в mo.js основано на одновременном запуске нескольких независимых или связанных анимационных сущностей с синхронизацией через временную шкалу. В отличие от последовательных сценариев, где каждый следующий эффект ожидает завершения предыдущего, здесь все элементы получают собственные временные интервалы и стартуют в одном временном окне.
Основная идея заключается в том, что любая анимация в mo.js — это самостоятельный объект, который может существовать отдельно или быть включённым в общую временную структуру. Это позволяет комбинировать эффекты без жёсткой привязки к линейному порядку выполнения.
Каждый экземпляр mojs.Tween, mojs.Shape или
mojs.Burst может запускаться автономно. Если несколько
объектов инициируются в одном и том же контексте выполнения, они
начинают проигрываться одновременно.
const circle = new mojs.Shape({
shape: 'circle',
radius: 40,
fill: 'none',
stroke: 'cyan',
strokeWidth: 4,
duration: 1000
});
const square = new mojs.Shape({
shape: 'rect',
radius: 30,
fill: 'none',
stroke: 'orange',
strokeWidth: 4,
duration: 1000
});
circle.play();
square.play();
Оба объекта запускаются независимо, и их анимации перекрываются по времени. Такой подход используется для простых сцен, где синхронизация не требует централизованного управления.
Более управляемый способ параллельного выполнения реализуется через
mojs.Timeline. Этот объект выступает контейнером для
нескольких анимаций и позволяет запускать их как единое целое.
const timeline = new mojs.Timeline();
const circle = new mojs.Shape({
shape: 'circle',
radius: 50,
fill: 'transparent',
stroke: 'cyan',
duration: 1200
});
const square = new mojs.Shape({
shape: 'rect',
radius: 50,
fill: 'transparent',
stroke: 'magenta',
duration: 1200
});
timeline.add(circle, square);
timeline.play();
Обе анимации стартуют одновременно, поскольку находятся в одном контейнере и не имеют смещений по времени. Timeline выступает единым управляющим механизмом, который синхронизирует запуск вложенных эффектов.
Параллельное выполнение не всегда означает абсолютную синхронность. Внутри одной временной шкалы можно задавать частичное перекрытие анимаций за счёт временных сдвигов.
const timeline = new mojs.Timeline();
const first = new mojs.Shape({
shape: 'circle',
radius: 40,
stroke: 'yellow',
duration: 1000
});
const second = new mojs.Shape({
shape: 'circle',
radius: 60,
stroke: 'lime',
duration: 1000,
delay: 300
});
timeline.add(first, second);
timeline.play();
В этом случае вторая анимация начинается с задержкой, но всё ещё относится к одному параллельному сценарию. Перекрытие фаз позволяет создавать сложные визуальные композиции без строгой последовательности.
Параллельное выполнение часто достигается не через явные настройки, а
через совпадение интервалов длительности. Если две анимации имеют
одинаковое время старта и пересекающиеся интервалы
duration, они автоматически выполняются параллельно.
const a = new mojs.Shape({
shape: 'polygon',
radius: 40,
duration: 1500
});
const b = new mojs.Shape({
shape: 'circle',
radius: 40,
duration: 1500
});
a.play();
b.play();
При одинаковом времени старта их жизненные циклы полностью накладываются, создавая эффект синхронного движения.
mojs.Burst представляет собой особый случай
параллельного выполнения, где несколько элементов генерируются
одновременно и расходятся по заданным траекториям.
const burst = new mojs.Burst({
radius: { 0: 100 },
count: 6,
children: {
shape: 'circle',
radius: 20,
fill: 'cyan',
duration: 1200
}
});
burst.play();
Все дочерние элементы создаются и анимируются в одном временном окне. Внутренняя система Burst автоматически синхронизирует стартовые параметры, обеспечивая параллельное распространение частиц.
В сложных сценах часто используется смешанная модель: часть анимаций
управляется через Timeline, а часть запускается отдельно.
Это позволяет разделить глобальную синхронизацию и локальные
эффекты.
const timeline = new mojs.Timeline();
const base = new mojs.Shape({
shape: 'circle',
radius: 50,
stroke: 'white',
duration: 2000
});
timeline.add(base);
timeline.play();
const extra = new mojs.Shape({
shape: 'rect',
radius: 30,
stroke: 'red',
duration: 800
});
extra.play();
Timeline задаёт основной ритм сцены, тогда как независимые анимации накладываются поверх него, формируя дополнительные слои движения.
Параллельное выполнение часто управляется не архитектурой объектов, а
единым событием запуска. Один вызов play() для нескольких
объектов в одном обработчике гарантирует их одновременный старт.
const shapes = [
new mojs.Shape({ shape: 'circle', duration: 1000 }),
new mojs.Shape({ shape: 'rect', duration: 1000 }),
new mojs.Shape({ shape: 'polygon', duration: 1000 })
];
function start() {
shapes.forEach(s => s.play());
}
Этот подход используется в интерактивных интерфейсах, где событие пользователя становится триггером для синхронного запуска нескольких визуальных эффектов.
При параллельном выполнении важно учитывать, что несколько объектов могут изменять один и тот же визуальный контекст: трансформации, прозрачность или позицию. В mo.js отсутствует автоматическая блокировка конфликтов, поэтому при наложении эффектов результат определяется порядком отрисовки и значениями свойств.
const a = new mojs.Shape({
shape: 'circle',
x: 0,
duration: 1200
});
const b = new mojs.Shape({
shape: 'circle',
x: 100,
duration: 1200
});
a.play();
b.play();
Обе анимации могут одновременно изменять координаты, что приводит к визуальному наложению траекторий. Управление слоями становится частью проектирования сцены.
Параллельность в mo.js не требует идентичного поведения анимаций. Разные кривые, длительности и easing-функции могут сосуществовать в одном временном диапазоне.
const fast = new mojs.Shape({
shape: 'circle',
duration: 600,
easing: 'cubic.out'
});
const slow = new mojs.Shape({
shape: 'rect',
duration: 1800,
easing: 'elastic.out'
});
fast.play();
slow.play();
Несмотря на различие в динамике, обе анимации работают одновременно, создавая многослойный визуальный эффект, где скорость становится дополнительным измерением композиции.
При построении сложных анимационных сцен параллельное выполнение используется как базовый принцип композиции. Отдельные элементы сцены распределяются по независимым анимационным объектам, а затем объединяются через временные пересечения.
Такой подход позволяет формировать поведение интерфейса как систему взаимодействующих процессов, где каждый элемент имеет собственный жизненный цикл, но не изолирован от остальных.