Draggable сдерживание использует Box Model для определения границ перетаскиваемых объектов.
сдерживание Тип: селектор или элемент или строка или массив, по умолчанию: false
Ограничивает перетаскивание в пределах указанного элемента или области. Поддерживается несколько типов:
- Селектор: Перетаскиваемый элемент будет помещен в ограничительную рамку первого элемента, найденного селектором. Если ни один элемент не найден, содержание не будет установлено.
- Элемент: Перетаскиваемый элемент будет находиться в ограничительной рамке этого элемента.
- Строка: Возможные значения:
"parent"
, "document"
, "window"
.
- Array: Массив, определяющий ограничивающий прямоугольник в виде
[ x1, y1, x2, y2 ]
.
Ссылка: http://api.jqueryui.com/draggable/
Таким образом, это означает, что вам необходимо создать сложные блоки или встроить обнаружение столкновений в ваш drag
обратный вызов. Когда срабатывает drag
, ему передается объект event
и ui
. ui.position
можно манипулировать:
Текущее положение CSS помощника как { top, left }
объекта. Значения могут быть изменены для изменения места расположения элемента. Это полезно для пользовательской локализации, привязки и т. Д.
Это может быть сложно, поэтому, если это начальный проект или что-то маленькое, рассмотрите возможность использования плагина Collision: jQuery Перетаскивание с обнаружением столкновения
Рассмотрим следующий примитивный пример.
$(function() {
function log(obj) {
var str = "T: " + obj.top + " L:, " + obj.left + ", R: " + obj.right + ", B: " + obj.bottom;
$("#log").html(str);
}
function getObjectPos(obj) {
var oPos = obj.position();
oPos.right = oPos.left + obj.width();
oPos.bottom = oPos.top + obj.height();
return oPos;
}
function collision(a, b) {
var col = false;
var side;
var r1 = getObjectPos(a);
var r2 = getObjectPos(b);
/*
https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection
rect1.x < rect2.x + rect2.width && rect1.x + rect1.width > rect2.x && rect1.y < rect2.y + rect2.height && rect1.y + rect1.height > rect2.y
*/
if (r1.left < r2.right && r1.right > r2.left && r1.top < r2.bottom && r1.bottom > r2.top) {
col = true;
}
return {
col: col,
right: r1.right > r2.left,
left: r1.left > r2.right,
bottom: r1.bottom > r2.bottom,
top: r1.top > r2.top
};
}
$("#draggable").draggable({
containment: "#containment-wrapper",
start: function(e, ui) {
ui.helper.data("prev-pos", getObjectPos(ui.helper));
},
drag: function(e, ui) {
var oPrevPos = ui.helper.data("prev-pos");
var oPos = getObjectPos(ui.helper);
console.log(oPrevPos, oPos);
log(oPos);
$("#containment-wrapper .no-drag").each(function(ind, el) {
var c = collision(ui.helper, $(el));
var col = c.col;
var side;
if (col) {
switch (true) {
case c.top:
side = "top";
break;
case c.left:
side = "left";
break;
case c.bottom:
side = "bottom";
break;
case c.right:
side = "right";
break;
}
console.log("Collision: " + col, side, c);
switch (side) {
case "left":
case "right":
ui.position.left = oPrevPos.left
break;
case "top":
case "bottom":
ui.position.top = oPrevPos.top
break;
}
} else {
console.log("Collision: " + c.col, c);
ui.helper.data("prev-pos", oPos);
}
});
}
});
});
.draggable {
width: 100px;
height: 100px;
float: left;
margin: 0;
padding: 0;
background: #CCC;
}
#containment-wrapper {
width: 400px;
height: 250px;
border: 2px solid #ccc;
padding: 10px;
position: relative;
}
#containment-wrapper .no-drag {
width: 100px;
height: 100px;
border: 2px solid #ccc;
top: 168px;
left: 318px;
position: absolute;
}
.output {
margin-top: -2em;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id="containment-wrapper">
<div id="draggable" class="draggable">
</div>
<div class="no-drag">
</div>
</div>
<div id="log" class="output"></div>
Это очень простой пример использования 2D Collision Detection. Это не здорово и может использовать улучшения, но вы можете увидеть, с чего начать.
Надеюсь, это поможет.