web-dev-qa-db-ja.com

jQueryをドラッグ可能にして特定のグリッドにスナップさせる

注:同様の質問をした人もいますが、具体的すぎて使用可能な回答が得られませんでした

jQuery UIのドラッグ可能なウィジェットには、グリッドにスナップするためのオプションがありますが、グリッドの相対的な位置を設定する方法はありません。

たとえば、ドロップターゲットに明確に定義された20x20グリッドがあります。ドロップターゲット内で0,0から始まるドラッグアイテムは、グリッドに対応してスナップします。ただし、別の場所またはドロップターゲットの外側で開始するドラッグアイテムは、そのグリッドと整列しません。

enter image description here

http://jsfiddle.net/FNhFX/5/

HTML:

<div class="drop-target">
    <div class="drag-item">Drag me</div>
    <div class="drag-item" style="left:87px;top:87px;">Drag me</div>
</div>
<div class="outside-drag-item">Drag me</div>

JS:

$(function() {
    $(".drag-item").draggable({
        grid: [20, 20]
    });
    $(".outside-drag-item").draggable({
        grid: [20, 20],
        helper:"clone"
    });
    $(".drop-target").droppable({
        accept: ".drag-item"
    });
});

JQueryドラッグ可能を使用して特定のグリッドにスナップする任意の方法はありますか?

13
Yarin

あなたが尋ねたフォローアップの質問 経由でここに来ましたが、私も先に進んでここに回答を投稿します。

ドラッグ可能なjQueryUIのdragイベント内で、独自のグリッドへのスナップ機能を非常に簡単に作成できます。

基本的に、ドラッグ可能なオブジェクトがグリッドにドラッグされている任意の時点で、現在のUI位置がどれだけ近いかを確認する必要があります。その近接度は、グリッドで割った余りとして常に表すことができます。その余りがsnapTolerance以下の場合は、その余りがない場合の位置に設定します。

それは散文で言うのは奇妙でした。コードでは、より明確になっているはずです。

ライブデモ

// Custom grid
$('#box-3').draggable({
    drag: function( event, ui ) {
        var snapTolerance = $(this).draggable('option', 'snapTolerance');
        var topRemainder = ui.position.top % 20;
        var leftRemainder = ui.position.left % 20;

        if (topRemainder <= snapTolerance) {
            ui.position.top = ui.position.top - topRemainder;
        }

        if (leftRemainder <= snapTolerance) {
            ui.position.left = ui.position.left - leftRemainder;
        }
    }  
});
19
Nate

JQuery UIでgridオプションを使用する代わりに、独自のグリッド(cssを使用して表示または非表示にすることができます)を作成しました。次に、snapオプションを使用して、各グリッド線のクラスを指定します。

元のjsfiddleに、次のcssを追加しました。

.gridlines {
display: none;
position:absolute;
background-color:#ccc;
}

および次のJavaScript:

function createGrid(size) {
  var i,
  sel = $('.drop-target'),
      height = sel.height(),
      width = sel.width(),
      ratioW = Math.floor(width / size),
      ratioH = Math.floor(height / size);

  for (i = 0; i <= ratioW; i++) { // vertical grid lines
    $('<div />').css({
        'top': 0,
        'left': i * size,
        'width': 1,
        'height': height
    })
      .addClass('gridlines')
      .appendTo(sel);
  }

  for (i = 0; i <= ratioH; i++) { // horizontal grid lines
    $('<div />').css({
        'top': i * size,
        'left': 0,
        'width': width,
        'height': 1
    })
      .addClass('gridlines')
      .appendTo(sel);
    }

  $('.gridlines').show();
}

createGrid(20);

これがjsFiddleです( http://jsfiddle.net/madstop/46sqd/2/

5
madstop