3

我正在尝试调整此示例http://raphaeljs.com/graffle.html以将拖动限制在容器 svg 内。

有点像http://bl.ocks.org/1557377http://jqueryui.com/demos/draggable/#constrain-movement基本上我想限制对象在拖动时从边界框移出。

这是添加到移动功能的调整代码(http://jsfiddle.net/f4mFQ/1/

    if(thisBox.x < 0){
        ddx = 0;
    }else if(thisBox.x>width-thisBox.width ){
        ddx = width-thisBox.width;
    }else {
        ddx = this.ox + dx;
    }

    if(thisBox.y < 0){
        ddy = 0;
    }else if(thisBox.y>height-thisBox.height ){
        ddy = height-thisBox.height;
    }else{
        ddy = this.oy + dy;
    }

这部分有效,当矩形移动超出边界时,它会在边缘跳舞!而圆和椭圆卡在边缘。

那么在这种情况下,如何在父边界框内限制元素拖动并限制移动

4

2 回答 2

4

一个问题是,当您设置ddxddy定位在一侧时,您会将该值作为椭圆的中心点反馈回来,以便它们“捕捉”到一侧。

第二件事是你在这个边界框的左上角进行计算,而不是这个(ox + dx)的实际计算位置。这就是造成混乱的原因。

这不是最漂亮的实现,但我想尽量减少对代码的更改,用这个替换 move 函数:

 move = function (dx, dy) {
    var width =this.paper.width,
    height = this.paper.height,
    thisBox = this.getBBox()
    //, box = {
    //     "x"      :thisBox.width,
    //     "y"      :thisBox.height,
    //     "x2"     :width-thisBox.width,
    //     "y2"     :height-thisBox.height,
    //     "width"  :width-thisBox.width,
    //     "height" :height-thisBox.height
    // };
    // var outOfBound=!Raphael.isBBoxIntersect(thisBox,box)
    ;

    console.log(thisBox.width,width,thisBox.x,thisBox
                ,this.ox);

    var ddx = this.ox + dx;
    var ddy = this.oy + dy;
    if (this.type == 'ellipse') { 
        ddx -= thisBox.width / 2;
        ddy -= thisBox.height / 2;
    }

    if(ddx < 0){
        ddx = 0;
    }else if(ddx>width-thisBox.width ){
        ddx = width-thisBox.width;
    }

    if(ddy < 0){
        ddy = 0;
    }else if(ddy>height-thisBox.height ){
        ddy = height-thisBox.height;
    }

    var att = this.type == "rect" ? {x: ddx, y: ddy} : {cx: ddx + (thisBox.width / 2), cy: ddy + (thisBox.height / 2)};
    this.attr(att);


    for (var i = connections.length; i--;) {
        r.connection(connections[i]);
    }
    r.safari();
} 

在开始时,我们根据 的位置计算ddxddy作为左上角this。(如果是椭圆,则进行调整,如ox中心oy坐标)。

然后它与以前大致相同,尽管当我们将值设置回来时,我们会重新调整椭圆的值。您可以更改存储/使用的值以避免重复计算。

这对我行得通。

编辑

将代码复制到它自己的fiddle中。

于 2013-09-02T11:25:40.323 回答
2

嗨,我已经用这段代码更新了小提琴,这似乎工作虽然不完美,

代码变了

       if (thisBox.x < 0) {
            ddx = 0 + thisBox.width/2;//the position 0 was problem
        } else if (thisBox.x > width - thisBox.width) {
            ddx = width - thisBox.width;
        } else {
            ddx = this.ox +dx;
        }

        if (thisBox.y < 0) {
            ddy = 0+thisBox.height/2;//the position 0 was problem
        } else if (thisBox.y > height - thisBox.height) {
            ddy = height - thisBox.height;
        } else {
            ddy = this.oy + dy;
        }

我已经更新了fiddle

我还更新了一些 CSS 以使其更加清晰和无错误。

更新:振动,

我已经更新fiddle2,消除了顶部和左侧的振动,

请检查并回复

另请参阅此fiddle3可以很好地与圆形/椭圆一起使用,但矩形有问题

于 2013-09-03T07:37:19.533 回答