如何在SVG中设置变换原点
我需要使用javascript调整SVG文档中某些元素的大小和旋转。问题是,默认情况下,它总是在左上角如何在SVG中设置变换原点,svg,coordinate-transformation,Svg,Coordinate Transformation,我需要使用javascript调整SVG文档中某些元素的大小和旋转。问题是,默认情况下,它总是在左上角(0,0)处围绕原点应用变换 如何重新定义此变换定位点 我尝试使用transform origin属性,但它不影响任何东西 我就是这样做的: svg.getDocumentById('someId').setAttribute('transform-origin', '75 240'); 它似乎没有将关键点设置为我指定的点,尽管我可以在Firefox中看到该属性设置正确。我试过像中底和50%1
(0,0)
处围绕原点应用变换
如何重新定义此变换定位点
我尝试使用transform origin
属性,但它不影响任何东西
我就是这样做的:
svg.getDocumentById('someId').setAttribute('transform-origin', '75 240');
它似乎没有将关键点设置为我指定的点,尽管我可以在Firefox中看到该属性设置正确。我试过像中底
和50%100%
这样的方法,有括号也有括号。到目前为止,一切都没起作用
有人能帮忙吗?要旋转,请使用
transform=“rotate(deg,cx,cy)”
,其中deg是要旋转的度数,而(cx,cy)定义旋转中心
对于缩放/调整大小,必须按(-cx,-cy)转换,然后缩放,然后再转换回(cx,cy)。您可以通过以下方式执行此操作:
其中,sx是x轴上的比例因子,sy是y轴上的比例因子。如果您像我一样,希望平移,然后使用“变换原点”进行缩放,则需要更多
// <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);
};
//
var view=document.getElementById(“视图”);
变量状态={
x:0,,
y:0,
比例:1
};
//变换原点,设置为鼠标位置或夹点中心
var oX=window.innerWidth/2;
var oY=窗内高度/2;
var changeScale=功能(比例){
//如果需要,请限制此处的比例
//缩放和平移变换原点等效
var scaleD=比例/状态.scale;
var currentX=state.x;
var currentY=状态y;
//魔法
var x=标度*(电流x-oX)+oX;
var y=标度*(当前y-oY)+oY;
state.scale=比例;
状态x=x;
状态y=y;
var transform=“矩阵(“+scale+”,0,0,“+scale+”,“+x+”,“+y+”);
//var transform=“translate(“+x+”,“+y+”)比例(“+scale+”);//相同
view.setAttributeNS(null,“transform”,transform);
};
它在这里工作:如果可以使用固定值(不是“中心”或“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)无法正确处理相对值。我也遇到了类似的问题。但是我使用了D3来定位我的元素,并且希望转换和转换由CSS处理。这是我的原始代码,我在Chrome 65中使用:
//...
this.layerGroups.selectAll('.dot')
.data(data)
.enter()
.append('circle')
.attr('transform-origin', (d,i)=> `${valueScale(d.value) * Math.sin( sliceSize * i)}
${valueScale(d.value) * Math.cos( sliceSize * i + Math.PI)}`)
//... etc (set the cx, cy and r below) ...
这允许我使用相同的数据在javascript中设置cx
、cy
和transform origin
值
但这在Firefox中不起作用我要做的是将圆圈
包裹在g
标记中,然后使用上面相同的定位公式对其进行translate
。然后我在g
标记中添加圆圈
,并将其cx
和cy
值设置为0
。从那里,transform:scale(2)
将按预期从中心进行缩放。最后的代码是这样的
this.layerGroups.selectAll('.dot')
.data(data)
.enter()
.append('g')
.attrs({
class: d => `dot ${d.metric}`,
transform: (d,i) => `translate(${valueScale(d.value) * Math.sin( sliceSize * i)} ${valueScale(d.value) * Math.cos( sliceSize * i + Math.PI)})`
})
.append('circle')
.attrs({
r: this.opts.dotRadius,
cx: 0,
cy: 0,
})
进行此更改后,我将CSS更改为以圆圈为目标,而不是.dot
,以添加变换:缩放(2)
。我甚至不需要使用变换原点
注意事项:
在第二个示例中,我使用的是d3 selection multi
。这允许我将对象传递给.attrs
,而不是对每个属性重复.attr
使用字符串模板文字时,请注意第一个示例中所示的换行符。这将在输出中包含一个换行符,可能会中断代码
无需使用矩阵
变换即可进行缩放:
transform="translate(cx, cy) scale(sx sy) translate(-cx, -cy)"
这里是CSS:
transform: translate(cxpx, cypx) scale(sx, sy) translate(-cxpx, -cypx)
应用transformbox:fill-box
将使SVG中的元素表现为普通HTML元素。然后,您可以像通常一样应用变换原点:中心
(或其他内容)
没错,变换框:填充框
。现在,不需要任何复杂的矩阵元素了,只需在DOM中设置嵌入元素的属性(transform origin=“center”
)就可以了
<circle
fill="#FFFFFF"
cx="82"
cy="81.625"
r="81.5"
transform-origin="center"
></circle>
可以很好地使用css转换非常感谢。我认为旋转工作得很完美,但缩放/调整大小总是以一些随机量结束。我试着使用矩阵,并像“translate(cxsx,cysy)scale(sx,sy)”那样分别进行。同样的结果。它不是transform=“matrix(sx,0,0,sy,cx-sxcx,cy-sycy)”吗?因为你只想通过差异来翻译。我认为这个逻辑是正确的,但它仍然让我失去了位置…现在它起作用了!我只是使用了错误的cx和cy值!非常感谢@是的,矩阵变换适用于任何系统,它只是数学。唯一的区别可能是符号。据我所知,CSS矩阵变换使用与SVG相同的表示法,因此按该顺序使用相同的六个数字应该可以。只是为了澄清一下,cx和cy需要是缩放框中心的偏移量。正如我在CSS框模型中思考的那样,这让我有点困惑@forresto在下面的回答中提到了这一点。FWIW应该在Firefox 19 beta 3中修复,尽管我在Firefox 22中仍然有问题。Mozilla bugzilla清单:@CTheDark,你能重新考虑一下这个问题的公认答案吗?我们现在有了一个更现代的解决方案:哇。如果可以,我会+10。这救了我一天!谢谢。如何在JavaScript中做到这一点?比如element.setAttribute('transform-origin','25px 25px')
?您的github链接404sHello@NuclearPeon,这太棒了,但我似乎无法在代码中实现它。我希望应用的SVG元素已经是一个名为“mainGrid”的变量。我尝试用“mainGrid”替换“view”的实例,但没有效果。我错过了什么?谢谢@sakeferret最明显要检查的是idsvg {
transform-box: fill-box;
}
<circle
fill="#FFFFFF"
cx="82"
cy="81.625"
r="81.5"
transform-origin="center"
></circle>