Snap.svg - drag event handler

泄露秘密 提交于 2020-01-22 13:36:46

问题


Question is about the onstart event handler for Element.drag in the newly announced Snap.svg.

The intention of the code below is to register event handlers for the start and stop of a drag (onstart/onstop) on an svg object.

        var s = Snap(800,600);

        var bigCircle = s.circle(300,150,100);

        bigCircle.drag(null,
                function(){
                    console.log("Move started");
                },
                function(){
                    console.log("Move stopped");
                }
        );

The console messages work fine on drag start and stop, but the null overrides the default onmove function - resulting in no actual drag happening. How do I pass something that says "I don't want to mess with the default onmove"?

(Note: I'd prefer to register an event handler by means of assignment, like the familiar onClick, but that's a different matter.)


Note added after few hours: The Raphael.js documentation and examples provide some clues. At least now I know how to pass in a proper function for onmove that provides the default move behavior:

        var s = Snap(800,600);

        var bigCircle = s.circle(300,150,100);

        start = function() {
            this.ox = parseInt(this.attr("cx"));
            this.oy = parseInt(this.attr("cy"));
            console.log("Start move, ox=" + this.ox + ", oy=" + this.oy);
        }

        move = function(dx, dy) {
            this.attr({"cx": this.ox + dx, "cy": this.oy + dy});
        }

        stop = function() {
            this.ox = parseInt(this.attr("cx"));
            this.oy = parseInt(this.attr("cy"));
            console.log("Stop move, ox=" + this.ox + ", oy=" + this.oy);
        }

        bigCircle.drag(move, start, stop);

回答1:


I'm not sure if I'm misunderstanding what you exactly want...don't you want to implement the drag ?

So for example...

var s = Snap(400,400);
var bigCircle = s.circle(150, 150, 100);

var moveFunc = function (dx, dy, posx, posy) {
    this.attr( { cx: posx , cy: posy } ); // basic drag, you would want to adjust to take care of where you grab etc.
};

bigCircle.drag( moveFunc,
            function(){
                console.log("Move started");
            },
            function(){
                console.log("Move stopped");
            }
    );

JSBin here http://jsbin.com/akoCAkA/1/edit?html,js,output




回答2:


There is an example how to drag with SnapSVG here: http://svg.dabbles.info/snaptut-drag.html

var s = Snap("#svgout");

var rect = s.rect(20,20,40,40);
var circle = s.circle(60,150,50);

var move = function(dx,dy) {
        this.attr({
                    transform: this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [dx, dy]
                });
}

var start = function() {
        this.data('origTransform', this.transform().local );
}
var stop = function() {
        console.log('finished dragging');
}

rect.drag(move, start, stop );
circle.drag(move, start, stop );



回答3:


After struggling for some hours to do this with snap.js, I finally discovered svg.js and its draggable plugin, with which it is so much easier:

var draw = SVG('svg');
var circle = draw.circle(10).attr({cx:30,cy:30,fill:'#f06'});
circle.dragend = function(delta, event) {
    alert(this.attr('cx'))
}
circle.draggable();

So, I switched to svg.js ...




回答4:


The eve.on method wasn't working for me, so I did some poking around and managed to recreate the onmove function. The other two (onstart and onend) require no specific code to work apparently:

var S = Snap(300,300);

var bigCircle = S.circle(150, 150, 100);

bigCircle.drag(onDragMove, onDragStart, onDragEnd);

var ddx = 0;
var ddy = 0;
var dxDone = 0;
var dyDone = 0;

function onDragMove (dx, dy, posx, posy) {
    dx = dx + dxDone;    // dx and dy reset to 0 for some reason when this function begins
    dy = dy + dyDone;    // retain the last move's position as the starting point
    this.attr( { transform: 't'+dx+','+dy } );
    ddx = dx;
    ddy = dy;
    console.log('moving...');
};

function onDragStart(x,y,e) {
    console.log('start!');
};

function onDragEnd(e) {
    dxDone = ddx;
    dyDone = ddy;
    console.log('end!');
};

Please note however that this should only be used for one dragged object at a time. If you need a custom drag for another object, you'll have to rename the functions (ie onDragStart2) and the four variables declared outside of them (ie ddx2) after duplicating it.

Also, the 'transform' string format I passed (tx,y) came from what I found after doing console.log( this.attr('transform') ). I'm not familiar with matrix() just yet, so this way seemed easier.

Hope this helps!




回答5:


I can't drag group elements with custom handlers, s.drag() makes it possible. So i searched further found its possible.

Documentation:

Additionaly following drag events are triggered: drag.start. on start, drag.end. on > end and drag.move. on every move. When element is dragged over another element > drag.over. fires as well.

Solution:

    s.drag();
    eve.on("snap.drag.start." + s.id, function () {
        console.log('cool');
    });

    eve.on("snap.drag.move." + s.id, function () {
        console.log('cooler');
    });

    eve.on("snap.drag.end." + s.id, function () {
        console.log('way cool');
    });

eve is not documented on snapsvg it is available on raphael. i don't know this is proper way or hack.



来源:https://stackoverflow.com/questions/19559349/snap-svg-drag-event-handler

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!