Работа с координатами в Snap.svg требует внимательного подхода, так как библиотека оперирует системой координат SVG, которая отличается от привычной системы координат HTML. SVG использует собственный векторный контекст, где верхний левый угол холста имеет координаты (0,0), а единицы измерения могут быть в пикселях, процентах или других масштабируемых единицах. Это приводит к ряду особенностей и потенциальных проблем при позиционировании элементов.
Каждый элемент SVG имеет локальные координаты, которые зависят от его собственного контейнера или трансформаций. Например:
var s = Snap(400, 400);
var rect = s.rect(50, 50, 100, 100);
rect.transform("translate(20,30)");
rect.attr("x") и rect.attr("y")
вернут исходные значения 50 и 50, а не итоговое
положение после трансформации.getBBox():var bbox = rect.getBBox();
console.log(bbox.x, bbox.y); // 70, 80
Вывод: важно различать координаты, заданные элементу
(attr) и координаты после применения трансформаций.
Если элементы находятся внутри <g> (группы), их
координаты становятся относительными к группе, а не к
корневому SVG:
var group = s.group(rect);
group.transform("translate(50,50)");
rect.getBBox() теперь учитывают
трансформацию группы, если используется
getBBox(true).x и y у rect
останутся прежними, что может запутать при динамическом
позиционировании.Рекомендация: при работе с вложенными элементами
использовать getBBox() или getCTM() (Current
Transformation Matrix) для точного расчета положения.
Snap.svg предоставляет объект Matrix, который позволяет
вычислять абсолютные координаты и преобразования:
var m = rect.matrix;
var point = s.paper.node.createSVGPoint();
point.x = 0; point.y = 0;
var transformed = point.matrixTransform(m);
console.log(transformed.x, transformed.y);
matrixTransform переводит локальные координаты элемента
в координаты SVG-холста.scale,
rotate, translate.При создании линии через Snap.svg:
var line = s.line(10, 20, 100, 200);
line.attr("x1") и line.attr("y1") —
исходные координаты точки начала.line.transform("translate(30,40)");
getBBox() или матрицу.Использование атрибута viewBox влияет на
масштабирование координат:
var s = Snap("#svg").attr({ viewBox: "0 0 200 200" });
var circle = s.circle("50%", "50%", "10%");
viewBox.circle.attr("cx") вернет строку
"50%", а не числовое значение.Координаты события мыши (event.clientX,
event.clientY) находятся в экранной
системе, а не в системе SVG:
s.click(function(event){
console.log(event.clientX, event.clientY); // координаты экрана
});
Чтобы получить координаты относительно SVG, нужно использовать
getBoundingClientRect и преобразование:
var rect = s.node.getBoundingClientRect();
var svgX = event.clientX - rect.left;
var svgY = event.clientY - rect.top;
getBBox() или
матрицы трансформации.viewBox преобразовывать проценты в
абсолютные координаты.В результате правильное понимание работы с координатами в Snap.svg позволяет создавать динамические сцены, правильно позиционировать элементы и избегать ошибок, связанных с трансформациями и масштабированием.