2016-12-31 68 views
4

我正在尝试使用d3转换 - 我需要翻译和旋转。 我有原始坐标: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 (点击移动开始转变)

+0

与您的实际问题没有关系,但仅仅为了简洁明了,并且避免了任何可能的错误来源:在JSFiddle中,您正在执行'.attr('transform',(d)=> transformFunction d));',它将对'transformFunction()'的调用包装成另一个匿名函数。这基本上等同于'.attr('transform',transformFunction);'只是传递函数的引用。 – altocumulus

+0

我知道,这只是一个例子。在实际应用中,我在那里做了更多的事情,而不仅仅是一个函数调用但是你是对的,在这个例子中它可以被简化。 – Klinki

+0

没关系!只是很多人对此感到困惑。荣誉保持简单,并提供一个精简的例子,而不是只是倾销你的整个代码! – altocumulus

回答

2

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

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

为了能够将这些值之间转换,所述transition.attr()函数使用d3.interpolateTransformSvg(a, b),当涉及到内插transform属性的值。这将执行以下操作:通过调用接口SVGTransformList.consolidate()

  1. 在模块的内部功能parseSvg() D3-插变换的定义是归结名单。

  2. 使用私有函数decompose()这巩固变换分解为它的值翻译旋转歪斜规模

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

在过渡然后通过d3.interpolateTransformSvg(a, b)返回的内插将在ab为各自的值之间进行内插(1)translate,(2)rotate,(3)skewX和(4)在scale正是这种order

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

+0

感谢您的解释!我将尝试使用补间功能。 – Klinki