最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - d3.js: How to rotate an SVG around its center while translating? - Stack Overflow

programmeradmin0浏览0评论

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
Add a ment  | 

1 Answer 1

Reset to default 5

Because 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".

发布评论

评论列表(0)

  1. 暂无评论