Reputation: 315
As stated in previous questions (for example d3.js Odd Rotation Behavior), when you want to rotate an SVG object on its place you should use
.attr('transform','rotate(45,100,100)')
where the first number is the rotation degrees, and the other two are the coordinates of the rotation origin.
The problem here is that I want to execute the rotation inside a transition:
.transition()
.attr('transform', 'rotate(45,100,100)')
.duration(300)
and I get a strange behaviour, I can see a translation before the expected rotation. You can see the result here: http://jsfiddle.net/uwM8u/121/
Is there a better way to obtain this?
Upvotes: 0
Views: 216
Reputation: 124059
Add a parent <g>
element with the translation so you are actually rotating the shape about the origin.
var svg = d3.select("body")
.append("svg")
.attr("width", 400)
.attr("height", 300);
svg
.append("text")
.text("click the square")
.attr("x", w/2)
.attr("y", w/2)
svg
.append("g")
.attr("transform", "translate(" + diamond.x + "," + diamond.y +")")
.append("rect")
.attr("transform", "rotate(" + rotation + ")")
.attr("x", -diamond.width / 2)
.attr("y", -diamond.width / 2)
.attr("height", diamond.width)
.attr("width", diamond.width)
.attr("fill", "teal")
.on("mousedown", function(){
d3.select(this)
.transition()
.attr("transform", "rotate("+ (rotation+=45) +")")
.duration(300)
});
or as a jsfiddle
Upvotes: 1
Reputation: 109232
The D3 way to do this is to use a custom tween function, which in this case is a simple string interpolation:
.attrTween("transform", function() {
return d3.interpolateString(d3.select(this).attr("transform"),
"rotate(" + (rotation+=45) + "," +
(diamond.x+diamond.width/2) + "," +
(diamond.y+diamond.width/2) + ")");
})
Complete demo here.
Upvotes: 3