d3转换过渡中的旋转顺序

时间:2016-12-31 09:49:51

标签: javascript d3.js svg transition

我正在尝试使用d3过渡 - 我需要同时进行平移和旋转。 我有原始坐标:

let data = [
    {x: 100, y: 100, rotation: 45},
];

和2个矩形。一个是先做翻译,另一个是做轮换 第一

这是在绘制矩形后得到的变换:

transform="rotate(45 115 105) translate(100, 100)"
transform="translate(100, 100) rotate(45 115 105)"

它们具有相同的平移和旋转变换,只有不同的是它们的顺序。

然后我改变数据:

data[0].x += 30;
data[0].y += 20;
data[0].rotation += 45;

我希望能够通过这种转变得到一些转变:

transform="rotate(90 145 125) translate(130, 120)"
transform="translate(130, 120) rotate(90 145 125)"

但我真正得到的是:

transform="translate(150, 110) rotate(90)"
transform="translate(400, 100) rotate(90)"
  • 注意它会改变第一个矩形的平移旋转顺序。
  • 它还会从旋转变换中移除旋转中心(它是否会在过渡期间以某种方式计算它?)
  • 如何得到结果数字?

d3过渡如何运作?我需要得到一些可预期的结果,因为我正在尝试使用一些更高级的过渡。

这是一个简单的例子:https://jsfiddle.net/pp6npw4g/2 (点击移动开始转换)

1 个答案:

答案 0 :(得分:2)

这是D3 transform属性值的标准插值的预期行为。 transform属性非常难以转换,因为它的值可能包含一个复杂的转换定义列表,它可能以任何顺序出现,甚至可能在一个列表中出现多次。例如:

transform="translate(100) rotate(30, 100, 100) scale(2.5) translate(-10, -50) skewX(20)"

为了能够在这些值之间进行转换,transition.attr()函数在插入transform属性'值时会使用d3.interpolateTransformSvg(a, b)。这样做如下:

  1. 在模块d3-interpolate的内部函数parseSvg()中,通过调用接口SVGTransformList.consolidate()来简化转换定义列表。

  2. 使用私有函数decompose()然后将此合并转换分解为 translate rotate skew 和比例

  3. 我已经描述了将answer中的转换列表分解为"Replacing d3.transform in D3 v4"的过程。

    在转换过程中,d3.interpolateTransformSvg(a, b)返回的插值器将在ab的相应值之间插入(1)translate,(2){{1 (3)rotate和(4)skewX正是这个order

    这会为您留下合并后的值,这些值最初可能会出乎意料。此外,它解释了为什么转换的顺序因转换而改变。要解决此问题并实现自定义转换,您必须提供可以通过调用transition.attrTween()分配的自定义补间函数。但是,这个功能的实现很大程度上取决于你的需求,超出了这个答案的范围。