Mouseenter и mouseleave

В библиотеке Snap.svg для работы с интерактивностью SVG-элементов используются стандартные события DOM, а также собственные методы библиотеки для привязки обработчиков событий. Особое внимание уделяется событиям mouseenter и mouseleave, которые позволяют отслеживать наведение мыши на элемент и выход курсора за его пределы, без всплытия (в отличие от mouseover и mouseout).


Отличия mouseenter/mouseleave от mouseover/mouseout

  • mouseover и mouseout срабатывают каждый раз при переходе курсора через дочерние элементы.
  • mouseenter и mouseleave срабатывают один раз при входе на элемент или выходе с него, игнорируя дочерние элементы.
  • Это особенно важно при работе с группами элементов или сложными SVG-структурами, где необходимо реагировать только на общую область элемента.

Пример:

var s = Snap("#svg");
var circle = s.circle(100, 100, 50);

circle.attr({
    fill: "#3498db",
    stroke: "#2980b9",
    strokeWidth: 4
});

// Обработчики событий
circle.mouseenter(function() {
    this.attr({fill: "#e74c3c"});
});

circle.mouseleave(function() {
    this.attr({fill: "#3498db"});
});

В этом примере при наведении на круг его цвет изменяется на красный, а при уходе курсора — возвращается синий. События mouseenter и mouseleave обеспечивают, что цвет изменится только при входе на сам элемент, без срабатывания при переходе на внутренние части или группы, если бы они были.


Привязка нескольких обработчиков

Snap.svg позволяет добавлять несколько обработчиков на одно событие, используя цепочку вызовов или отдельные вызовы методов:

circle.mouseenter(function() {
    this.attr({strokeWidth: 8});
}).mouseenter(function() {
    console.log("Курсор вошел в круг");
});

Методы можно комбинировать с другими событиями, например, click или mousemove.


Использование с группами (<g>)

SVG-группы часто применяются для объединения нескольких элементов, например, для создания иконок или сложных фигур. События mouseenter и mouseleave работают корректно и с группами:

var g = s.group(
    s.rect(50, 50, 100, 50).attr({fill: "#2ecc71"}),
    s.circle(100, 100, 25).attr({fill: "#27ae60"})
);

g.mouseenter(function() {
    g.attr({opacity: 0.5});
});

g.mouseleave(function() {
    g.attr({opacity: 1});
});

При наведении на любую часть группы её прозрачность изменяется, а при уходе — возвращается к исходной. Это позволяет создавать интерактивные кнопки и панели.


Передача данных в обработчик

В Snap.svg обработчик события получает объект event аналогично обычным DOM-событиям, что позволяет использовать информацию о позиции курсора или целевом элементе:

circle.mouseenter(function(event) {
    console.log("X:", event.clientX, "Y:", event.clientY);
});
  • event.clientX и event.clientY дают координаты курсора относительно окна браузера.
  • this внутри обработчика ссылается на SVG-элемент Snap, к которому привязан обработчик.

Анимация при mouseenter и mouseleave

Snap.svg интегрируется с анимациями через метод animate, что позволяет создавать плавные визуальные эффекты:

circle.mouseenter(function() {
    this.animate({r: 70, fill: "#f1c40f"}, 300, mina.easeinout);
});

circle.mouseleave(function() {
    this.animate({r: 50, fill: "#3498db"}, 300, mina.easeinout);
});
  • r — радиус круга, меняется при наведении.
  • fill — цвет заливки, плавно меняется.
  • mina.easeinout — встроенная функция плавного перехода.

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


Применение с текстом и сложными фигурами

События mouseenter и mouseleave одинаково эффективно работают с текстовыми элементами и сложными SVG-фигурами:

var text = s.text(50, 200, "Hover me").attr({
    fontSize: 24,
    fill: "#8e44ad"
});

text.mouseenter(function() {
    this.attr({fill: "#c0392b"});
});

text.mouseleave(function() {
    this.attr({fill: "#8e44ad"});
});

Можно комбинировать с эффектами масштабирования, перемещения или изменения стиля шрифта.


Практические советы

  • Для сложных SVG-групп стоит привязывать обработчики к группам, а не к отдельным элементам, чтобы избежать множественных срабатываний.
  • При работе с анимацией важно сбрасывать свойства при mouseleave, чтобы избежать конфликтов между состояниями.
  • Использование mouseenter/mouseleave предпочтительно для UI-элементов, где важна корректная реакция на курсор без всплытия через дочерние элементы.

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