События и их параметры

В библиотеке Snap.svg взаимодействие с элементами SVG осуществляется через события, которые позволяют реагировать на действия пользователя, изменения состояния или внутренние события анимации. Snap.svg поддерживает стандартные DOM-события, такие как click, mouseover, mouseout, mousedown, mouseup, а также собственные методы для управления событиями на SVG-элементах.


Привязка событий к элементам

Для добавления события к элементу используется метод element.hover() или element.click(), а также универсальный метод element.drag() для обработки движения мыши.

Пример привязки клика к элементу:

var s = Snap("#svg");
var circle = s.circle(100, 100, 50);
circle.attr({ fill: "#3498db", stroke: "#2980b9", strokeWidth: 3 });

circle.click(function(event) {
    this.attr({ fill: "#e74c3c" });
    console.log("Клик по кругу", event);
});

В данном примере событие click изменяет цвет круга и выводит объект события в консоль. Объект event содержит стандартные параметры, такие как clientX, clientY, target, что позволяет использовать координаты клика для дополнительных вычислений.


События наведения: hover

Метод hover() принимает два callback-функции: одна выполняется при наведении мыши, другая — при уходе мыши с элемента.

circle.hover(
    function() { this.attr({ stroke: "#2ecc71", strokeWidth: 5 }); },
    function() { this.attr({ stroke: "#2980b9", strokeWidth: 3 }); }
);

Ключевой момент: при использовании hover важно помнить, что первый callback — это mouseenter, а второй — mouseleave. Это позволяет создавать интерактивные элементы с визуальными эффектами без использования CSS.


Метод drag(): перетаскивание элементов

Snap.svg предоставляет гибкий механизм обработки перетаскивания через метод drag(onMove, onStart, onEnd).

  • onMove(dx, dy, x, y, event) — вызывается при движении элемента.
  • onStart(x, y, event) — вызывается при начале перетаскивания.
  • onEnd(event) — вызывается при завершении перетаскивания.
circle.drag(
    function(dx, dy) { this.attr({ cx: this.ox + dx, cy: this.oy + dy }); },
    function() { this.ox = this.attr("cx"); this.oy = this.attr("cy"); },
    function() { console.log("Перетаскивание завершено"); }
);

Особенности: Snap.svg автоматически передает в onMove относительные смещения (dx, dy) и абсолютные координаты мыши (x, y). Для корректного перемещения рекомендуется сохранять исходные координаты элемента при начале перетаскивания.


Универсальное добавление и удаление событий

Для добавления событий можно использовать метод element.touchstart() или обертку element.mouseover(). Более гибкий способ — использование метода element.data() для хранения состояния и пользовательских данных вместе с обработчиком.

Удаление события производится через метод element.unclick() или element.undrag(). Для событий, добавленных через hover(), можно использовать element.unhover().

circle.unhover(); // убирает обработчики hover
circle.unclick(); // убирает обработчик click

Примечание: важно всегда удалять ненужные обработчики, чтобы избежать утечек памяти при работе с большим количеством интерактивных элементов.


Параметры события

Объект события event содержит полезные свойства:

  • target — элемент, на котором произошло событие
  • currentTarget — элемент, на который в данный момент назначен обработчик
  • type — тип события (click, mouseover, mousemove)
  • clientX / clientY — координаты курсора относительно окна
  • offsetX / offsetY — координаты относительно элемента

Для работы с SVG полезно вычислять координаты относительно системы координат SVG:

circle.click(function(event) {
    var pt = this.paper.node.createSVGPoint();
    pt.x = event.clientX;
    pt.y = event.clientY;
    var svgP = pt.matrixTransform(this.paper.node.getScreenCTM().inverse());
    console.log("Координаты относительно SVG:", svgP.x, svgP.y);
});

Делегирование событий

Snap.svg не имеет встроенного механизма делегирования событий как в jQuery, но можно реализовать его через проверку event.target:

s.click(function(event) {
    if (event.target.tagName === "circle") {
        console.log("Клик по кругу:", event.target);
    }
});

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


Встроенные события анимации

Snap.svg позволяет отслеживать события анимации через метод animate() с дополнительным callback:

circle.animate({ r: 80 }, 1000, mina.easeinout, function() {
    console.log("Анимация завершена");
});

Callback вызывается после окончания анимации и позволяет запускать последующие действия или цепочки анимаций. Также можно использовать событие onframe через mina для пошагового контроля анимации.


Практические рекомендации

  • Использовать hover() вместо CSS при необходимости анимировать SVG атрибуты.
  • Для перетаскивания сохранять исходные координаты в onStart.
  • Всегда удалять ненужные обработчики через unclick(), unhover(), undrag().
  • Для вычисления координат относительно SVG использовать createSVGPoint() и getScreenCTM().
  • Для динамически создаваемых элементов применять проверку event.target для делегирования событий.

Эти инструменты позволяют создавать сложные интерактивные интерфейсы на SVG с точным контролем поведения элементов и реакцией на действия пользователя.