В библиотеке mo.js временная шкала (Timeline) выступает центральным механизмом координации анимаций. Скорость воспроизведения определяет, насколько быстро проходят все связанные tween- и shape-анимации внутри одной композиции, сохраняя при этом синхронизацию между ними. Контроль скорости становится ключевым инструментом при создании адаптивных, интерактивных и событийно-зависимых эффектов.
В основе работы Timeline лежит относительная шкала времени. Каждая анимация внутри таймлайна получает прогресс в диапазоне от 0 до 1, который затем интерполируется во внутренние параметры объекта.
Изменение скорости не влияет на длительность анимаций напрямую — вместо этого модифицируется коэффициент времени:
В mo.js скорость часто задаётся через параметр speed при
создании или через динамическое изменение свойства экземпляра
Timeline.
const timeline = new mojs.Timeline({
speed: 1
});
Значение 1 соответствует нормальному воспроизведению,
2 — ускорению в два раза, 0.5 — замедлению
вдвое.
Одним из ключевых аспектов работы с Timeline является возможность изменения скорости во время воспроизведения. Это позволяет создавать эффекты “ускорения сцены”, замедления при наведении или резкой остановки.
timeline.speed(2);
timeline.speed(0.3);
timeline.speed(0);
Изменение скорости применяется ко всей иерархии анимаций, включая
вложенные timelines, если они подключены через .add().
При резкой смене скорости важно учитывать текущий прогресс. Без дополнительной логики может возникнуть визуальный скачок из-за перерасчёта времени.
Внутренне mo.js оперирует концепцией time-scaling, аналогичной
playbackRate в Web Animations API. При увеличении
коэффициента времени все tween’ы получают более быстрые значения
прогресса.
const timeline = new mojs.Timeline();
timeline.add([
new mojs.Html({
el: '.box',
x: { 0: 100 },
duration: 1000
})
]);
timeline.play();
timeline.setSpeed(1.5);
Изменение скорости не изменяет duration объектов. Это
принципиально важно: длительность остаётся фиксированной, меняется
только способ прохождения времени.
При работе с несколькими объектами внутри одной Timeline синхронизация зависит от общего временного делителя.
Если один элемент имеет длительность 1000ms, а другой 500ms, ускорение Timeline в 2 раза приводит к фактическому завершению за:
Однако относительная структура сохраняется, и оба объекта завершаются одновременно.
Это поведение делает Timeline удобным инструментом для композиции сложных сцен, где важна не абсолютная длительность, а относительное положение элементов во времени.
Резкие скачки скорости могут привести к:
Особенно заметно это при использовании сложных кривых сглаживания
(easing), так как интерполяция зависит от временного
шага.
const tween = new mojs.Html({
el: '.circle',
x: { 0: 300 },
duration: 2000,
easing: 'cubic.out'
});
При ускорении Timeline кривая остаётся неизменной, но вычисляется за меньшее количество кадров, что визуально “сжимает” плавность.
Timeline часто связывается с пользовательскими событиями. Управление скоростью становится способом визуального отклика на действия:
const timeline = new mojs.Timeline({
speed: 1
});
timeline.add(animation);
document.addEventListener('mouseenter', () => {
timeline.speed(2);
});
document.addEventListener('mouseleave', () => {
timeline.speed(0.5);
});
Такой подход позволяет использовать Timeline как реактивный механизм, а не только как последовательный проигрыватель.
Для избежания резких скачков применяется интерполяция коэффициента скорости. Вместо мгновенной смены значения используется промежуточное сглаживание:
let currentSpeed = 1;
let targetSpeed = 3;
function updateSpeed() {
currentSpeed += (targetSpeed - currentSpeed) * 0.1;
timeline.speed(currentSpeed);
requestAnimationFrame(updateSpeed);
}
updateSpeed();
Такой подход создаёт эффект “инерционного” ускорения, особенно полезный в интерактивных сценах.
mo.js позволяет вкладывать Timeline друг в друга. В этом случае изменение скорости родительского таймлайна распространяется вниз по иерархии.
const innerTimeline = new mojs.Timeline();
innerTimeline.add(animation);
const outerTimeline = new mojs.Timeline();
outerTimeline.add(innerTimeline);
outerTimeline.speed(2);
Каскадное ускорение важно учитывать при построении сложных сцен: итоговая скорость становится произведением коэффициентов всех уровней.
При использовании повторов (repeat) скорость влияет на
каждый цикл воспроизведения. Это позволяет создавать эффекты:
const pulse = new mojs.Html({
el: '.dot',
scale: { 1: 2 },
duration: 500,
repeat: 5
});
const timeline = new mojs.Timeline({
speed: 1
});
timeline.add(pulse);
timeline.play();
Изменение скорости во время повторов может привести к изменению восприятия ритма без изменения структуры анимации.
Состояния воспроизведения напрямую взаимодействуют с коэффициентом скорости. При паузе скорость сохраняется, но прогресс останавливается.
timeline.pause();
timeline.play();
При возобновлении проигрывания используется текущий speed, что позволяет динамически управлять интенсивностью анимации без сброса состояния.
В сложных композициях часто используется комбинированный подход:
Такой подход позволяет избегать необходимости вручную пересчитывать длительности каждого элемента.
Особенно важно это при сценах с большим количеством синхронизированных объектов, где изменение одного параметра должно влиять на всю систему.
Easing-функции не зависят от скорости напрямую, но их визуальный эффект изменяется из-за изменения плотности вычислений по времени.
Это важно учитывать при создании физических или “натуральных” анимаций, где форма кривой критична для восприятия движения.
В продвинутых сценариях управление скоростью выносится в отдельный слой логики:
const state = {
speed: 1
};
function setSpeed(value) {
state.speed = value;
timeline.speed(state.speed);
}
Такой подход обеспечивает централизованное управление временной моделью всей анимационной системы.
Практически всегда вводятся границы:
При экстремальных значениях возможна потеря визуальной целостности сцены, так как кадровая дискретизация становится заметной.