这是一个棘手的,因为如果绑定拖动事件到rect
然后移动g
该RECT所属所示,在d3.event
对象计算出的dx
和dy
值将每一后弄乱事件发生,因为这些计算值已经转化为拖拽行为所绑定的元素的本地坐标系统。所以,我们可以自己做一些类似的工作来解决这个问题。这里的诀窍是知道我们真的只需要在拖动动作期间找出鼠标位置x
和y
的变化。而且这个D3使得d3.event
对象的sourceEvent
属性可用。
所以使用底层sourceEvent
在d3.event
对象来获取clientX
和clientY
位置,才算最后的值和当前值,它会告诉你,你需要多远额外给translate
的g
元素之间的差异。您还需要初始化您正在比较的值,以免在开始时出现随机跳跃。幸运的是,我们可以使用dragstart
事件来做到这一点。
一旦我们发现了这一点,我们可以将drag
处理程序绑定到rect
,我们应该很好。
下面是一个正在做我所描述的例子。
var g = d3.select("#mysvg").append("g");
var rect = g.append("rect").attr("height", 100).attr("width", 100);
var circle = g.append("circle").attr("cx", 200).attr("cy", 200).attr("r", 50).attr("fill", "black");
var transX = 0, transY = 0;
var lastX = 0, lastY = 0;
var drag = d3.behavior.drag().on("drag", function() {
transX += d3.event.sourceEvent.clientX - lastX;
transY += d3.event.sourceEvent.clientY - lastY;
g.attr("transform", "translate(" + transX + "," + transY + ")");
lastX = d3.event.sourceEvent.clientX;
lastY = d3.event.sourceEvent.clientY;
}).on("dragstart", function() {
lastX = d3.event.sourceEvent.clientX;
lastY = d3.event.sourceEvent.clientY;
});
rect.call(drag);
circle.on("click", function() {
var now_color = d3.select(this).attr("fill");
if (now_color == "black")
d3.select(this).attr("fill", "green");
else
d3.select(this).attr("fill", "black");
});
//circle.call(drag).on(".drag", null);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg id="mysvg" height="800" width="800"></svg>
这工作!非常感谢你。但是,如果我想将笔刷绑定到组中的数百个元素,并且仅在少数元素上禁用事件。看起来我必须使用for循环来选择我想要调用的元素。这不像D3风格。 :( – 2015-04-15 10:56:05
你不需要一个for循环,只需使用d3选择并调用'.call(drag)'就可以了。 – 2015-04-15 13:27:56