Reputation: 1216
I have a number of circles that i'm using as draggable buttons, i can assign drag events to these and it works correctly, but i want to clone AND drag them, so i end up with multiple buttons (as many as needed). How do i clone and then drag the cloned object?
This is what i have
var a = r.circle(20, 50, 15)
// drag handler
var start = function(x,y,event) {
this.ox = this.attr("cx");
this.oy = this.attr("cy");
this.animate({r: 20, opacity: .25}, 500, ">");
},
move = function(dx, dy) {
this.attr({cx: this.ox + dx, cy: this.oy + dy});
},
up = function () {
this.animate({r: 15, opacity: .5}, 500, ">");
};
a.drag(move, start, up);
I have tried various things, cloning 'a', cloning 'this' in start, but my js knowledge is limited so any help would be appreciated.
Thanks!
Upvotes: 2
Views: 2978
Reputation: 1216
My own solution uses mousemove, see my jsfiddle
It clones on the movement start, mousedown, mouseup, click dont work but this does
a.mousemove(clone_handler);
var clone_handler = function() {
var x = this.clone();
x.drag(move, start, up);
Upvotes: 3
Reputation: 1514
Try using objects.
I created an object to encapsulate the Raphael object and the drag functions to be used on it.
function Button(ix,iy,ir)
{
// grab a reference to the objects "this"
var that = this;
that.a = r.circle(ix, iy, ir).attr({"fill":"red"})
// drag handler
that.start = function(x,y,event) {
that.a.ox = this.attr("cx");
that.a.oy = this.attr("cy");
that.a.animate({r: 20, opacity: .25}, 500, ">");
}
that.move = function(dx, dy) {
that.a.attr({cx: that.a.ox + dx, cy: that.a.oy + dy});
}
that.up = function () {
that.a.animate({r: 15, opacity: .5}, 500, ">");
};
that.a.drag(that.move,that.start,that.up);
return that;
}
The important thing here is to capture the "this" reference in a variable and use the variable to refer to it in your drag functions.
The reason for doing this is that when drag calls "move", "start" and "up", the this object isn't going to refer to your object. "This" changes frequently. By using "that", you're locking in the object to use within these methods.
Here's a better explanation of "that = this". (Be sure to upvote lonesomeday for an excellent explanation)
Here's a fiddle that creates two buttons that you can drag independently.
Hope that helps
Upvotes: 3
Reputation: 411
Not sure if Raphael has clone functionality for a generic node, but cloning a circle can be done manually by doing something like
var circle = r.circle(x, y, r);
var clone = r.circle(circle.cx, circle.cy, circle.r);
clone.attr({ attr1: circle.attr1, ...);
Edit: aparent you can simply call circle.clone() instead of doing the above (Element.clone)
As for cloning when dragging, it may not be straightforward to do as once the drag starts I suppose you can't change the object being dragged. Your alternatives here could be:
Upvotes: 0