Mousedown, mouseup, mousemove

Snap.svg предоставляет удобные методы для работы с событиями мыши на SVG-элементах, что позволяет реализовывать интерактивные интерфейсы, рисование, перетаскивание объектов и сложную анимацию. Основные события, связанные с движением мыши, — это mousedown, mouseup и mousemove.


mousedown

Событие mousedown срабатывает в момент нажатия кнопки мыши на элементе SVG. В Snap.svg оно подключается через метод .mousedown(handler). Этот обработчик принимает объект события, содержащий координаты клика и другие параметры.

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

circle.attr({
    fill: "blue",
    stroke: "black",
    strokeWidth: 2
});

circle.mousedown(function(event) {
    console.log("Нажатие на элемент", event.offsetX, event.offsetY);
    this.attr({fill: "red"});
});

Ключевые моменты:

  • event.offsetX и event.offsetY дают координаты клика относительно SVG-контейнера.
  • Событие можно использовать для инициализации действия, например, начала перетаскивания или начала рисования.
  • Можно подключать несколько обработчиков через .mousedown, Snap.svg поддерживает цепочку вызовов.

mouseup

Событие mouseup срабатывает в момент отпускания кнопки мыши. Оно особенно важно при работе с интерактивными объектами, чтобы завершить действия, инициированные mousedown.

circle.mouseup(function(event) {
    console.log("Отпускание кнопки мыши", event.offsetX, event.offsetY);
    this.attr({fill: "blue"});
});

Особенности mouseup:

  • Часто используется совместно с mousedown для реализации перетаскивания объектов.
  • Позволяет фиксировать конечное состояние объекта после взаимодействия.
  • Обработчик получает тот же объект события, что и mousedown, с координатами и свойствами кнопки мыши.

mousemove

Событие mousemove срабатывает при движении мыши над элементом. В Snap.svg оно подключается методом .mousemove(handler) и передает объект события с координатами текущего положения указателя.

circle.mousemove(function(event) {
    console.log("Движение мыши над элементом", event.offsetX, event.offsetY);
});

Особенности использования:

  • С помощью mousemove можно реализовать динамическое взаимодействие, например, изменение позиции или формы объекта в реальном времени.
  • Чаще всего mousemove комбинируется с флагом, который включается на mousedown и выключается на mouseup, чтобы движение учитывалось только при зажатой кнопке мыши.

Пример реализации перетаскивания элемента

var isDragging = false;
var startX, startY;

circle.mousedown(function(event) {
    isDragging = true;
    startX = event.offsetX - this.attr("cx");
    startY = event.offsetY - this.attr("cy");
});

circle.mousemove(function(event) {
    if (isDragging) {
        this.attr({
            cx: event.offsetX - startX,
            cy: event.offsetY - startY
        });
    }
});

circle.mouseup(function() {
    isDragging = false;
});

Разбор кода:

  1. Флаг isDragging определяет, активен ли процесс перетаскивания.
  2. При mousedown фиксируются смещения startX и startY между мышью и центром круга.
  3. В mousemove координаты элемента обновляются только если isDragging = true.
  4. mouseup завершает процесс перетаскивания, сбрасывая флаг.

Особенности работы с координатами

Snap.svg хранит координаты элементов в атрибутах SVG (cx, cy, x, y). При работе с событиями мыши важно учитывать:

  • event.offsetX и event.offsetY — координаты мыши относительно SVG-контейнера.
  • Для сложных трансформаций (масштаб, rotate, translate) лучше использовать метод getBBox() для получения текущей позиции элемента или Matrix для корректной трансформации.

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

  • Всегда использовать флаг состояния (isDragging, isDrawing), чтобы ограничивать действия мыши в определенном контексте.
  • Для элементов с прозрачными областями следует учитывать, что mousedown сработает только по видимой части элемента (fill не none).
  • Для плавной анимации при движении мыши можно использовать requestAnimationFrame вместо прямого обновления координат в обработчике mousemove.

Взаимодействие событий

Часто mousedown, mousemove и mouseup используются вместе для создания сложных интерфейсов:

  1. mousedown — инициализация действия.
  2. mousemove — динамическое обновление состояния объекта.
  3. mouseup — завершение действия и сброс состояния.

Такой подход позволяет создавать интерактивные элементы, такие как:

  • Перетаскиваемые фигуры
  • Рисование линий или кривых
  • Игровые объекты с управлением мышью
  • Интерактивные диаграммы с динамическим обновлением данных

Поддержка разных кнопок мыши

Объект события содержит event.button:

  • 0 — левая кнопка
  • 1 — средняя кнопка (колесо)
  • 2 — правая кнопка

Можно фильтровать обработку событий для определенной кнопки:

circle.mousedown(function(event) {
    if (event.button === 0) {
        console.log("Только левая кнопка мыши");
    }
});

Резюме основных методов Snap.svg

  • .mousedown(handler) — срабатывает при нажатии кнопки мыши на элементе.
  • .mouseup(handler) — срабатывает при отпускании кнопки мыши.
  • .mousemove(handler) — срабатывает при движении мыши над элементом.
  • Использование флагов состояния позволяет управлять интерактивностью и избегать лишних обновлений.
  • Координаты мыши всегда следует корректировать относительно текущей позиции элемента и контейнера.

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