2016-12-31 70 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