13

问题是关于新发布的Snap.svg中Element.drag的 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 函数 - 导致没有实际拖动发生。如何传递“我不想弄乱默认的 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);
4

6 回答 6

9

我不确定我是否误解了你到底想要什么......你不想实现拖动吗?

所以例如...

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

于 2013-10-24T09:34:32.297 回答
8

这里有一个如何使用 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 );
于 2014-12-03T07:29:03.523 回答
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 ...

于 2013-12-26T17:30:50.300 回答
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() ,所以这种方式似乎更容易。

希望这可以帮助!

于 2014-01-10T15:36:50.960 回答
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 上可用。我不知道这是正确的方法还是hack。

于 2013-12-03T19:33:49.493 回答
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 ); 
于 2020-12-03T09:21:03.190 回答