[英]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.