[英]Why does rotating element make it bounce?
I've got an svg element and I'm adding a simple rotation attribute to it. 我有一个svg元素,我正在添加一个简单的旋转属性。 Problem is, I want the element to rotate relative to center of itself, not the whole svg, so I specify x and y for rotate, but it has a weird bouncy effect.
问题是,我希望元素相对于自身的中心旋转,而不是整个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>
As an alternative, I tried adding transform-origin
on css, something like transform-origin: 800px 800px;
作为替代方案,我尝试在css上添加
transform-origin
,类似于transform-origin: 800px 800px;
(but with valid center px of course) and while it works in Chrome, it doesn't work in IE and Safari. (但当然使用有效的中心px)虽然它在Chrome中有效,但它在IE和Safari中不起作用。
Why is supplying x and y on rotate making my element bounce? 为什么在旋转时提供x和y使我的元素反弹?
There are a few questions floating around that deal with this issue. 关于这个问题的处理有几个问题。 Here's one that explains a bit what's going on: D3.js animate rotation
这里有一个解释了一下发生了什么: D3.js动画旋转
The way Mike Bostock does it here: https://bl.ocks.org/mbostock/3305854 is by placing the object in a <g>
that is translated to the position you want and then rotating. Mike Bostock在这里做的方式: https : //bl.ocks.org/mbostock/3305854是将对象放在
<g>
,然后转换到你想要的位置然后旋转。 This might be the easiest way to get a nice animation. 这可能是获得精彩动画的最简单方法。 For example:
例如:
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})`; }); }
<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>
LOOK AT THIS DIFFERENT
看看这个不同
if you select
by id
or by class
and rotate
it slowly, you will see the red dot in middle rotation move by little, but select
by id
i thing it more stable not like select
by class
it bouncing harder 如果你
select
的id
或class
和rotate
慢慢地,你会看到一点中间旋转移动的红点,但select
的id
我的东西更加稳定不喜欢select
的class
就更难反弹
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})`; }); }
<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>
then if you bouncing it with harsh value(big value) you will defintely see the red dot bouncing, but once again select
by id
doing more stable 然后,如果你用苛刻的价值(大价值)弹跳它,你将彻底看到红点反弹,但再一次
select
id
更稳定
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})`; }); }
<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>
SOLUTION
解
you must make it slowly to rotated to end point, you can make tween using
d3.interpolate
, and boom... it rotated perfecly byid
or byclass
你必须慢慢地旋转到终点,你可以使用
d3.interpolate
来做补间,并且它可以通过id
或class
完全旋转
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); } }
<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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.