【问题标题】:Snap.svg - drag event handlerSnap.svg - 拖动事件处理程序
【发布时间】:2013-11-02 18:31:28
【问题描述】:

问题是关于新发布的Snap.svgElement.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);

【问题讨论】:

  • 是的,我遇到了同样的问题,最后到了这里,如果我想附加一个 movestart 处理程序,我必须重新定义 onmove 函数是没有意义的

标签: javascript svg snap.svg


【解决方案1】:

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

比如说……

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

【讨论】:

  • 谢谢,您回答了我的问题,即使我在看到 Rahpael.js 示例后用更新编辑了我的帖子。
  • 嗯,JSBIN 从用户单击的大圆圈上的点开始拖动并不顺畅。它...“卡入”到位(不是双关语)。只是说编写一个优美的移动函数有一些陷阱,作者在编写自己的处理程序时不应该重新发明这个轮子。修复此问题的线程@github.com/adobe-webplatform/Snap.svg/issues/…
【解决方案2】:

这里有一个如何使用 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 );

【讨论】:

  • 简单!...关于“转换”调用如何最终成为“移动”的解释会很好。!!
【解决方案3】:

在使用 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 ...

【讨论】:

  • svgjs 绝对非常简单!
【解决方案4】:

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() 还不熟悉,所以这种方式似乎更容易。

希望这会有所帮助!

【讨论】:

    【解决方案5】:

    我无法使用自定义处理程序拖动组元素,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。

    【讨论】:

    • 另外值得注意的是,全局回调不需要 id
    【解决方案6】:

    试试这个

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多