Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does rotating element make it bounce?

I've got an svg element and I'm adding a simple rotation attribute to it. 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.

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; (but with valid center px of course) and while it works in Chrome, it doesn't work in IE and Safari.

Why is supplying x and y on rotate making my element bounce?

like image 382
LocustHorde Avatar asked Jul 28 '26 04:07

LocustHorde


1 Answers

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

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. 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>
like image 149
Mark Avatar answered Jul 30 '26 18:07

Mark



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!