I'm having trouble when I try to correctly execute a rotation animation using the D3.js library. The problem has to do with the point at which I want to rotate the element about.
Here is a fiddle I made to show what I mean (in slow motion): http://jsfiddle.net/74mCb/
It seems like the source of the problem lies here:
.attr("transform", "rotate(-60, 150,130)");
And then I rotate it like so:
.attr("transform", "rotate(40 150,130)");
I would like the butt of the needle to stay in position (to be the center of rotation), could someone please explain what I am doing wrong?
Thanks!
Here's what I think is going on: per the SVG spec, the transform
rotate(40 150,130)
is equivalent to:
translate(150,130) rotate(40) translate(-150, -130)
It looks like D3 is animating the translation as well as the rotation - the internal d3.transform representation of rotate(40 150,130) is a rotate component + a translation component, so both are being included in the transition.
The easiest fix here is to draw your needle at the origin, translate it with an outer g element to the correct position, then rotate it:
var needle = svg
  .append("g")
    .attr("class", "needle")
    .attr("transform", "translate(150 , 130)")
  .append("path")
    .attr("class", "tri")
    // your path may have been prettier
    .attr("d", "M-3 0 L0 -130 L3 0 S3 5 0 5 S-3 5 -3 0 Z")
    .attr("transform", "rotate(-60)");
then
needle
    .transition()
    .duration(2000)
    .attr("transform", "rotate(40)");
See working fiddle: http://jsfiddle.net/nrabinowitz/74mCb/1/
This is a bit tricky to grasp (I don't fully understand it myself) but D3 needs some help knowing how to interpolate between the two strings that represent your rotation.
function turnNeedle()
{
    needle
      .transition()
      .duration(2000)
      .attrTween("transform", tween);
    function tween(d, i, a) {
      return d3.interpolateString("rotate(-60, 150, 130)", "rotate(60, 150, 130)");
    }
}
d is the datum, i is the index, a is the attribute in case you want to make this data-driven. 
http://jsfiddle.net/SHF2M/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With