Question

I'd like to create a straight line in SVG that is anchored at one point. When the user clicks and drags the other endpoint, that endpoint follows their cursor. I'm using snap.svg for this.

My idea to do this was to first draw a line:

var line = paper.line( 300, 250, 450, 150 );

line.attr({
  stroke: "#000",
  strokeWidth: 5,
  strokeLinecap:"round"
});

then create a controlling circle that I track drag events on. In the drag callback I would update the x2 and y2 properties of the line using the dx and dy arguments passed.

The first thing I noticed is that simply setting the attributes causing things to blow up. I'm not entirely sure I understand why this is, but it seems like it might be the case that my callback is called repeatedly before it has a chance to run. Then when it 'catches up' to itself it somehow overshoots. I'm not too sure.

Anyway, through Googling I was able to determine that using the transform property on the controlling circle would allow me to emulate the default drag method:

var move = function(dx,dy) {
  // This appends the new transform to the original
  this.attr({
    transform: this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [dx, dy]
  });
} 

// Maybe this saves the current transform if it hasn't happened yet?
var start = function() {
  this.data('origTransform', this.transform().local );
}

var circle = paper.circle( 450, 150, 5 );

circle.drag(move, start);

At this point, I'm stuck. I can't use the same transform trick for the x2 and y2 attributes of the line. And if I set them directly I get that overshooting problem.

SVG pros – any thoughts on how to do this?

Was it helpful?

Solution

I made sample code. http://jsdo.it/defghi1977/kxK1


var paper = Snap().attr({width:"500",height:"500"});
var line = paper.line(0,0,100,100)
    .attr({strokeWidth:5,stroke:"black",strokeLinecap:"round"});
var circle = paper.circle(100,100,10).attr({fill:"red"});
var x,y;
circle.drag(function(dx,dy){
    circle.attr({cx:+x+dx,cy:+y+dy});
    line.attr({x2:+x+dx,y2:+y+dy});
},function(){
    x = line.attr("x2");
    y = line.attr("y2");
},function(){});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top