這是一個棘手的,因爲如果綁定拖動事件到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