SVG-траектория используется как направляющая, по которой перемещаются
элементы интерфейса. В веб-анимации это реализуется через вычисление
позиции вдоль кривой Безье и преобразование этой позиции в координаты
трансформации элемента. В экосистеме Motion One подобная задача решается
через высокоуровневые параметры, абстрагирующие работу с
offset-path, offset-distance и вращением вдоль
касательной.
SVG-путь задаётся через <path> и описывает кривую,
вдоль которой может двигаться объект. В классическом подходе требуется
вручную вычислять длину пути и позицию точки, но Motion One использует
нативные возможности браузера.
<svg width="600" height="300" viewBox="0 0 600 300">
<path id="route"
d="M50,250 C150,50 450,50 550,250"
fill="none"
stroke="black"/>
<div id="dot"></div>
</svg>
Элемент, который будет двигаться, позиционируется поверх SVG через absolute positioning.
Ключевой параметр — offsetDistance. Он определяет,
насколько далеко элемент продвинут вдоль пути (в процентах или пикселях
длины пути).
import { animate } from "motion";
animate(
"#dot",
{
offsetDistance: ["0%", "100%"]
},
{
duration: 3,
easing: "ease-in-out",
repeat: Infinity
}
);
offsetDistance интерпретируется браузером относительно
offset-path, который должен быть задан через CSS.
#dot {
width: 20px;
height: 20px;
background: red;
border-radius: 50%;
offset-path: path("M50,250 C150,50 450,50 550,250");
}
Чтобы элемент не просто перемещался, а поворачивался по касательной
линии пути, используется offsetRotate.
animate(
"#dot",
{
offsetDistance: ["0%", "100%"],
offsetRotate: "auto"
},
{
duration: 3,
easing: "linear",
repeat: Infinity
}
);
auto заставляет элемент автоматически ориентироваться по
направлению движения. Возможны альтернативы:
auto-reverse — разворот на 180°90deg)Motion One позволяет описывать движение вдоль пути через ключевые кадры, что полезно для нелинейного контроля скорости.
animate(
"#dot",
{
offsetDistance: ["0%", "40%", "80%", "100%"]
},
{
duration: 5,
easing: "ease-in-out"
}
);
Каждый ключевой кадр соответствует точке на пути, а easing влияет на распределение скорости между ними.
При необходимости несколько элементов могут двигаться по одной траектории с различными задержками.
import { stagger, animate } from "motion";
animate(
".dot",
{
offsetDistance: ["0%", "100%"]
},
{
duration: 4,
delay: stagger(0.3),
repeat: Infinity
}
);
stagger создаёт фазовый сдвиг движения, формируя эффект
«цепочки».
Обратное движение достигается простым разворотом диапазона ключевых кадров:
animate(
"#dot",
{
offsetDistance: ["100%", "0%"]
},
{
duration: 3,
easing: "linear",
repeat: Infinity
}
);
Такой подход полезен для циклических анимаций, где направление должно чередоваться.
Motion One поддерживает синхронизацию анимаций с прокруткой страницы
через inView и scroll.
import { animate, scroll } from "motion";
scroll(
animate("#dot", {
offsetDistance: ["0%", "100%"]
}),
{
target: document.querySelector("#section"),
offset: ["start end", "end start"]
}
);
Движение по пути становится реактивным относительно положения секции в viewport.
Часто требуется одновременно перемещать объект по пути и изменять его масштаб или прозрачность.
animate(
"#dot",
{
offsetDistance: ["0%", "100%"],
scale: [0.5, 1],
opacity: [0.2, 1]
},
{
duration: 4,
easing: "ease-out"
}
);
Комбинация трансформаций позволяет создавать эффект приближения или появления объекта во время движения.
Easing-функции определяют распределение скорости движения по кривой. Линейное движение обеспечивает равномерную скорость, тогда как cubic-bezier создаёт сложные динамические эффекты.
animate(
"#dot",
{
offsetDistance: ["0%", "100%"]
},
{
duration: 4,
easing: "cubic-bezier(.42,0,.58,1)"
}
);
Такая настройка особенно заметна на длинных и сложных SVG-кривых.
Для сложных сцен путь может быть разбит на логические участки, а анимация распределена по timeline.
import { timeline } from "motion";
timeline([
["#dot", { offsetDistance: "30%" }, { duration: 1 }],
["#dot", { offsetDistance: "70%" }, { duration: 2 }],
["#dot", { offsetDistance: "100%" }, { duration: 1 }]
]);
Timeline позволяет задавать не только позиции, но и временную структуру движения.
SVG-путь может изменяться во время выполнения, и Motion One
автоматически пересчитывает позицию элемента, если обновляется
offset-path.
document.querySelector("#route").setAttribute(
"d",
"M50,250 C100,100 500,100 550,250"
);
При изменении кривой движение адаптируется без пересоздания анимации.
При работе с несколькими движущимися объектами вдоль пути важно учитывать:
transform вместо layout-свойств#dot {
will-change: transform;
}
Эта директива снижает стоимость перерасчёта кадров при движении по сложным кривым.