Анимация по пути в mo.js строится вокруг идеи движения объекта вдоль заранее заданной кривой, чаще всего описанной через SVG path. В основе лежит интерполяция позиции объекта между точками, вычисляемыми по параметрической кривой, что позволяет получать сложные траектории без ручного расчёта координат.
Ключевая особенность подхода — использование стандартного формата
SVG-пути path, который уже содержит всю геометрию движения:
линии, кривые Безье, дуги. mo.js использует этот путь как математическую
функцию, возвращающую координаты точки на заданном проценте длины
траектории.
SVG-путь задаётся строкой команд, например:
M0,0 C150,0 150,200 300,200
где:
M — начальная точкаC — кубическая кривая Безьеmo.js воспринимает этот путь как непрерывную линию, по которой можно вычислять положение объекта через параметр прогресса анимации.
В mo.js движение по траектории реализуется через tween-анимацию, в которую передаётся SVG path. Объекту задаётся процент прохождения пути, а библиотека автоматически вычисляет координаты.
const pathMotion = new mojs.Tween({
duration: 2000,
onUpdate: (progress) => {
const point = path.getPointAtLength(pathLength * progress);
element.style.transform = `translate(${point.x}px, ${point.y}px)`;
}
});
Здесь используется базовый принцип:
progress изменяется от 0 до 1getPointAtLengthtransformДля точной работы с траекторией используется API SVG:
const path = document.querySelector('path');
const pathLength = path.getTotalLength();
Каждая точка на пути вычисляется через:
path.getPointAtLength(distance)
где distance — текущая позиция вдоль кривой.
Такой подход позволяет:
В mo.js используется концепция сегментного отображения пути. Вместо перемещения объекта можно анимировать видимую часть линии.
const tween = new mojs.Tween({
duration: 3000,
onUpdate: (progress) => {
path.style.strokeDasharray = `${progress * 1000} 1000`;
}
});
В более абстрактной форме это выражается через:
pathStart — начало видимого сегментаpathEnd — конец видимого сегментаТакой подход применяется для:
Для реалистичной анимации объект часто поворачивается по касательной к кривой. Это требует вычисления угла между двумя соседними точками.
const p1 = path.getPointAtLength(distance);
const p2 = path.getPointAtLength(distance + 1);
const angle = Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Math.PI;
Применение:
element.style.transform =
`translate(${p1.x}px, ${p1.y}px) rotate(${angle}deg)`;
Такой метод обеспечивает:
Анимация по пути часто комбинируется с визуальными эффектами mo.js,
такими как Shape и Burst.
Пример движения частицы вдоль пути с одновременным масштабированием:
const tween = new mojs.Tween({
duration: 2500,
onUpdate: (p) => {
const point = path.getPointAtLength(pathLength * p);
const scale = 1 - p;
element.style.transform =
`translate(${point.x}px, ${point.y}px) scale(${scale})`;
}
});
Это позволяет:
При работе с группой объектов используется общий расчёт прогресса пути, но с разными смещениями.
const offset = 0.2;
const progress = (globalProgress + offset) % 1;
const point = path.getPointAtLength(pathLength * progress);
Так создаются:
Хотя движение по пути линейно по длине, можно управлять скоростью через easing-функции:
const eased = mojs.easing.cubic.out(progress);
const point = path.getPointAtLength(pathLength * eased);
Это позволяет:
Сложные траектории часто состоят из нескольких логических частей. Для управления используется нормализация длины:
const segmentLength = pathLength * 0.5;
const point = path.getPointAtLength(segmentLength * progress);
Так можно:
При использовании Timeline движение по пути становится
частью сложной композиции анимаций.
const timeline = new mojs.Timeline();
timeline.add(pathTween, shapeTween, burstTween);
timeline.play();
Это даёт возможность:
При большом количестве объектов критично снижать нагрузку:
pathLengthrequestAnimationFrameПример оптимизированного цикла:
function animate(time) {
const progress = (time % duration) / duration;
const point = lookupTable[Math.floor(progress * tableSize)];
element.style.transform =
`translate(${point.x}px, ${point.y}px)`;
requestAnimationFrame(animate);
}
Использование lookup-table снижает количество вызовов
getPointAtLength.
mo.js не ограничивает тип траектории. Можно создавать:
Генерация пути:
const path = `M0,0 C${x1},${y1} ${x2},${y2} ${x3},${y3}`;
После этого путь используется как стандартная траектория движения.
Анимация по пути применяется в:
Основное преимущество — высокая выразительность при минимальном коде управления геометрией движения.