javascript - d3.js:如何在翻译时围绕其中心旋转 SVG?

标签 javascript html css d3.js svg

问题:

我一直在尝试寻找一种通用解决方案,以使用 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)';
            });

(不幸的是,我无法让 D3 v4 在 JSFiddle 中工作,所以 JSFiddle 在这里使用的是 v3。但是,问题是一样的)。

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

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

对我不起作用的解决方案:

How to rotate an object around the center in d3.js

  • 这是关于围绕更远的固定点旋转,而不是围绕试图旋转的物体上的点旋转

SVG rotation anchorpoint

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

How do I rotate or scale (transform) an SVG path relative to its center point?

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

总结:

我现在很困惑,非常感谢任何帮助。感谢您的宝贵时间。

最佳答案

因为 D3 transitions 同时应用了平移和旋转,所以即使最终结果是您想要的,您也会得到一些看起来很尴尬的动画。

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 animate rotation”。

关于javascript - d3.js:如何在翻译时围绕其中心旋转 SVG?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39241248/

相关文章:

javascript - 在 D3 视觉 (flare.json) 中获取指向被点击元素的路径

javascript - 向格式为 'h:i:s: A' 的字符串添加分钟和秒的最快方法

javascript - 如何在javascript中选择名称以某个特定字符串开头的元素?

javascript - 尝试让一个按钮用作提交按钮

javascript - 使用屏幕高度动态填充框

css - Bootstrap 4 : Stop collapse from pushing content down

html - Bootstrap 模式中的 Dropzone.js 打破流程和样式

javascript - Jquery UI 位置 : wrong top offset

用于同步事件的 JavaScript 库

html - 表单标签打破导航栏布局