Snap.svg предоставляет мощный инструментарий для работы с векторной графикой и анимациями на основе SVG. Анимация путей является одной из ключевых возможностей библиотеки, позволяя создавать плавное движение объектов вдоль кривых и сложных форм.
Элемент пути (<path>) в Snap.svg создаётся с
помощью метода paper.path(), где paper — это
экземпляр SVG-контейнера:
var s = Snap(800, 600);
var path = s.path("M50,150 C150,50 350,250 450,150");
M — начальная точка (move to)C — кубическая кривизна Безье с контрольными
точкамиПуть хранит данные в виде строки d, которая определяет
все координаты и сегменты кривой.
Для перемещения объекта по пути используется метод
Snap.animate(). Основная идея заключается в анимации
позиции объекта на кривой через длину пути. Snap.svg
предоставляет методы getPointAtLength() и
getTotalLength() для точного расчёта координат:
var circle = s.circle(0, 0, 20).attr({fill: "#f00"});
var length = path.getTotalLength();
Snap.animate(0, length, function(step) {
var point = path.getPointAtLength(step);
circle.attr({cx: point.x, cy: point.y});
}, 2000, mina.easeinout);
length — общая длина путиstep — текущая позиция вдоль путиpoint — объект с координатами x и
y и углом alphaКлючевой момент: для плавного движения необходимо
использовать подходящие функции интерполяции, такие как
mina.linear, mina.easein,
mina.easeout или mina.easeinout.
Чтобы объект не только следовал за кривой, но и ориентировался в
направлении пути, используется угол alpha, возвращаемый
методом getPointAtLength():
Snap.animate(0, length, function(step) {
var point = path.getPointAtLength(step);
circle.attr({
cx: point.x,
cy: point.y,
transform: "rotate(" + point.alpha + "," + point.x + "," + point.y + ")"
});
}, 2000, mina.easeinout);
transform применяет вращение относительно центра
объектаpoint.alpha — угол касательной к кривой в данной
точкеМожно одновременно перемещать несколько объектов по одному пути, задавая разное смещение или скорость:
var circle2 = s.circle(0, 0, 15).attr({fill: "#00f"});
Snap.animate(0, length, function(step) {
var point1 = path.getPointAtLength(step);
circle.attr({cx: point1.x, cy: point1.y});
var point2 = path.getPointAtLength((step + 50) % length);
circle2.attr({cx: point2.x, cy: point2.y});
}, 3000, mina.easeinout);
(step + offset) % length позволяет создавать циклическое
смещениеSnap.svg поддерживает прямую анимацию атрибутов SVG. Для путей это позволяет менять цвет, ширину, непрозрачность или даже саму форму кривой:
path.animate({stroke: "#00ff00", strokeWidth: 5}, 1000, mina.easeinout);
Для анимации формы пути используется плавное изменение строки
d:
var path2 = "M50,150 C100,50 400,250 450,150";
path.animate({d: path2}, 2000, mina.easeinout);
Особенность: при анимации d важно,
чтобы количество сегментов исходного и целевого пути совпадало, иначе
Snap.svg может интерпретировать кривую некорректно.
Snap.svg не предоставляет встроенного таймлайна, но можно реализовать бесконечную или циклическую анимацию с помощью повторного вызова анимации в коллбэке:
function animateCircle() {
Snap.animate(0, length, function(step) {
var point = path.getPointAtLength(step);
circle.attr({cx: point.x, cy: point.y});
}, 2000, mina.easeinout, animateCircle);
}
animateCircle();
setTimeout и последовательные анимацииSnap.svg позволяет комбинировать движение вдоль пути с масштабированием, прозрачностью и вращением одновременно:
Snap.animate(0, length, function(step) {
var point = path.getPointAtLength(step);
circle.attr({
cx: point.x,
cy: point.y,
transform: "rotate(" + point.alpha + "," + point.x + "," + point.y + ") scale(" + (1 + 0.5 * Math.sin(step/20)) + ")",
opacity: 0.5 + 0.5 * Math.sin(step/30)
});
}, 4000, mina.easeinout);
scale() динамически изменяет размерopacity плавно изменяет прозрачностьАнимация путей в Snap.svg строится на трёх ключевых принципах: определение кривой, получение точек и углов на пути и плавная интерполяция свойств объекта. Использование этих инструментов позволяет создавать реалистичное движение объектов, управлять их ориентацией и визуальными свойствами в динамическом SVG-контейнере.