我需要使用javascript调整SVG文档中的某些元素并调整其大小。问题是,默认情况下,它总是在(0, 0)
- 左上角的原点周围应用变换。
如何重新定义此变换锚点?
我尝试使用transform-origin
属性,但它不会影响任何内容。
我就这样做了:
svg.getDocumentById('someId').setAttribute('transform-origin', '75 240');
虽然我可以在Firefox中看到属性设置正确,但它似乎没有将关键点设置为我指定的点。我尝试了center bottom
和50% 100%
这样的事情,有或没有括号。到目前为止没有任何工作。
有人可以帮忙吗?
答案 0 :(得分:129)
旋转使用transform="rotate(deg, cx, cy)"
,其中deg是您想要旋转的度数,(cx,cy)定义旋转中心。
对于缩放/调整大小,你必须翻译(-cx,-cy),然后缩放然后转换回(cx,cy)。您可以使用matrix transform:
执行此操作transform="matrix(sx, 0, 0, sy, cx-sx*cx, cy-sy*cy)"
其中sx是x轴的缩放系数,sy是y轴。
答案 1 :(得分:18)
如果您可以使用固定值(不是"中心"或" 50%"),您可以改用CSS:
AppWidget
某些浏览器(如Firefox)无法正确处理相对值。
答案 2 :(得分:11)
如果你像我一样想要平移然后用变换原点进行缩放,你需要多一点。
// <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);
};
答案 3 :(得分:11)
svg {
transform-box: fill-box;
}
应用transform-box: fill-box
将使SVG中的元素的行为像普通的HTML元素一样。然后,您可以像平常一样应用transform-origin: center
(或其他方法)
是的,transform-box: fill-box
。如今,不需要任何复杂的矩阵东西
答案 4 :(得分:8)
无需使用matrix
转换即可进行缩放:
transform="translate(cx, cy) scale(sx sy) translate(-cx, -cy)"
这里是CSS:
transform: translate(cxpx, cypx) scale(sx, sy) translate(-cxpx, -cypx)
答案 5 :(得分:0)
我有类似的问题。但我使用 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
。
使用字符串模板文字时,请注意第一个示例中所示的换行符。这将在输出中包含换行符,可能会破坏您的代码。
答案 6 :(得分:-1)
在DOM内部设置嵌入元素的属性(transform-origin="center"
对我来说很成功
<circle
fill="#FFFFFF"
cx="82"
cy="81.625"
r="81.5"
transform-origin="center"
></circle>
使用CSS转换效果很好