Reputation: 12869
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?
Upvotes: 2
Views: 6313
Reputation: 5349
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(){});
Upvotes: 10