Timeline в mo.js представляет собой механизм управления последовательностью анимаций, позволяющий объединять отдельные твины и эффекты в единый сценарий воспроизведения. В основе лежит объект, координирующий запуск, синхронизацию, задержки и повторения анимационных блоков, обеспечивая предсказуемую композицию сложных визуальных сцен.
Основная идея заключается в том, что каждый tween или shape может существовать самостоятельно, но при включении в timeline начинает подчиняться общей временной сетке. Это позволяет выстраивать как простые последовательности, так и многослойные анимационные системы с перекрывающимися фазами.
Создание timeline в mo.js выполняется через конструктор
mojs.Timeline. После инициализации он наполняется
анимационными сущностями через метод add.
const timeline = new mojs.Timeline();
const circle = new mojs.Shape({
parent: '#app',
shape: 'circle',
radius: { 0: 50 },
fill: 'cyan',
duration: 600
});
timeline.add(circle);
timeline.play();
Каждый добавленный элемент сохраняет собственные параметры длительности и задержки, но их запуск синхронизируется относительно стартовой точки timeline.
Организация временной структуры определяется параметрами отдельных анимаций. При отсутствии задержек элементы стартуют одновременно, формируя параллельное воспроизведение.
const timeline = new mojs.Timeline();
const a = new mojs.Shape({
shape: 'circle',
radius: { 0: 40 },
duration: 500
});
const b = new mojs.Shape({
shape: 'rect',
radius: { 0: 40 },
delay: 500,
duration: 500
});
timeline.add(a, b);
timeline.play();
Задержка во втором элементе формирует последовательную структуру, при которой второй tween начинает работу после завершения первого.
Каждый элемент timeline может иметь параметры duration,
delay, repeat, влияющие на общую композицию.
Суммарная длительность timeline не задаётся напрямую, а вычисляется как
максимум всех вложенных временных интервалов.
const timeline = new mojs.Timeline();
const segment1 = new mojs.Shape({
radius: { 0: 30 },
duration: 400
});
const segment2 = new mojs.Shape({
radius: { 0: 60 },
delay: 200,
duration: 600
});
timeline.add(segment1, segment2);
Перекрытие временных интервалов позволяет создавать сложные визуальные переходы без явного управления состояниями.
Timeline может содержать другие timeline, формируя иерархическую структуру анимаций. Такой подход используется для группировки логически связанных сцен.
const inner = new mojs.Timeline();
const part1 = new mojs.Shape({
radius: { 0: 20 },
duration: 300
});
const part2 = new mojs.Shape({
radius: { 0: 40 },
delay: 150,
duration: 300
});
inner.add(part1, part2);
const main = new mojs.Timeline();
main.add(inner);
main.play();
Вложенные структуры упрощают повторное использование анимационных блоков и позволяют масштабировать композиции без дублирования логики.
Timeline предоставляет базовые методы управления жизненным циклом анимации:
play() — запуск с текущей позицииreplay() — перезапуск с началаpause() — остановка на текущем кадреstop() — полная остановка с возвратом к начальному
состояниюconst timeline = new mojs.Timeline();
timeline.add(new mojs.Shape({
radius: { 0: 50 },
duration: 800
}));
timeline.play();
timeline.pause();
timeline.replay();
Поведение replay особенно важно в интерфейсных
сценариях, где требуется повторная синхронизация без пересоздания
объектов.
Timeline позволяет объединять разные типы анимаций: формы, твины, burst-эффекты. Это создаёт единое временное пространство, где визуальные элементы взаимодействуют синхронно.
const burst = new mojs.Burst({
radius: { 0: 100 },
count: 10,
children: {
shape: 'circle',
radius: { 0: 20 },
duration: 600
}
});
const circle = new mojs.Shape({
shape: 'circle',
radius: { 0: 50 },
fill: 'orange',
duration: 600
});
const timeline = new mojs.Timeline();
timeline.add(circle, burst);
timeline.play();
Синхронный старт позволяет формировать комплексные визуальные реакции, где разные элементы развиваются в одном временном контуре.
Хотя mo.js не предоставляет отдельного stagger API в timeline, аналогичный эффект достигается через динамическое вычисление задержек.
const timeline = new mojs.Timeline();
const items = Array.from({ length: 5 }).map((_, i) =>
new mojs.Shape({
radius: { 0: 30 },
delay: i * 100,
duration: 400
})
);
timeline.add(...items);
timeline.play();
Такой подход формирует каскадное появление элементов, при котором каждый следующий tween смещён во времени относительно предыдущего.
Timeline поддерживает повторное воспроизведение через параметр
repeat. Это позволяет создавать циклические анимации без
внешнего управления состоянием.
const timeline = new mojs.Timeline({
repeat: 2
});
timeline.add(
new mojs.Shape({
radius: { 0: 40 },
duration: 500
})
);
timeline.play();
Цикличность используется в интерфейсных индикаторах и фоновых анимациях, где требуется непрерывное движение.
Скорость выполнения timeline может изменяться через свойство
speed. Это влияет на все вложенные анимации одновременно,
сохраняя относительные временные пропорции.
const timeline = new mojs.Timeline();
timeline.add(
new mojs.Shape({
radius: { 0: 60 },
duration: 1000
})
);
timeline.speed(2);
timeline.play();
Увеличение скорости уменьшает общее время выполнения, не изменяя структуру последовательности.
Перекрывающиеся анимации позволяют формировать многослойные эффекты,
где одна фаза начинается до завершения другой. Это достигается
комбинацией delay и различной длительности элементов.
const timeline = new mojs.Timeline();
timeline.add(
new mojs.Shape({
radius: { 0: 30 },
duration: 600
}),
new mojs.Shape({
radius: { 0: 60 },
delay: 200,
duration: 600
}),
new mojs.Shape({
radius: { 0: 90 },
delay: 400,
duration: 600
})
);
timeline.play();
Такая структура формирует эффект нарастающей волны, где визуальные состояния накладываются друг на друга.
Timeline часто используется как реакция на пользовательские действия. В этом случае его запуск синхронизируется с событиями DOM.
const timeline = new mojs.Timeline();
timeline.add(
new mojs.Shape({
radius: { 0: 50 },
duration: 500
})
);
document.addEventListener('click', () => {
timeline.replay();
});
Перезапуск анимации на событие обеспечивает детерминированный визуальный отклик без накопления состояния.
При увеличении количества элементов timeline используется как центральный координатор, разделяющий логику на независимые блоки. Каждый блок описывает отдельную фазу интерфейса, а общий timeline управляет их синхронизацией.
Разделение на под-timeline позволяет избегать линейного усложнения кода и сохранять временную структуру читаемой даже при десятках анимационных элементов.
const intro = new mojs.Timeline();
const loop = new mojs.Timeline();
intro.add(new mojs.Shape({ radius: { 0: 40 }, duration: 400 }));
loop.add(new mojs.Shape({ radius: { 0: 20 }, duration: 300 }));
const main = new mojs.Timeline();
main.add(intro, loop);
main.play();