简体   繁体   English

为什么旋转元件会反弹?

[英]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 如果你selectidclassrotate慢慢地,你会看到一点中间旋转移动的红点,但selectid我的东西更加稳定不喜欢selectclass就更难反弹

 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 by id or by class 你必须慢慢地旋转到终点,你可以使用d3.interpolate来做补间,并且它可以通过idclass完全旋转

 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM