Как установить происхождение трансформации в SVG

Мне нужно изменить размер и повернуть некоторые элементы в документе SVG с помощью javascript. Проблема заключается в том, что по умолчанию она всегда применяет преобразование вокруг начала координат в (0, 0) - вверху слева.

Как я могу переопределить эту точку привязки преобразования?

Я попытался использовать атрибут transform-origin, но он ничего не влияет.

Вот как я это сделал:

svg.getDocumentById('someId').setAttribute('transform-origin', '75 240');

Кажется, он не указывает ключевую точку на указанную мной точку, хотя я могу видеть в Firefox, что атрибут правильно установлен. Я пробовал такие вещи, как center bottom и 50% 100% с круглыми скобками и без них. Пока ничего не работало.

Может ли кто-нибудь помочь?

Ответ 1

Для поворота используйте transform="rotate(deg, cx, cy)", где deg - степень, которую вы хотите повернуть, и (cx, cy) определяют центр вращения.

Для масштабирования/изменения размера вам нужно перевести на (-cx, -cy), затем масштабировать, а затем перевести обратно на (cx, cy). Вы можете сделать это с помощью матричного преобразования:

transform="matrix(sx, 0, 0, sy, cx-sx*cx, cy-sy*cy)"

Где sx - коэффициент масштабирования по оси x, sy по оси y.

Ответ 2

Если вы можете использовать фиксированное значение (не "center" или "50%" ), вы можете использовать CSS вместо:

-moz-transform-origin: 25px 25px;
-ms-transform-origin:  25px 25px;
-o-transform-origin: 25px 25px;
-webkit-transform-origin:  25px 25px;
transform-origin: 25px 25px;

Некоторые браузеры (например, Firefox) не будут корректно обрабатывать относительные значения.

Ответ 3

Если вы похожи на меня и хотите панорамировать, а затем увеличивайте масштаб с помощью трансформационного начала, вам понадобится немного больше.

// <g id="view"></g>
var view = document.getElementById("view");

var state = {
  x: 0,
  y: 0,
  scale: 1
};

// Origin of transform, set to mouse position or pinch center
var oX = window.innerWidth/2;
var oY = window.innerHeight/2;

var changeScale = function (scale) {
  // Limit the scale here if you want
  // Zoom and pan transform-origin equivalent
  var scaleD = scale / state.scale;
  var currentX = state.x;
  var currentY = state.y;
  // The magic
  var x = scaleD * (currentX - oX) + oX;
  var y = scaleD * (currentY - oY) + oY;

  state.scale = scale;
  state.x = x;
  state.y = y;

  var transform = "matrix("+scale+",0,0,"+scale+","+x+","+y+")";
  //var transform = "translate("+x+","+y+") scale("+scale+")"; //same
  view.setAttributeNS(null, "transform", transform);
};

Здесь он работает: http://forresto.github.io/dataflow-prototyping/react/