Snap.svg предоставляет мощный инструмент для работы с анимацией векторной графики на базе SVG. Одной из наиболее востребованных возможностей является организация бесконечной или циклической анимации, когда объект повторяет движения или трансформации без остановки.
Для реализации бесконечного цикла анимации используется комбинация
методов animate и функций обратного
вызова. Snap.svg позволяет анимировать любые атрибуты SVG: координаты,
размеры, цвета, прозрачность, трансформации.
Ключевой момент: бесконечность достигается не специальным флагом, а повторным вызовом анимации в функции обратного вызова:
var s = Snap("#svg");
var circle = s.circle(50, 50, 30).attr({
fill: "#3498db"
});
function animateCircle() {
circle.animate({ cx: 250 }, 1000, mina.easeinout, function() {
circle.animate({ cx: 50 }, 1000, mina.easeinout, animateCircle);
});
}
animateCircle();
В этом примере:
circle перемещается по оси X от 50 до 250 за 1
секунду.animateCircle рекурсивно перезапускает
анимацию, создавая бесконечный цикл движения.Snap.svg использует собственную библиотеку интерполяции mina для плавного перехода значений. Доступны стандартные функции:
mina.linear – линейная анимация без ускоренияmina.easein – постепенный стартmina.easeout – постепенная остановкаmina.easeinout – плавное начало и завершениеПрименение разных интерполяторов позволяет создавать более естественные циклические движения и плавные эффекты.
circle.animate({ cy: 200 }, 1500, mina.easeinout, function() {
circle.animate({ cy: 50 }, 1500, mina.easeinout, animateCircle);
});
Snap.svg поддерживает анимацию сразу нескольких свойств элемента. Это особенно полезно для сложных бесконечных эффектов:
circle.animate({ cx: 250, cy: 200, r: 50, fill: "#e74c3c" }, 2000, mina.easeinout, function() {
circle.animate({ cx: 50, cy: 50, r: 30, fill: "#3498db" }, 2000, mina.easeinout, animateCircle);
});
Здесь одновременно меняются:
cx, cy)r)fill)Таким образом, можно создавать эффект живого, пульсирующего объекта, который непрерывно трансформируется.
repeat и setTimeoutДля удобства иногда используют функцию setTimeout или
setInterval, чтобы запускать анимацию через определённые
интервалы. Это полезно для синхронизации нескольких объектов:
function bounceRect(rect) {
rect.animate({ y: 150 }, 800, mina.bounce, function() {
rect.animate({ y: 50 }, 800, mina.bounce, function() {
setTimeout(function() {
bounceRect(rect);
}, 0);
});
});
}
var rect = s.rect(100, 50, 80, 80).attr({ fill: "#2ecc71" });
bounceRect(rect);
Использование setTimeout гарантирует, что новая анимация
запустится после завершения предыдущей, создавая непрерывный
эффект “прыжка”.
Snap.animateМетод Snap.animate позволяет анимировать произвольные
числовые значения, не привязанные к конкретному элементу. Это удобно для
сложных циклических эффектов, где значения передаются в функцию
обратного вызова для изменения свойств объектов:
Snap.animate(0, 360, function(val) {
circle.attr({ transform: `rotate(${val}, 150, 150)` });
}, 3000, mina.linear, function() {
Snap.animate(360, 0, function(val) {
circle.attr({ transform: `rotate(${val}, 150, 150)` });
}, 3000, mina.linear, arguments.callee);
});
val интерполируется от 0 до 360 градусов.Snap.svg позволяет объединять несколько элементов в группу через
g(). Это упрощает управление анимацией
сразу нескольких объектов:
var group = s.g(
s.circle(50, 50, 20).attr({ fill: "#f1c40f" }),
s.rect(100, 50, 40, 40).attr({ fill: "#e67e22" })
);
function animateGroup() {
group.animate({ transform: "t200,0" }, 1000, mina.easeinout, function() {
group.animate({ transform: "t0,0" }, 1000, mina.easeinout, animateGroup);
});
}
animateGroup();
Циклическая анимация может распространяться и на
градиенты или цвета заливки, используя
атрибуты fill или stroke:
var rect = s.rect(50, 50, 100, 100);
function animateColor() {
rect.animate({ fill: "#9b59b6" }, 1000, mina.easeinout, function() {
rect.animate({ fill: "#1abc9c" }, 1000, mina.easeinout, animateColor);
});
}
animateColor();
Цвет плавно меняется, создавая бесконечное переливание.
requestAnimationFrame в
комбинации с Snap.animate для плавного FPS.g() для массовой анимации, это
снижает количество отдельных вызовов animate.mina для естественного движения,
избегая резких линейных изменений.Благодаря этим подходам можно создавать динамические, живые, бесконечно повторяющиеся анимации любой сложности, от простых перемещений до сложных трансформаций групп объектов и градиентов.