The Problem:
I have been trying, to no avail, to find a general solution for simultaneously rotating and translating an SVG with d3.js v4.2.2.
I can get the SVG starting and ending in the correct positions, but the easing in-between is all wrong. Below is a JSFiddle where I have done a rotate+translate on many instances of the same SVG pulled from the DOM, each to a different amount rotation according to the datapoint.
A key thing to note is that I need this solution to work when translating from (100,100) to (500,500) just as well as when I start from (0,0).
/
var serializer = new XMLSerializer();
var svgNode = serializer.serializeToString(document.querySelector('#svgs svg defs svg'));
var dataset = [1,8,15,22,29,36,43,50,57,64,71,78,85,92,99,106,113,120,127,134,141,148,155,162,169,176,183,190,197,204,211,218,225,232,239,246,253,260,267,274,281,288,295,302,309,316,323,330,337,344,351,358]
var wrapper = d3
.select('#game svg')
.attr('width', window.innerWidth)
.attr('height', window.innerHeight)
.selectAll('g')
.data(dataset)
.enter()
.append('g')
.html(function(d) { return svgNode; })
.transition()
.duration(1500)
.attr('transform', function(d) {
return 'translate(500,300)' +
'rotate(' + d * 1.8 + ', 63, 54.77)';
});
(Unfortunately, I wasn't able to get D3 v4 working in JSFiddle, so JSFiddle is using v3 here. However, the problem is the same).
My expected behaviour: All of the chickens rotate around the same center, never extending past the dimensions of the circle seen at the end of the animation.
The actual result: All chickens rotate around the translated original position of the top left corner before returning to the correct position at the end.
Solutions That Didn't Work for Me:
How to rotate an object around the center in d3.js
- This is about rotating around a fixed point further away, not around a point on the object one is trying to rotate
SVG rotation anchorpoint
- This might work, but pletely takes me out of the D3 ecosystem
How do I rotate or scale (transform) an SVG path relative to its center point?
- I need the solution to start from an arbitrary point, not always the origin @ (0,0)
In Conclusion:
I'm pretty bewildered at the moment, and any help is greatly appreciated. Thanks for your time.
The Problem:
I have been trying, to no avail, to find a general solution for simultaneously rotating and translating an SVG with d3.js v4.2.2.
I can get the SVG starting and ending in the correct positions, but the easing in-between is all wrong. Below is a JSFiddle where I have done a rotate+translate on many instances of the same SVG pulled from the DOM, each to a different amount rotation according to the datapoint.
A key thing to note is that I need this solution to work when translating from (100,100) to (500,500) just as well as when I start from (0,0).
https://jsfiddle/3jbv23em/
var serializer = new XMLSerializer();
var svgNode = serializer.serializeToString(document.querySelector('#svgs svg defs svg'));
var dataset = [1,8,15,22,29,36,43,50,57,64,71,78,85,92,99,106,113,120,127,134,141,148,155,162,169,176,183,190,197,204,211,218,225,232,239,246,253,260,267,274,281,288,295,302,309,316,323,330,337,344,351,358]
var wrapper = d3
.select('#game svg')
.attr('width', window.innerWidth)
.attr('height', window.innerHeight)
.selectAll('g')
.data(dataset)
.enter()
.append('g')
.html(function(d) { return svgNode; })
.transition()
.duration(1500)
.attr('transform', function(d) {
return 'translate(500,300)' +
'rotate(' + d * 1.8 + ', 63, 54.77)';
});
(Unfortunately, I wasn't able to get D3 v4 working in JSFiddle, so JSFiddle is using v3 here. However, the problem is the same).
My expected behaviour: All of the chickens rotate around the same center, never extending past the dimensions of the circle seen at the end of the animation.
The actual result: All chickens rotate around the translated original position of the top left corner before returning to the correct position at the end.
Solutions That Didn't Work for Me:
How to rotate an object around the center in d3.js
- This is about rotating around a fixed point further away, not around a point on the object one is trying to rotate
SVG rotation anchorpoint
- This might work, but pletely takes me out of the D3 ecosystem
How do I rotate or scale (transform) an SVG path relative to its center point?
- I need the solution to start from an arbitrary point, not always the origin @ (0,0)
In Conclusion:
I'm pretty bewildered at the moment, and any help is greatly appreciated. Thanks for your time.
Share Improve this question edited May 23, 2017 at 12:22 CommunityBot 11 silver badge asked Aug 31, 2016 at 5:14 Sebastian Kazenbroot-GuppySebastian Kazenbroot-Guppy 851 silver badge6 bronze badges 1-
1
Not related to your problem, but to use d3 4.x in JSfiddle you just need to reference it in the HTML panel, like this:
<script src="https://d3js/d3.v4.min.js"></script>
– Gerardo Furtado Commented Aug 31, 2016 at 5:50
1 Answer
Reset to default 5Because D3 transitions applies both the translate and the rotate together you get some awkward looking animations even though the end result is what you are looking for.
D3 provides a d3.interpolateString which handles executing the animation the way you would like. d3.interpolateString requires a starting and ending transform. d3.interpolateString is used within attrTween.
Replace
.attr('transform', function(d) {
return 'translate(500,300)' +
'rotate(' + d * 1.8 + ', 63, 54.77)';
});
With
.attrTween('transform', function(d, i, a) {
return d3.interpolateString('translate(0,0) rotate(0)',
'translate(500,300)' +
'rotate(' + d * 1.8 + ', 63, 54.77)');
});
Here is an updated jsfiddle with a tweak to the translation for better viewability for smaller screens.
https://jsfiddle/3jbv23em/16/
A helpful link with the same issue is "D3.js animate rotation".