d3.js:如何在平移SVG时围绕其中心旋转?

7

问题:

我一直在尝试寻找一种通用解决方案,以便在d3.js v4.2.2中同时旋转和平移SVG,但一直没有成功。

我可以让SVG在正确的位置开始和结束,但是在过渡期间的缓动效果都不对。下面是一个JSFiddle链接,我在其中对来自DOM的多个相同SVG实例进行了旋转+平移,每个实例根据数据点旋转不同的角度。

需要注意的关键一点是,我需要这个解决方案能够在从(100,100)到(500,500)平移时正常工作,也能在从(0,0)开始时正常工作。

https://jsfiddle.net/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)';
            });

很不幸,在JSFiddle上我无法使用D3 v4,所以这里使用的是v3。然而,问题是相同的。

我期望的行为: 所有的小鸡都围绕同一个中心旋转,永远不会超出动画结束时看到的圆形的尺寸。

实际结果: 所有的小鸡都围绕左上角的平移原始位置旋转,最后回到正确的位置。

没有解决我的方案:

如何在d3.js中围绕中心旋转对象

  • 这是关于围绕更远的固定点旋转,而不是围绕要旋转的对象上的点旋转

SVG 旋转锚点

  • 这可能行得通,但完全让我走出了D3生态系统

如何相对于中心点旋转或缩放(变换)SVG路径?

  • 我需要从任意点开始解决方案,而不仅仅是原点 @ (0,0)

总之:

我现在感到非常困惑,非常感谢任何帮助。感谢您花费时间。


1
与您的问题无关,但要在JSfiddle中使用d3 4.x,您只需要在HTML面板中引用它,就像这样:<script src="https://d3js.org/d3.v4.min.js"></script> - Gerardo Furtado
1个回答

5
因为D3过渡同时应用了translate和rotate,所以动画看起来有些尴尬,尽管最终结果是你想要的。
D3提供了d3.interpolateString来处理按你希望的方式执行动画。d3.interpolateString需要起始和结束的变换。d3.interpolateString在attrTween中被使用。
替换为:
.attr('transform', function(d) { 
    return 'translate(500,300)' +
           'rotate(' + d * 1.8 + ', 63, 54.77)';
});

随着

.attrTween('transform', function(d, i, a) { 
    return d3.interpolateString('translate(0,0) rotate(0)',
                                'translate(500,300)' +
                                'rotate(' + d * 1.8 + ', 63, 54.77)');
});

这里有一个更新的 jsfiddle,针对小屏幕视图做了调整以提高可视性。

https://jsfiddle.net/3jbv23em/16/

一个有用的链接,涉及相同问题:D3.js 旋转动画


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接