Получение текущей матрицы

В Snap.svg каждая графическая фигура или группа элементов имеет собственную систему координат, которая управляется через матрицу трансформаций. Для получения и работы с текущей матрицей используется метод getCTM(), который возвращает текущую матрицу преобразований элемента относительно его родителя.

Метод getCTM()

Синтаксис:

var matrix = element.getCTM();
  • element — объект Snap.svg, представляющий любой SVG-элемент (например, rect, circle, path, g).
  • matrix — объект SVGMatrix, содержащий текущие параметры преобразования.

Возвращаемый объект SVGMatrix содержит свойства:

  • a — масштабирование по оси X.
  • b — наклон по оси Y.
  • c — наклон по оси X.
  • d — масштабирование по оси Y.
  • e — смещение по оси X.
  • f — смещение по оси Y.

Пример получения матрицы:

var s = Snap(400, 400);
var rect = s.rect(50, 50, 100, 100);
rect.transform("t100,50r45");

var matrix = rect.getCTM();
console.log(matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f);

В этом примере прямоугольник сначала смещается на (100, 50), затем поворачивается на 45°. Метод getCTM() возвращает комбинированную матрицу, учитывающую все примененные трансформации.

Применение текущей матрицы

Текущая матрица трансформаций особенно полезна при:

  1. Вычислении абсолютных координат точки внутри элемента. Для преобразования координат используется метод matrix.transformPoint(x, y):
var point = matrix.transformPoint(0, 0);
console.log(point.x, point.y);
  1. Анимации с сохранением текущего состояния. При динамических трансформациях можно сохранять текущую матрицу, а затем применять дополнительные преобразования относительно неё:
var currentMatrix = rect.getCTM();
rect.transform(currentMatrix.toTransformString() + "t50,0");
  1. Комбинирования трансформаций для сложных элементов. В случае групп элементов (<g>) матрица учитывает все трансформации родительских групп, что позволяет правильно позиционировать дочерние элементы.

Преобразование матрицы в строку трансформации

Объект SVGMatrix можно преобразовать обратно в строку, которую понимает Snap.svg:

var transformString = matrix.toTransformString();
rect.transform(transformString);

Это полезно, когда необходимо сохранить текущее состояние элемента и повторно применить его позже.

Отличие getCTM() от transform()

  • transform() возвращает строку всех локальных трансформаций элемента, в том виде, в каком они были заданы (t, r, s, m).
  • getCTM() возвращает абсолютную матрицу относительно SVG-контейнера, учитывающую все родительские трансформации.

Пример различия:

rect.transform("t100,50r30");
console.log(rect.transform()); // "t100,50r30"
console.log(rect.getCTM());    // матрица с учетом поворота и смещения

Работа с группами (<g>)

При работе с группами текущая матрица учитывает трансформации всех родителей:

var group = s.group(rect);
group.transform("t50,50");
var matrix = rect.getCTM();

В этом случае matrix.e и matrix.f будут включать смещение как элемента, так и группы, что позволяет точно вычислять позицию элемента на канве.

Пример вычисления координат клика относительно элемента

s.click(function(event) {
    var point = s.node.createSVGPoint();
    point.x = event.clientX;
    point.y = event.clientY;
    var ctm = rect.getCTM().inverse();
    var local = point.matrixTransform(ctm);
    console.log(local.x, local.y); // координаты клика внутри rect
});

Здесь используется обратная матрица (inverse()), чтобы преобразовать глобальные координаты мыши в локальные координаты элемента. Это часто применяют для интерактивных приложений и drag-and-drop интерфейсов.

Рекомендации по использованию

  • Для анимаций и сложных трансформаций всегда лучше использовать getCTM(), чтобы учитывать все предыдущие изменения.
  • Для быстрого получения локальной трансформации, изменяемой вручную, достаточно transform().
  • При работе с вложенными группами и SVG с масштабированием, вычисления через getCTM() обеспечивают корректное позиционирование и взаимодействие элементов.

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