Snap.svg - 拖动事件处理程序

时间:2013-10-24 07:15:35

标签: javascript svg snap.svg

问题是关于新发布的Element.dragSnap.svg的onstart事件处理程序。

下面代码的目的是为svg对象上的拖动(onstart / onstop)的开始和停止注册事件处理程序。

        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");
                }
        );

控制台消息在拖动开始和停止时工作正常,但是null会覆盖默认的onmove函数 - 导致不会发生实际的拖动。如何传递“我不想弄乱默认情况”的内容?

(注意:我更喜欢通过赋值来注册事件处理程序,比如熟悉的onClick,但这是另一回事。)


注意几小时后添加: Raphael.js文档和示例提供了一些线索。至少现在我知道如何为onmove传递一个适当的函数来提供默认的移动行为:

        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);

6 个答案:

答案 0 :(得分:8)

我不确定我是否误解了你究竟想要的东西......难道你不想实施阻力吗?

所以例如......

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 http://jsbin.com/akoCAkA/1/edit?html,js,output

答案 1 :(得分:7)

这里有一个如何使用SnapSVG进行拖动的示例: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 );

答案 2 :(得分:2)

在使用snap.js挣扎了几个小时后,我终于发现了svg.js及其可拖动的插件,它更容易使用它:

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();

所以,我切换到svg.js ......

答案 3 :(得分:1)

eve.on方法对我来说不起作用,所以我做了一些探索并设法重新创建了onmove函数。另外两个(onstart和onend)显然不需要特定的代码:

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!');
};

但请注意,这只应用于一次拖动一个对象。如果您需要为另一个对象进行自定义拖动,则必须在复制之后重命名函数(即onDragStart2)和在它们之外声明的四个变量(即ddx2)。

此外,'转换'我传递的字符串格式(tx,y)来自我在执行console.log之后发现的内容(this.attr(' transform'))。我还不熟悉matrix(),所以这种方式似乎更容易。

希望这有帮助!

答案 4 :(得分:0)

我无法使用自定义处理程序拖动组元素,s.drag()使其成为可能。所以我进一步搜索发现它可能。

文档:

  

附加拖动事件后触发:drag.start。在开始时,拖动。在>结束并拖动。移动。一举一动。当元素被拖过另一个元素时> drag.over。火也是。

解决方案:

    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未记录在snapsvg上,它可用于raphael。我不知道这是正确的方法还是黑客攻击。

答案 5 :(得分:0)

尝试一下

var paper = Snap("#main"); 

var object  = paper.circle(300,150,100)
object .attr({
  stroke: "#000",
  strokeWidth: 10,
  strokeLinecap:"round"
}); 

var move1 = function(dx,dy, posx, posy) { 
this.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('dragging done');
}

object.drag(move1, start, stop );