В 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 имеет собственную систему координат. Прямое использование
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);
});
Разбор кода:
createSVGPoint() создаёт точку в пространстве SVG.pt.x и pt.y устанавливаются в координаты
события.getScreenCTM() возвращает матрицу преобразования из
локальной системы координат SVG в экранную.matrixTransform(...inverse()) переводит экранные
координаты обратно в координаты 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);
});
Здесь координаты вычисляются относительно круга с учётом всех трансформаций группы.
createSVGPoint и обратное преобразование матрицы
(matrixTransform(...inverse())).getScreenCTM() для координат относительно
всего SVG.getCTM() для координат относительно
конкретного элемента.Этот подход обеспечивает точное позиционирование элементов и корректную работу интерактивных приложений на Snap.svg.