d3的过渡和旋转可以很好地协同工作吗? [英] Can d3's transition and rotation play well together?

查看:175
本文介绍了d3的过渡和旋转可以很好地协同工作吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Transitions in combination with rotations have odd results.

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

Here is a fiddle with my problem: http://jsfiddle.net/emperorz/E3G3z/1/ Try clicking on each square to see the varying behaviour.

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

Please forgive the hacked code, but if I use transition with rotation (and x/y placement) then it loops about.

I已经尝试过:

1)所有变换(旋转然后翻译),这看起来基本没问题。有点不稳定。

1) all in the transform (rotate then translate), and that seems mostly okay. A little wobbly.

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

2) just rotate in the transform, positioned using x/y attributes. Flies all over the place, but ends up at the correct spot. Very weird.

3)变换中的所有内容(平移然后旋转),飞走了,最终都在(完全)错误的地方。

嗯。奇怪。

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

Is there a correct approach to rotating shapes with transitions?

直观地说,如果第二个选项有效。

Intuitively, it would be good if the second option worked.

谢谢

推荐答案

旋转SVG在任意轴上的对象,您需要两个转换: translate (设置轴)和 rotate 。你真正想要的是首先完全应用 translate 然后旋转已移动的元素,但它似乎 translate rotate 独立并同时运作。这在正确的位置结束,但动画 translate 实际上是在旋转期间移动轴,从而产生摆动。您可以通过让它们出现在SVG元素层次结构中的不同位置,从 rotate 中隔离 translate 。例如,请查看以下内容:

To rotate an SVG object on an arbitrary axis, you need two transformations: translate (to set the axis) and rotate. What you really want is to apply the translate fully first and then rotate the already moved element, but it appears that translate and rotate operate independently and simultaneously. This ends at the right place, but animating the translate is essentially moving the axis during rotation, creating the wobble. You can isolate the translate from the rotate by having them occur at separate places in the SVG element hierarchy. For example, take a look at the following:

<g class="outer">
    <g class="rect-container">
        <rect class="rotate-me" width=200 height=100 />
    </g>
</g>

您可以将< rect> 居中on(0,0)with translate(-100,-50)。如果将旋转应用于< rect> 元素,它将会抖动,但如果旋转,它将完全旋转 g.rect-container 元素。如果要进一步重新定位,缩放或以其他方式转换元素,请在 g.outer 上执行此操作。而已。您现在可以完全控制转换。

You can center the <rect> on (0,0) with translate (-100, -50). It will wobble if you apply your rotation to the <rect> element, but it will rotate cleanly if you rotate the g.rect-container element. If you want to reposition, scale, or otherwise transform the element further, do so on g.outer. That's it. You now have full control of your transforms.

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

Finding a <rect>'s center is easy, but finding the center of a <path>, <g>, etc. is much harder. Luckily, a simple solution is available in the .getBBox() method (code in CoffeeScript; see below for a JavaScript version*):

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

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

You can now center your element/group by passing the non-wrapped element (using D3's .node() method)

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

对于在单个<$ c上实现此功能的代码$ c>< rect> 和< g> of 2 rect s通过重新定位和缩放,看到这个小提琴

For code that implements this on a both a single <rect> and <g> of of 2 rects with repositioning and scaling, see this fiddle.

*以上代码的Javascript:

*Javascript of the above code:

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 + ")");

这篇关于d3的过渡和旋转可以很好地协同工作吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆