Колбэки и события анимации

В Snap.svg колбэки играют ключевую роль при управлении анимацией и событиями, позволяя запускать дополнительные действия после завершения анимации или в процессе её выполнения. Основной метод анимации в библиотеке — element.animate(attrs, duration, easing, callback), где:

  • attrs — объект с атрибутами SVG, которые нужно анимировать (например, cx, cy, r, fill и др.).
  • duration — время анимации в миллисекундах.
  • easing — функция ускорения (например, mina.linear, mina.easein, mina.easeout, mina.easeinout).
  • callback — функция, вызываемая после завершения анимации.

Пример использования колбэка:

var circle = s.circle(100, 100, 50);
circle.animate({ r: 80, fill: "#f00" }, 1000, mina.easeinout, function() {
    console.log("Анимация завершена");
});

В этом примере после завершения анимации круга в консоль выводится сообщение. Колбэк выполняется только один раз, когда анимация полностью завершена.

Цепочка анимаций с использованием колбэков

Для последовательного запуска нескольких анимаций удобно использовать вложенные колбэки. Например:

circle.animate({ r: 80 }, 500, mina.linear, function() {
    circle.animate({ fill: "#0f0" }, 500, mina.linear, function() {
        circle.animate({ cx: 200 }, 500, mina.linear);
    });
});

Здесь создаётся цепочка из трёх анимаций: сначала увеличивается радиус, затем меняется цвет, и, наконец, смещается центр круга. Использование колбэков позволяет точно синхронизировать последовательные действия без использования таймеров.

Использование событий SVG с Snap.svg

Snap.svg поддерживает привязку стандартных событий DOM и кастомных событий через метод element.click(), element.hover(), element.mousedown(), element.mouseup() и другие. Пример:

circle.click(function() {
    this.animate({ r: 100, fill: "#00f" }, 800, mina.easeinout);
});

В этом примере при клике на элемент запускается анимация изменения радиуса и цвета. Методы hover позволяют разделять обработку событий наведения и ухода курсора:

circle.hover(
    function() { this.attr({ fill: "#ff0" }); },
    function() { this.attr({ fill: "#f00" }); }
);

Колбэки в многоэлементных группах

Snap.svg позволяет объединять элементы в группы (Paper.group) и применять к ним анимации. Колбэки могут быть использованы для обработки завершения анимации группы:

var g = s.group(circle, s.rect(50, 50, 100, 100));
g.animate({ transform: 't100,0' }, 1000, mina.easeinout, function() {
    console.log("Анимация всей группы завершена");
});

В этом случае колбэк вызывается после завершения трансформации всех элементов группы.

Колбэки для повторяющихся и бесконечных анимаций

Для создания циклической анимации колбэк можно использовать рекурсивно:

function pulse(el) {
    el.animate({ r: 80 }, 500, mina.easeinout, function() {
        el.animate({ r: 50 }, 500, mina.easeinout, function() {
            pulse(el);
        });
    });
}
pulse(circle);

Этот приём позволяет создавать бесконечное «пульсирующее» движение элемента.

События на уровне документа и элементов

Snap.svg предоставляет возможность слушать события не только на отдельных элементах, но и на документе SVG через paper.mousemove() или paper.click():

s.mousemove(function(event) {
    console.log("Координаты курсора: ", event.clientX, event.clientY);
});

Методы drag и mousemove поддерживают колбэки для начала, движения и окончания взаимодействия:

circle.drag(
    function(dx, dy) { this.attr({ cx: this.data('ox') + dx, cy: this.data('oy') + dy }); },
    function(x, y) { this.data('ox', this.attr('cx')); this.data('oy', this.attr('cy')); },
    function() { console.log("Перетаскивание завершено"); }
);

Первый аргумент — функция движения, второй — функция начала перетаскивания, третий — завершение.

Практические рекомендации по работе с колбэками

  • Для сложных цепочек анимаций лучше использовать именованные функции вместо анонимных, чтобы улучшить читаемость и отладку кода.
  • Избегать глубоких вложенных колбэков — вместо этого можно использовать вспомогательные функции или промисы.
  • Колбэки часто комбинируют с событиями, чтобы запускать анимацию в ответ на пользовательское взаимодействие.
  • Для синхронизации нескольких анимаций лучше использовать группы элементов и один общий колбэк.

Интеграция с библиотеками управления асинхронностью

Snap.svg колбэки можно оборачивать в промисы для более чистого управления последовательностью анимаций:

function animateAsync(el, attrs, duration) {
    return new Promise(resolve => {
        el.animate(attrs, duration, mina.linear, resolve);
    });
}

animateAsync(circle, { r: 70 }, 500)
    .then(() => animateAsync(circle, { fill: "#0f0" }, 500))
    .then(() => console.log("Все анимации завершены"));

Такой подход делает код более структурированным и позволяет избегать «адского колбэка».

Колбэки и события в Snap.svg обеспечивают гибкое управление визуальными эффектами и интерактивностью, позволяя создавать динамичные, отзывчивые интерфейсы с SVG-графикой.