Обработчики касаний

Snap.svg предоставляет мощный и гибкий механизм для работы с событиями касаний и взаимодействий с пользователем на сенсорных устройствах. Основной задачей таких обработчиков является отслеживание прикосновений к элементам SVG и выполнение заданных функций при их возникновении.

Основные методы

Snap.svg использует стандартный синтаксис событий JavaScript, но предоставляет удобные обёртки для работы с SVG-элементами. Основные методы для обработки касаний:

  • element.touchstart(handler) – вызывается при начале касания элемента.
  • element.touchmove(handler) – вызывается при перемещении пальца по элементу.
  • element.touchend(handler) – вызывается при завершении касания.

Каждый из этих методов принимает одну функцию-обработчик, которая получает объект события event как параметр. Этот объект содержит информацию о координатах касания (event.clientX, event.clientY) и дополнительных свойствах, таких как идентификатор пальца (event.identifier), что особенно важно при мультитач-взаимодействиях.

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

circle.touchstart(function(event) {
    console.log("Начало касания:", event.clientX, event.clientY);
});

circle.touchmove(function(event) {
    circle.attr({cx: event.clientX, cy: event.clientY});
});

circle.touchend(function(event) {
    console.log("Касание завершено");
});

Объект события касания

Объект события касания в Snap.svg соответствует стандартному TouchEvent и содержит следующие ключевые свойства:

  • touches – список всех текущих касаний на экране.
  • targetTouches – касания, относящиеся только к текущему элементу.
  • changedTouches – касания, изменившиеся с момента предыдущего события.

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

circle.touchmove(function(event) {
    if (event.touches.length === 2) {
        var dx = event.touches[0].clientX - event.touches[1].clientX;
        var dy = event.touches[0].clientY - event.touches[1].clientY;
        var distance = Math.sqrt(dx*dx + dy*dy);
        circle.attr({r: distance / 2});
    }
});

События мультитач и идентификаторы

Каждое касание имеет уникальный идентификатор (event.identifier). Это позволяет отслеживать движение каждого пальца отдельно:

circle.touchmove(function(event) {
    for (var i = 0; i < event.changedTouches.length; i++) {
        var touch = event.changedTouches[i];
        console.log("ID касания:", touch.identifier, "координаты:", touch.clientX, touch.clientY);
    }
});

Использование идентификаторов особенно важно при реализации перетаскивания нескольких объектов одновременно или при сложных жестах.

Привязка и удаление обработчиков

Snap.svg позволяет легко управлять обработчиками событий:

  • element.touchstart(handler) – добавляет обработчик.
  • element.untouchstart(handler) – удаляет конкретный обработчик.
  • Аналогично работают методы touchmove и touchend.
function moveHandler(event) {
    circle.attr({cx: event.clientX, cy: event.clientY});
}

circle.touchmove(moveHandler);
// Для удаления обработчика:
circle.untouchmove(moveHandler);

Комбинирование с другими событиями

Обработчики касаний можно комбинировать с кликами и наведением мыши. Snap.svg корректно обрабатывает различие между click, mousedown, touchstart и мультитач-касаем:

circle.click(function() {
    console.log("Клик мышью");
});

circle.touchstart(function() {
    console.log("Сенсорное касание");
});

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

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

  • Использовать preventDefault() внутри обработчика touchstart для предотвращения стандартного скролла или масштабирования браузера.
  • Всегда учитывать мультитач и идентификаторы касаний для сложных жестов.
  • Оптимизировать обработчики touchmove, чтобы избежать задержек и торможений на мобильных устройствах.
  • Для анимации элементов лучше применять Snap.svg методы трансформации (transform, animate) вместо прямого изменения координат через attr, что повышает производительность.

Примеры жестов

  1. Перетаскивание одного объекта пальцем:
var startX, startY;
circle.touchstart(function(event) {
    startX = event.touches[0].clientX - circle.getBBox().cx;
    startY = event.touches[0].clientY - circle.getBBox().cy;
});

circle.touchmove(function(event) {
    var x = event.touches[0].clientX - startX;
    var y = event.touches[0].clientY - startY;
    circle.attr({cx: x, cy: y});
});
  1. Масштабирование двумя пальцами:
var initialDistance, initialRadius;
circle.touchstart(function(event) {
    if (event.touches.length === 2) {
        var dx = event.touches[0].clientX - event.touches[1].clientX;
        var dy = event.touches[0].clientY - event.touches[1].clientY;
        initialDistance = Math.sqrt(dx*dx + dy*dy);
        initialRadius = circle.attr("r");
    }
});

circle.touchmove(function(event) {
    if (event.touches.length === 2) {
        var dx = event.touches[0].clientX - event.touches[1].clientX;
        var dy = event.touches[0].clientY - event.touches[1].clientY;
        var distance = Math.sqrt(dx*dx + dy*dy);
        var scale = distance / initialDistance;
        circle.attr({r: initialRadius * scale});
    }
});

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