Получение координат события

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

Объект события и его свойства

Когда происходит событие, обработчик получает объект события (event), содержащий множество свойств. Для Snap.svg ключевыми являются:

  • event.clientX и event.clientY – координаты относительно окна браузера.
  • event.pageX и event.pageY – координаты относительно всей страницы.
  • event.offsetX и event.offsetY – координаты относительно целевого элемента (не всегда корректно в SVG).
  • event.target – ссылка на элемент, на котором произошло событие.

Для корректного определения координат внутри SVG используется метод преобразования координат через SVGPoint.

Получение координат относительно SVG

SVG имеет собственную систему координат. Прямое использование clientX и clientY может привести к ошибкам при трансформациях (scale, translate). Snap.svg предлагает следующий способ:

var s = Snap("#svg");
var rect = s.rect(0, 0, 100, 100);

rect.click(function(event) {
    var pt = s.node.createSVGPoint();
    pt.x = event.clientX;
    pt.y = event.clientY;
    
    var svgP = pt.matrixTransform(s.node.getScreenCTM().inverse());
    console.log("X:", svgP.x, "Y:", svgP.y);
});

Разбор кода:

  1. createSVGPoint() создаёт точку в пространстве SVG.
  2. pt.x и pt.y устанавливаются в координаты события.
  3. getScreenCTM() возвращает матрицу преобразования из локальной системы координат SVG в экранную.
  4. matrixTransform(...inverse()) переводит экранные координаты обратно в координаты SVG.

Использование координат в элементах Snap.svg

После получения координат можно использовать их для создания или перемещения элементов:

s.click(function(event) {
    var pt = s.node.createSVGPoint();
    pt.x = event.clientX;
    pt.y = event.clientY;
    var svgP = pt.matrixTransform(s.node.getScreenCTM().inverse());

    s.circle(svgP.x, svgP.y, 10).attr({
        fill: "red"
    });
});

В результате при клике на SVG создаётся красный кружок в точке события.

Обработка сложных трансформаций

Если элемент имеет собственные трансформации (transform="translate(50,50) scale(2)"), координаты события должны учитывать локальную систему координат элемента. Для этого применяется метод getCTM() элемента:

rect.click(function(event) {
    var pt = s.node.createSVGPoint();
    pt.x = event.clientX;
    pt.y = event.clientY;
    
    var svgP = pt.matrixTransform(rect.node.getCTM().inverse());
    console.log("Локальные координаты относительно прямоугольника:", svgP.x, svgP.y);
});

Использование rect.node.getCTM().inverse() позволяет корректно вычислять координаты даже после масштабирования, поворота или смещения элемента.

Пример отслеживания движения мыши

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

s.mousemove(function(event) {
    var pt = s.node.createSVGPoint();
    pt.x = event.clientX;
    pt.y = event.clientY;
    var svgP = pt.matrixTransform(s.node.getScreenCTM().inverse());

    console.log("Координаты мыши в SVG:", svgP.x, svgP.y);
});

Это удобно для интерактивных графиков, рисования или drag-and-drop элементов.

Вывод координат в локальную систему вложенного элемента

Если SVG содержит вложенные группы (<g>), важно учитывать матрицу трансформации группы:

var group = s.group();
var circle = s.circle(0, 0, 20).attr({fill: "blue"});
group.add(circle);
group.transform("translate(100,100)");

circle.click(function(event) {
    var pt = s.node.createSVGPoint();
    pt.x = event.clientX;
    pt.y = event.clientY;

    var localP = pt.matrixTransform(circle.node.getCTM().inverse());
    console.log("Координаты относительно круга:", localP.x, localP.y);
});

Здесь координаты вычисляются относительно круга с учётом всех трансформаций группы.

Итоговые принципы

  • Для получения точных координат внутри SVG необходимо использовать createSVGPoint и обратное преобразование матрицы (matrixTransform(...inverse())).
  • Использовать getScreenCTM() для координат относительно всего SVG.
  • Использовать getCTM() для координат относительно конкретного элемента.
  • При сложных трансформациях и группировках всегда учитывать иерархию и локальные матрицы трансформации.

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