raphaeljs:拖动并将转换应用于Paper.set()

时间:2012-06-23 17:44:15

标签: raphael

我开始尝试使用raphaeljs,但是在拖动并将转换应用到Paper.set()时遇到了一个小问题

以下是我的示例:http://jsfiddle.net/PQZmp/2/

1)为什么拖动事件仅添加到marker而不是slider

2)转换应该是相对的(即translate by而不是translate to),但是如果我拖动marker两次,则第二次拖动从头开始而不是从第一个结束。

修改: 在Zero的响应之后,我创建了一个新的JSFiddle示例:http://jsfiddle.net/9b9W3/1/

1)如果this引用set而不是集合的第一个元素,那将会很酷。这不能用dragger.apply(slider)完成吗?我试过了,但只适用于方法的第一次执行(也许在Raphael内部,它已经完成但是set中的第一个元素而不是set

2)根据Raphael docs,转换应该相对于对象位置(即translate by而不是translate to)。但根据上面的jsfiddle,它不是正在发生的事情(检查两个标记拖动事件)。

3)因此上面的2)会产生第三个问题。如果transform("t30,0")translation by 30px horizontally,原点是如何计算的?基于attr("x")getBBox().x

2 个答案:

答案 0 :(得分:4)

拖动事件实际上被添加到标记和滑块 - 但是你的滑块的笔触宽度为1并且没有填充,所以除非你捕到精确的边框,否则点击“落到”画布

这背后是另一个问题:拖动被应用于两个元素,但是拖动处理程序中的this引用了一个特定元素,该集合 - 因此两个元素都会拖动彼此独立。

最后:每个拖动从初始位置开始的原因是因为dragger中的dx,dy参数相对于初始拖动事件的坐标,并且您的转换不会将先前的转换考虑在内。考虑这样的替代方案:

var r = new Raphael(0, 0, 400, 200);
var marker = r.path("M10,0L10,100").attr({"stroke-width": 5});
var button = r.rect(0, 0, 20, 20, 1).attr( { 'stroke-width': 2, fill: 'white' } );
var slider = r.set( marker, button );

var startx, starty;

var startDrag = function(){
    var bbox = slider.getBBox();
    startx = bbox.x;
    starty = bbox.y;
    console.log(this);
}, dragger = function(dx, dy){
    slider.transform("t" + ( startx + dx ) + "," + starty );
}, endDrag = function(){

};

slider.drag(dragger, startDrag, endDrag);

要解决您的更新:

  1. 我相信你可以指定执行拖动功能的上下文作为element.drag的可选第四,第五和第六个参数。我自己没试过,但看起来这应该很有效:

    slider.drag(dragger,startDrag,endDrag,slider,slider,slider);

  2. 转换是相对于对象位置的。这适用于第一个滑块,因为它的起始位置为0,但对于第二个滑块不太好,因为......

  3. ...最小/最大滑块的转换实际上应该与比例相关,而不是单个标记。因此,您会注意到,当您将鼠标光标拖回零位置时,您的最大滑块(红色滑块)将返回其初始位置。有道理吗?

答案 1 :(得分:0)

    var position;
    var rect = paper.rect(20, 20, 40, 40).attr({
            cursor: "move",
            fill: "#f00",
            stroke: "#000"
    });
    t = paper.text(70,70, 'test').attr({
            "font-size":16, 
            "font-family": 
            "Arial, Helvetica, sans-serif" 
    });
    var st = paper.set();
    st.push(rect, t);
    rect.mySet = st;
    rect.drag(onMove, onStart, onEnd);
    onStart = function () {
        positions = new Array();
        this.mySet.forEach(function(e) {
            var ox = e.attr("x");
            var oy = e.attr("y");
            positions.push([e, ox, oy]);
        });
    }
    onMove = function (dx, dy) {
        for (var i = 0; i < positions.length; i++) {//you can use foreach but I want to
             // show that is a simple array
            positions[i][0].attr({x: positions[i][1] + dx, y: positions[i][2] + dy});
        }
    }
    onEnd = function() {}