[英]d3.js Node “jumps back” on fast drag in force layout
我正在使用零重力和電荷值的力布局:
var force = d3.layout.force()
.gravity(0)
.charge(0)
.friction(0.9)
.linkDistance(250)
.linkStrength(1)
.size([width, height])
.on("tick", tick);
function tick(e) {
d.y = Math.max(d.radius, Math.min(height - d.radius, d.y));
d.x = Math.max(d.radius, Math.min(width - d.radius, d.x));
return "translate(" + d.x + "," + d.y + ")";
});
}
有一個圓圈。 問題是當我快速拖動時,圓圈“跳回”。 任何幫助,將不勝感激。 謝謝。
CodePen: http ://codepen.io/vanquang9387/pen/gpLpGE?edit = 001
改變這個......
.friction(0.9)
對...
.friction(0)
在d3中的force layout模塊內部,有一個force.tick
方法,在每個動畫幀之前調用。 這是重新計算節點位置的位置。 對鏈路進行了計算,其中考慮了鏈路strength
, weights
和目標linkDistance
; gravity
計算,它是每個節點距布局中心的距離的函數; 以及基於charge
, charge
chargeDistance
和節點的相對位置的電荷計算。 還有friction
計算。 所有這些 - 除了friction
計算 - 都考慮了布局( alpha
)的當前“溫度”,這實際上只是一個指數衰減值,它是自布局開始以來經過了多少滴答的函數。
這些計算順序應用於布局的所有元素,每個步驟的輸入位置是前一個的輸出。 但“固定”的節點的處理方式不同的摩擦計算和被拖動節點fixed
由拖動行為。
friction
不是真正的“摩擦”,它更像是WIKI中解釋的速度衰減, friction
計算是通過將節點移動到前一刻度結束時的位置來保持節點的速度( px
, py
) 。 移開的距離與每個節點的速度成比例,該速度基於( px
, py
)與當前tick
前一步驟(鏈接,電荷和重力)計算的位置之間的距離(實際上它更多一點)比那更復雜,因為電荷計算實際上是“非因果”並且改變了以前的位置,但這並不影響摩擦計算的原理)。
在拖,( px
, py
)與由每拖動行為鼠標位置更新的mousemove
。 然后 ,在下一個刻度線上,這些值將復制到力布局中的( x
, y
)。 因此,在拖動過程中, 前一個位置實際上是當前位置,反之亦然! 因此,當阻力結束時,摩擦計算中使用的速度與其實際速度方向相反 ,因此friction
計算試圖保持這個......這就是它向后跳躍的原因。
我的下一步行動是找到一種在dragend
事件處理程序中將( px
, py
)設置為( x
, y
)的dragend
。
比如這樣......
var stdDragEnd = force.drag().on("dragend.force");
force.drag().on("dragend.force", myDragEnd);
function myDragEnd(d) {
d.px = d.x; d.py = d.y;
stdDragEnd.call(this, d)
}
您可以將它放在已定義force
變量的代碼中的任何位置。 這個想法是掛鈎標准行為而不是替換它。
現在,即使你將摩擦設置為1.0,節點也會在dragend之后停止。
順便說一下,你不需要根據代碼的當前狀態來保留this
上下文,但無論如何,我認為這是一個好習慣。 誰知道未來將會帶來什么;)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.