d3的过渡和旋转可以很好地协同工作吗?

emp*_*orz 2 javascript transition rotation jsfiddle d3.js

与旋转相结合的过渡具有奇怪的结果.

这是我的问题的小提琴:http://jsfiddle.net/emperorz/E3G3z/1/ 尝试点击每个方块以查看不同的行为.

请原谅被黑客入侵的代码,但如果我使用带有旋转的转换(和x/y放置),那么它就会循环.

我试过了:

1)所有在变换(旋转然后翻译),这似乎大多没关系.有点不稳定.

2)只需在变换中旋转,使用x/y属性定位.飞到各处,但最终到达正确的位置.很奇怪.

3)所有在变换中(平移然后旋转),飞走,并最终在(完全)错误的地方.

嗯.奇怪.

是否有正确的方法来旋转带有过渡的形状?

直观地说,如果第二种选择有效,那就太好了.

谢谢

rdi*_*ert 6

要在任意轴上旋转SVG对象,您需要两个转换:( translate设置轴)和rotate.你真正想要的是应用translate完全第一,然后旋转已经转移元素,但现在看来,translaterotate独立和同时操作.这在正确的位置结束,但动画translate是在旋转期间基本上移动轴,从而产生摆动.您可以隔离translaterotate通过使它们发生在SVG元素层次不同的地方.例如,看看以下内容:

<g class="outer">
    <g class="rect-container">
        <rect class="rotate-me" width=200 height=100 />
    </g>
</g>
Run Code Online (Sandbox Code Playgroud)

您可以将<rect>(0,0)居中translate (-100, -50).如果你申请你旋转到它会晃动<rect>元素,但它会干净转动,如果你rotateg.rect-container元素.如果要进一步重新定位,缩放或以其他方式转换元素,请执行此操作g.outer.而已.您现在可以完全控制变换.

查找<rect>的中心很容易,但找到的中心<path>,<g>等更难.幸运的是,.getBBox()方法中提供了一个简单的解决方案(CoffeeScript中的代码;请参阅下面的JavaScript版本*):

centerToOrigin = (el) ->
    boundingBox = el.getBBox()
    return {
        x: -1 * Math.floor(boundingBox.width/2),
        y: -1 * Math.floor(boundingBox.height/2) 
    }
Run Code Online (Sandbox Code Playgroud)

您现在可以通过传递非包装元素来居中您的元素/组(使用D3的.node()方法)

group = d3.select("g.rotate-me")
center = centerToOrigin(group.node())
group.attr("transform", "translate(#{center.x}, #{center.y})")
Run Code Online (Sandbox Code Playgroud)

对于在重新定位和缩放的单个<rect><g>2 rect秒上实现此功能的代码,请参阅此小提琴.


*以上代码的Javascript:

var center, centerToOrigin, group;

centerToOrigin = function(el) {
  var boundingBox;
  boundingBox = el.getBBox();
  return {
    x: -1 * Math.floor(boundingBox.width / 2),
    y: -1 * Math.floor(boundingBox.height / 2)
  };
};

group = d3.select("g.rotate-me");
center = centerToOrigin(group.node());
group.attr("transform", "translate(" + center.x + ", " + center.y + ")");
Run Code Online (Sandbox Code Playgroud)