Snap.svg предоставляет гибкие инструменты для работы с векторной графикой в браузере, в том числе для управления позиционированием объектов. Ключевым моментом при работе с динамическими элементами является правильный перерасчет координат после трансформаций, изменения размеров контейнера или вложенных групп.
Каждый элемент Snap.svg имеет собственные координаты в локальной системе отсчета. Локальная система определяется:
<svg> или
группы <g>).transform), такими
как translate, rotate,
scale.Для базового получения координат используется метод:
var bbox = element.getBBox();
console.log(bbox.x, bbox.y, bbox.width, bbox.height);
getBBox() возвращает
ограничивающий прямоугольник элемента в текущей системе
координат SVG, включая все трансформации.
Если элемент вложен в группу, а группа имеет трансформации,
координаты элемента локальные относительно группы, а не
всего документа. Для преобразования в глобальные координаты используется
метод getCTM() (Current Transformation Matrix):
var matrix = element.getCTM();
var globalX = matrix.e;
var globalY = matrix.f;
Эта матрица позволяет учитывать все трансформации: переносы,
масштабирование и вращение. Она возвращает объект типа
SVGMatrix:
a, b, c, d — элементы матрицы для масштабирования и
вращения.e, f — сдвиг по X и Y.Для перерасчета любой точки (x, y) в глобальные
координаты:
var pt = element.paper.createSVGPoint();
pt.x = x;
pt.y = y;
var globalPt = pt.matrixTransform(element.getCTM());
Snap.svg предоставляет метод transform(), который
позволяет применить несколько операций одновременно:
element.transform('t100,50r45s2,2');
t100,50 — перенос (translate)r45 — вращение (rotate)s2,2 — масштабирование (scale)Чтобы корректно пересчитать координаты после трансформации:
element.transform().globalMatrixinverse() для
обратного преобразования из глобальных координат в локальные.Пример обратного преобразования:
var invMatrix = element.getCTM().inverse();
var localPt = globalPt.matrixTransform(invMatrix);
Элементы внутри <g> наследуют трансформации
родителя. Для точного перерасчета:
element.getBBox() для локальных
координат.element.getCTM() для глобальных
координат.getCTM().var parentGroup = paper.group();
var rect = paper.rect(0, 0, 50, 50);
parentGroup.add(rect);
parentGroup.transform('t200,100r30');
var rectGlobal = rect.getCTM(); // учитывает трансформацию группы
rect.animate({transform: 't300,150'}, 1000, mina.easeinout, function() {
var bbox = rect.getBBox();
console.log('Новые координаты:', bbox.x, bbox.y);
});
svg.addEventListener('mousemove', function(evt){
var pt = svg.createSVGPoint();
pt.x = evt.clientX;
pt.y = evt.clientY;
var local = pt.matrixTransform(svg.getScreenCTM().inverse());
console.log('Локальные координаты курсора:', local.x, local.y);
});
getBBox() при
большом количестве элементов, так как это вычислительно затратная
операция.matrixTransform, избегая повторного вычисления
getCTM() для каждого события.Для path-элементов перерасчет координат осуществляется
через:
getBBox() — возвращает ограничивающий
прямоугольник.getPointAtLength(), getTotalLength().Пример:
var path = paper.path("M10,10 C20,20, 40,20, 50,10");
var len = path.getTotalLength();
var pt = path.getPointAtLength(len/2); // точка в середине пути
var globalPt = pt.matrixTransform(path.getCTM());
Это позволяет точно позиционировать объекты вдоль кривых и корректно пересчитывать координаты при трансформациях группы или контейнера.
getBBox().getCTM() +
matrixTransform().inverse().getCTM().getBBox().Перерасчет координат является фундаментальным инструментом для анимации, интерактивности и точного позиционирования в Snap.svg.