如何在SVG中设置变换原点

Cha*_*gne 90 svg coordinate-transformation

我需要使用javascript调整SVG文档中的某些元素并调整其大小.问题是,默认情况下,它始终在(0, 0)左上方的原点周围应用变换.

如何重新定义此变换锚点?

我尝试使用该transform-origin属性,但它不会影响任何东西.

我就这样做了:

svg.getDocumentById('someId').setAttribute('transform-origin', '75 240');
Run Code Online (Sandbox Code Playgroud)

虽然我可以在Firefox中看到属性设置正确,但它似乎没有将关键点设置为我指定的点.我尝试之类的东西center bottom,并50% 100%有和没有括号.到目前为止没有任何工作.

有人可以帮忙吗?

Pet*_*dge 138

要旋转使用transform="rotate(deg, cx, cy)",其中deg是您想要旋转的度数,(cx,cy)定义旋转中心.

对于缩放/调整大小,您必须翻译(-cx,-cy),然后缩放,然后转换回(cx,cy).你可以用矩阵变换做到这一点:

transform="matrix(sx, 0, 0, sy, cx-sx*cx, cy-sy*cy)"
Run Code Online (Sandbox Code Playgroud)

其中sx是x轴中的缩放因子,y轴是sy.

  • 难道不是变换="矩阵(sx,0,0,sy,cx-sx*cx,cy-sy*cy)"?因为你只希望通过差异来翻译.我认为这个逻辑是正确的,但它仍然让我失去了立场...... (6认同)

Geo*_*rge 33

svg * { 
  transform-box: fill-box;
}
Run Code Online (Sandbox Code Playgroud)

应用transform-box: fill-box将使 SVG 中的元素表现得像普通的 HTML 元素。然后你可以transform-origin: center像往常一样申请(或其他东西)

没错,transform-box: fill-box。这些天,不需要任何复杂的矩阵东西

  • 非常有用的解决方案,这应该得到更高的支持。这正是我所需要的;谢谢你!svg 和 html 元素在转换和过渡时有细微的差别。我对一个动画错误感到困惑了好几个小时,直到我找到了这个答案......使用“transform-b​​ox: fill-box;”,你可以让 svg 元素以理智的方式尊重“transform-origin”/就像你所期望的那样! (8认同)
  • 不用担心,伙计!当我找到它时,我也有类似的宽慰(谢谢@Robert Longson)!它解决了我在尝试控制 svg 地图上的点时所面临的巨大头痛问题:sweat: :sweat: :sweat: (2认同)
  • 请注意:transform-b​​ox 于 2017 年全面引入 - 在这个问题被提出和首次回答 6 年后。因此,你可能不得不原谅那些“错过了窍门”的人。 (2认同)
  • 这是最好的答案 (2认同)

Haf*_*ich 20

如果您可以使用固定值(不是"中心"或"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;
Run Code Online (Sandbox Code Playgroud)

某些浏览器(如Firefox)无法正确处理相对值.


for*_*sto 13

如果你像我一样想要平移然后用变换原点进行缩放,你需要更多一点.

// <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);
};
Run Code Online (Sandbox Code Playgroud)

这是工作:http://forresto.github.io/dataflow-prototyping/react/


cmi*_*iuc 10

对于无需使用matrix转换即可进行缩放:

transform="translate(cx, cy) scale(sx sy) translate(-cx, -cy)"
Run Code Online (Sandbox Code Playgroud)

在CSS中:

transform: translate(cxpx, cypx) scale(sx, sy) translate(-cxpx, -cypx)
Run Code Online (Sandbox Code Playgroud)