D3在mousedown期间触发拖动

时间:2014-05-25 07:13:30

标签: javascript svg d3.js drag-and-drop

有没有办法点击svg中的任意位置并让元素捕捉到该位置并同时开始拖动?

我最接近的是在下面的代码中。拖动圆圈并单击其他位置会使圆圈移动到该位置,但我无法弄清楚如何在不释放鼠标并直接单击圆圈的情况下开始拖动。

更一般地说,如何在不直接与被拖动元素交互的情况下启动拖动行为?

http://jsfiddle.net/Hj44M/1/

var width = 200,
    height = 200,
    radius = 10;

var drag = d3.behavior.drag()
    .origin(function(d) { return d; })
    .on("dragstart", function(){
        d3.event.sourceEvent.stopPropagation()
    })
    .on("drag", dragmove);

var svg = d3.select("body")
    .data([{x: 100, y : 100}])
    .append('svg')
    .attr("height", 200)
    .attr("widht", 200)
    .on("mousedown", function(){
        circle.each(dragmove)
    });


var circle = svg.append("circle")
    .attr("r", radius)
    .attr("cx", function(d) { return d.x; })
    .attr("cy", function(d) { return d.y; })
    .call(drag);

function dragmove(d) {
    d3.select(this)
    .attr("cx", d.x = Math.max(radius, Math.min(width - radius, d3.event.x)))
    .attr("cy", d.y = Math.max(radius, Math.min(height - radius, d3.event.y)));
}

1 个答案:

答案 0 :(得分:3)

更新

我用一种暴力解决方案解决了这个问题:我删除了拖动行为,只是将mousedown,mousemove和mouseup处理程序添加到svg画布中。这是我想要的功能,但我仍然更喜欢使用d3的拖动行为。如果有人有更优雅的解决方案,请告诉我。

http://jsfiddle.net/Hj44M/5/

    var width = 200,
    height = 200,
    radius = 10;

var isDown = false;

var svg = d3.select("body")
    .data([{x: 100, y : 100}])
    .append('svg')
    .attr("height", 200)
    .attr("widht", 200)
    .on("mousedown", function(){
        isDown = true;  
        var coordinates = d3.mouse(this);
        circle.each(function(d){
            circle.attr("cx", d.x = coordinates[0])
            circle.attr("cy", d.y = coordinates[1])
        })

    })
    .on("mousemove", function(){
        if(isDown) {
            var coordinates = d3.mouse(this);
            circle.each(function(d){
                circle.attr("cx", d.x = coordinates[0])
                circle.attr("cy", d.y = coordinates[1])
            })
        }
     })
    .on("mouseup", function(){
        isDown = false;
    });     

var circle = svg.append("circle")
    .attr("r", radius)
    .attr("cx", function(d) { return d.x; })
    .attr("cy", function(d) { return d.y; });