3

この例http://raphaeljs.com/graffle.htmlを微調整して、ドラッグをコンテナsvg内に制限しようとしています。

http://bl.ocks.org/1557377http://jqueryui.com/demos/draggable/#constrain-movementのように基本的に、ドラッグ中にバウンディングボックスからオブジェクトが移動するのを制限したいと思います。

これがmove関数に追加された微調整されたコードです(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;
    }

これは部分的に機能します。長方形が境界を越えて移動すると、エッジで踊ります。円と楕円が端にくっついている間。

したがって、この場合はsvgの場合、親バウンディングボックス内の制限された動きで要素のドラッグを制限する方法

4

2 に答える 2

4

1 つの問題は、横に設定ddxまたはddy配置するときに、その値を楕円の中心点としてフィードバックして、横に「スナップ」することです。

2 つ目は、これの実際に計算された位置 (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();
} 

ddx最初に、 の位置に基づいてとddyを左上として計算し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 に答える