admin管理员组

文章数量:1415111

Is there a way to click anywhere in an svg and have an element snap to that location and simultaneously begin dragging?

The closest I've gotten is in the code below. Dragging the circle works and clicking elsewhere will make the circle move to that location, but I can't figure out how to start the drag without releasing the mouse and directly clicking the circle.

More generally, how can I start the drag behavior without directly interacting with the element being dragged?

/

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)));
}

Is there a way to click anywhere in an svg and have an element snap to that location and simultaneously begin dragging?

The closest I've gotten is in the code below. Dragging the circle works and clicking elsewhere will make the circle move to that location, but I can't figure out how to start the drag without releasing the mouse and directly clicking the circle.

More generally, how can I start the drag behavior without directly interacting with the element being dragged?

http://jsfiddle/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)));
}
Share Improve this question edited May 25, 2014 at 8:03 sfletche 49.9k31 gold badges109 silver badges120 bronze badges asked May 25, 2014 at 7:13 procterwprocterw 1311 silver badge9 bronze badges 1
  • It sounds like you would want a click handler on your SVG that moves the circle to the location of the click. – Lars Kotthoff Commented May 25, 2014 at 10:49
Add a ment  | 

1 Answer 1

Reset to default 5

UPDATE

I've solved this issue with a sort of brute-force solution: I removed the drag behavior and just added mousedown, mousemove, and mouseup handlers to the svg canvas. This is the functionality I want but I'd still prefer to use d3's drag behavior. If anyone has a more elegant solution do let me know.

http://jsfiddle/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("width", 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; });

本文标签: javascriptD3 Triggering drag during mousedownStack Overflow