Laurento-kun
Laurento-kun

Reputation: 13

Snap.svg drag a group along a path and save position

I'm trying Snap to manipulate SVG but I'm having some issues when dragging a group of elements along a path.

I modified this code that I found here.

start = function () {
    this.data("ox", +this.getBBox().cx);
    this.data("oy", +this.getBBox().cy);
},
move = function (dx, dy) {
    var tmpPt = {
        x: this.data('ox') + dx,
        y: this.data('oy') + dy
    };
    // move will be called with dx and dy
    l = gradSearch(l, tmpPt);
    pt = path.getPointAtLength(l);

    if (!isNaN(pt.x) && !isNaN(pt.y)) {
        this.transform('t' + (pt.x - this.data("ox")) + ',' + (pt.y - this.data("oy")));
    };
},
end = function () {
    console.log('End of drag');
}

I can drag the group, it stays where I drop it, but when I start to drag again, the group goes back to it's origin point and if I go crazy it starts to be really buggy.

I'm new to SVG, I tried some tutorials to learn but this stuff seams to be out of my league, I'd really appreciate some insights from you

Edit : It's better with my code, thanks for pointing that out Ian.

Upvotes: 1

Views: 318

Answers (1)

Ian
Ian

Reputation: 13852

I think the problem is that you are resetting ox each time. In the previous examples, they used attr('cx') not ox, so they were always referencing the very original position of the shape to offset from. As you are resetting this each time, the difference will always be zero, so it resets to scratch. So you need a couple of modifications.

So lets all 'ox' the 'original position' before we do anything as our base. And call 'sx' the 'starting position' that we figure out every drag start. We will need this to add 'dx' (the delta difference to add in a drag).

We can store the original position intitially...and then change the transform later to reference that original position, rather than the start position.

group.drag(move, start, end);
group.data("ox", +group.getBBox().cx);
group.data("oy", +group.getBBox().cy);

start = function () {
    this.data("sx", +this.getBBox().cx);
    this.data("sy", +this.getBBox().cy);
},

move = function (dx, dy) {

    var tmpPt = {
        x: this.data('sx') + dx,
        y: this.data('sy') + dy
    };

    l = gradSearch(l, tmpPt);

    pt = path.getPointAtLength(l);

    // We change this!!!
    if (!isNaN(pt.x) && !isNaN(pt.y)) {
       this.transform('t' + (pt.x - this.data("ox")) + ',' + (pt.y - this.data("oy")) );
};
},

jsfiddle

Upvotes: 0

Related Questions