我需要使用javascript调整SVG文档中的某些元素的大小和旋转。问题是,默认情况下,它总是在原点(0, 0)
-左上角周围应用变换。
我如何重新定义这个转换锚点?
我尝试使用transform-origin
属性,但它不影响任何东西。
我是这样做的:
svg.getDocumentById('someId').setAttribute('transform-origin', '75 240');
它似乎没有将枢纽点设置为我指定的点,尽管我可以在Firefox中看到该属性是正确设置的。我尝试了center bottom
和50% 100%
这样的东西,有或没有括号。
有人能帮忙吗?
使用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轴的比例因子
2020年新方案
svg * {
transform-box: fill-box;
}
应用transform-box: fill-box
将使SVG中的元素表现为普通的HTML元素。然后你可以应用transform-origin: center
(或其他东西),因为你通常会
没错,transform-box: fill-box
。现在,不需要任何复杂的矩阵
如果你可以使用一个固定的值(不是"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)不能正确处理相对值
无需使用matrix
转换即可缩放:
transform="translate(cx, cy) scale(sx sy) translate(-cx, -cy)"
这里是CSS:
transform: translate(cxpx, cypx) scale(sx, sy) translate(-cxpx, -cypx)
如果你像我一样,想要用transform-origin平移然后缩放,你需要更多的东西
// <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/
在DOM内设置嵌入元素的属性(transform-origin="center"
)对我来说很有用
<circle
fill="#FFFFFF"
cx="82"
cy="81.625"
r="81.5"
transform-origin="center"
></circle>
您可以在0,0原点附近构建任何您想要的内容,然后将其放入组<g></g>
中并对整个组进行矩阵翻译。像这样,对象将始终围绕0,0旋转,但整个组将移动(平移)到其他地方,并在旋转后应用平移矩阵。
<g transform="matrix(1 0 0 1 160 200)">
<polygon id="arrow-A" class="arrow" points="0,4 -90,0 0,-4 "/>
</g>
<style>
.arrow {
transform: rotate(60deg);
}
/* OR */
#arrow-A {
transform: rotate(60deg);
}
</style>
OR scripting:
<script>
document.getElementById("arrow-A").setAttribute("transform", "rotate(60)");
</script>
这将创建一个箭头(例如:对于量规),将宽端移至[0,0],并将其移至[160,200]。无论对"箭头"类应用哪个旋转,它都会围绕[160,200]旋转。
测试版本:Chrome, Firefox, Opera, MS Edge
我也遇到过类似的问题。但是我使用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中不起作用!我要做的是将circle
包装在g
标签和translate
标签中,使用与上面相同的定位公式。然后,我将circle
添加到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目标circle
而不是.dot
,添加transform: scale(2)
。我甚至不需要使用transform-origin
。
指出:
我在第二个例子中使用
d3-selection-multi
。这允许我将对象传递给.attrs
,而不是为每个属性重复.attr
。当使用字符串模板文字时,要注意第一个示例中所示的换行。这将在输出中包含一个换行符,并可能破坏您的代码。