我有一个svg元素,我正在为它添加一个简单的旋转属性。 问题是,我希望元素相对于自身的中心旋转,而不是整个svg,所以我指定旋转的x和y,但它有一个奇怪的弹性效果。
let currentAngle = 0;
function rotate() {
d3.select('.group1')
.transition()
.attr('transform', function() {
let bb = this.getBBox();
let rx = bb.x + bb.width / 2;
let ry = bb.y + bb.height / 2;
currentAngle += 90;
return `rotate(${currentAngle}, ${rx}, ${ry})`;
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg viewbox="0 0 1600 1600" width="500" height="500">
<g class="group1" onclick="rotate()">
<rect x="250" y="250" width="100" height="100" />
<circle cx="420" cy="300" r="50" />
</g>
</svg>
作为替代方案,我尝试在css上添加transform-origin
,类似于transform-origin: 800px 800px;
(但当然有效中心px),虽然它在Chrome中有效但在IE和Safari中无效
为什么在旋转时提供x和y使我的元素反弹?
答案 0 :(得分:2)
这个问题涉及到一些问题。这是解释一下发生了什么的问题:D3.js animate rotation
Mike Bostock在这里做的方式:https://bl.ocks.org/mbostock/3305854是将对象放在<g>
中,然后转换到你想要的位置然后旋转。这可能是获得精彩动画的最简单方法。例如:
let currentAngle = 0;
function rotate() {
d3.select('rect')
.transition()
.attr('transform', function() {
let bb = this.getBBox();
let rx = bb.x + bb.width / 2;
let ry = bb.y + bb.height / 2;
currentAngle += 45;
return `rotate(${currentAngle}, ${rx}, ${ry})`;
});
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg viewbox="0 0 1600 1600" width="500" height="500">
<g transform="translate(250, 250)">
<rect x="-50", y="-50" width="100" height="100" onclick="rotate()" />
</g>
</svg>
&#13;
答案 1 :(得分:1)
看看这个不同的
如果select
id
或class
和rotate
慢慢地,你会看到中间旋转的红点一点一点地移动,但是{{1} } select
我认为它更稳定而不像id
select
更强大地弹跳
class
&#13;
let currentAngle = 0;
let currentAngle2 = 0;
function rotate() {
d3.select('#aa')
.transition()
.duration(300)
.attr('transform', function() {
let bb = this.getBBox();
let rx = bb.x + bb.width / 2;
let ry = bb.y + bb.height / 2;
d3.select(this).append('circle')
.attr('cx',rx)
.attr('cy',ry)
.attr('r',20)
.attr('fill','red')
currentAngle += 10;
return `rotate(${currentAngle}, ${rx}, ${ry})`;
});
}
function rotate2() {
d3.selectAll('.aa')
.transition()
.attr('transform', function() {
let bb = this.getBBox();
let rx = bb.x + bb.width / 2;
let ry = bb.y + bb.height / 2;
d3.select(this).append('circle')
.attr('cx',rx)
.attr('cy',ry)
.attr('r',20)
.attr('fill','red')
currentAngle2 += 10;
return `rotate(${currentAngle2}, ${rx}, ${ry})`;
});
}
&#13;
然后,如果你用苛刻的价值(大值)反弹,你会看到红点反弹,但再次<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg viewbox="0 0 1600 1600" width="500" height="500">
<g id ='aa' onclick="rotate()">
<rect x="100", y="100" width="100" height="100" />
<circle cx="250" cy="150" r="50"/>
</g>
<g class ='aa' onclick="rotate2()">
<rect x="600", y="100" width="100" height="100" />
<circle cx="750" cy="150" r="50" />
</g>
</svg>
select
做得更稳定
id
&#13;
let currentAngle = 0;
let currentAngle2 = 0;
function rotate() {
d3.select('#aa')
.transition()
.duration(300)
.attr('transform', function() {
let bb = this.getBBox();
let rx = bb.x + bb.width / 2;
let ry = bb.y + bb.height / 2;
d3.select(this).append('circle')
.attr('cx',rx)
.attr('cy',ry)
.attr('r',20)
.attr('fill','red')
currentAngle += 90;
return `rotate(${currentAngle}, ${rx}, ${ry})`;
});
}
function rotate2() {
d3.selectAll('.aa')
.transition()
.attr('transform', function() {
let bb = this.getBBox();
let rx = bb.x + bb.width / 2;
let ry = bb.y + bb.height / 2;
d3.select(this).append('circle')
.attr('cx',rx)
.attr('cy',ry)
.attr('r',20)
.attr('fill','red')
currentAngle2 += 90;
return `rotate(${currentAngle2}, ${rx}, ${ry})`;
});
}
&#13;
解决方案
你必须慢慢地旋转到终点,你可以做补间 使用
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <svg viewbox="0 0 1600 1600" width="500" height="500"> <g id ='aa' onclick="rotate()"> <rect x="100", y="100" width="100" height="100" /> <circle cx="250" cy="150" r="50"/> </g> <g class ='aa' onclick="rotate2()"> <rect x="600", y="100" width="100" height="100" /> <circle cx="750" cy="150" r="50" /> </g> </svg>
,然后繁荣......它完全按d3.interpolate
或者{。}旋转id
class
&#13;
let currentAngle = 0;
let currentAngle2 = 0;
function rotate() {
d3.select('#aa')
.transition()
.duration(300)
.attrTween("transform", tween);
/*
.attr('transform', function() {
let bb = this.getBBox();
let rx = bb.x + bb.width / 2;
let ry = bb.y + bb.height / 2;
d3.select(this).append('circle')
.attr('cx',rx)
.attr('cy',ry)
.attr('r',20)
.attr('fill','red')
currentAngle += 10;
// console.log(rx,ry,currentAngle)
return `rotate(${currentAngle}, ${rx}, ${ry})`;
});
*/
function tween(d, i, a) {
let bb = this.getBBox();
let rx = bb.x + bb.width / 2;
let ry = bb.y + bb.height / 2;
d3.select(this).append('circle')
.attr('cx',rx)
.attr('cy',ry)
.attr('r',20)
.attr('fill','red')
var e = `rotate(${currentAngle}, ${rx}, ${ry})`
currentAngle += 90;
var o = `rotate(${currentAngle}, ${rx}, ${ry})`
return d3.interpolateString(e,o);
}
}
function rotate2() {
d3.selectAll('.aa')
.transition()
.duration(300)
.attrTween("transform", tween);
/*
.attr('transform', function() {
let bb = this.getBBox();
let rx = bb.x + bb.width / 2;
let ry = bb.y + bb.height / 2;
d3.select(this).append('circle')
.attr('cx',rx)
.attr('cy',ry)
.attr('r',20)
.attr('fill','red')
currentAngle2 += 10;
// console.log(rx,ry,currentAngle)
return `rotate(${currentAngle2}, ${rx}, ${ry})`;
});
*/
function tween(d, i, a) {
let bb = this.getBBox();
let rx = bb.x + bb.width / 2;
let ry = bb.y + bb.height / 2;
d3.select(this).append('circle')
.attr('cx',rx)
.attr('cy',ry)
.attr('r',20)
.attr('fill','red')
var e = `rotate(${currentAngle2}, ${rx}, ${ry})`
currentAngle2 += 90;
var o = `rotate(${currentAngle2}, ${rx}, ${ry})`
return d3.interpolateString(e,o);
}
}
&#13;