gpt4 book ai didi

javascript - JQuery Draggable - 防止网格对象进入同一位置

转载 作者:行者123 更新时间:2023-11-29 19:15:20 26 4
gpt4 key购买 nike

我正在使用 JQuery Draggable 在网格中移动项目。对象捕捉到 32x32 网格区域。如果对象处于同一位置,我希望能够取消网格捕捉。

拖动无法取消,必须阻止它进入正方形。在它被阻止并移回之前的位置后,如果用户继续拖动到一个新的未占用的网格位置,它必须捕捉到那个位置。

我已经创建了一个用于上述目的的演示,但是图像在尝试进入新位置时出现故障,但随后又被取消回到旧位置。

https://jsfiddle.net/dtx7my4e/1/

这是 fiddle 中的代码:

HTML:

   <div class="drop-target">
<div class="drag-item" object-id="0"></div>
<div class="drag-item" style="left: 32px;" object-id="1"></div>
</div>

Javascript:

var objects = [
[0, 0],
[1, 1]
];

$(function() {
$(".drag-item").draggable({
grid: [ 32, 32 ],
containment: '.drop-target',
drag: function (event, obj){
let objectId = $(this).attr('object-id');

var objectPositionX = $(this).position().left / 32;
var objectPositionY = $(this).position().top / 32;

var previousPositionX = Math.floor(objects[objectId][0]);
var previousPositionY = Math.floor(objects[objectId][1]);

if (objectPositionX != previousPositionX || objectPositionY != previousPositionY) {
if(!isObjectInPosition(objects, [objectPositionX, objectPositionY])) {
objects[objectId] = [objectPositionX, objectPositionY];
} else {
obj.position.left = previousPositionX * 32;
obj.position.top = previousPositionY * 32;
}
}
}
});
});


function isObjectInPosition(arrayToSearch, positionToFind)
{
for (let i = 0; i < arrayToSearch.length; i++) {
if (arrayToSearch[i][0] == positionToFind[0]
&& arrayToSearch[i][1] == positionToFind[1]) {
return true;
}
}
return false;
}

CSS:

.drag-item {
background-image: url("http://i.imgur.com/lBIWrWw.png");
background-size: 32px auto;
width: 32px;
height: 32px;
cursor: move;
}

.drop-target {
background: whitesmoke url("http://i.imgur.com/uUvTRLx.png") repeat scroll 0 0 / 32px 32px;
border: 1px dashed orange;
height: 736px;
left: 0;
position: absolute;
top: 0;
width: 736px;
}

谢谢,非常感谢任何帮助。

托比。

最佳答案

如果您愿意修改 draggable 本身,我认为这会使逻辑更易于应用。一旦拖动事件被触发,您可以做很多事情,但如果您修改 draggable 的 _generatePosition 方法,您将拥有更多的控制权。一开始它可能看起来更复杂,但对于这种行为,有时更容易工作。

基本上,您可以在应用网格和包含检查后运行您的 isInPosition 函数。通常下一步是设置新位置,但如果您的 isInPosition 返回 true,您将阻止拖动。像这样:

'use strict'
// This is the function generating the position by calculating
// mouse position, different offsets and option.

$.ui.draggable.prototype._generatePosition = function(event, constrainPosition) {
var containment, co, top, left,
o = this.options,
scrollIsRootNode = this._isRootNode(this.scrollParent[0]),
pageX = event.pageX,
pageY = event.pageY;

// Cache the scroll
if (!scrollIsRootNode || !this.offset.scroll) {
this.offset.scroll = {
top: this.scrollParent.scrollTop(),
left: this.scrollParent.scrollLeft()
};
}

/*
* - Position constraining -
* Constrain the position to a mix of grid, containment.
*/

// If we are not dragging yet, we won't check for options
if (constrainPosition) {

if (this.containment) {
if (this.relativeContainer) {
co = this.relativeContainer.offset();
containment = [
this.containment[0] + co.left,
this.containment[1] + co.top,
this.containment[2] + co.left,
this.containment[3] + co.top
];
} else {
containment = this.containment;
}

if (event.pageX - this.offset.click.left < containment[0]) {
pageX = containment[0] + this.offset.click.left;
}
if (event.pageY - this.offset.click.top < containment[1]) {
pageY = containment[1] + this.offset.click.top;
}
if (event.pageX - this.offset.click.left > containment[2]) {
pageX = containment[2] + this.offset.click.left;
}
if (event.pageY - this.offset.click.top > containment[3]) {
pageY = containment[3] + this.offset.click.top;
}
}

if (o.grid) {

//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;

left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
}

if (o.axis === "y") {
pageX = this.originalPageX;
}

if (o.axis === "x") {
pageY = this.originalPageY;
}
}

// This is the only part added to the original function.
// You have access to the updated position after it's been
// updated through containment and grid, but before the
// element is modified.
// If there's an object in position, you prevent dragging.

if (isObjectInPosition(objects, [pageX - this.offset.click.left - this.offset.parent.left, pageY - this.offset.click.top - this.offset.parent.top])) {
return false;

}

return {
top: (
pageY - // The absolute mouse position
this.offset.click.top - // Click offset (relative to the element)
this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent
this.offset.parent.top + // The offsetParent's offset without borders (offset + border)
(this.cssPosition === "fixed" ? -this.offset.scroll.top : (scrollIsRootNode ? 0 : this.offset.scroll.top))
),
left: (
pageX - // The absolute mouse position
this.offset.click.left - // Click offset (relative to the element)
this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent
this.offset.parent.left + // The offsetParent's offset without borders (offset + border)
(this.cssPosition === "fixed" ? -this.offset.scroll.left : (scrollIsRootNode ? 0 : this.offset.scroll.left))
)
};

}

var objects = [
[0, 0],
[1, 1]
];

$(function() {
$(".drag-item").draggable({
grid: [32, 32],
containment: '.drop-target',
// on start you remove coordinate of dragged item
// else it'll check its own coordinates
start: function(event, obj) {
var objectId = $(this).attr('object-id');
objects[objectId] = [null, null];
},
// on stop you update your array
stop: function(event, obj) {
var objectId = $(this).attr('object-id');
var objectPositionX = $(this).position().left / 32;
var objectPositionY = $(this).position().top / 32;
objects[objectId] = [objectPositionX, objectPositionY];

}
});
});


function isObjectInPosition(arrayToSearch, positionToFind) {

for (let i = 0; i < arrayToSearch.length; i++) {
if (arrayToSearch[i][0] === (positionToFind[0] / 32) && arrayToSearch[i][1] === (positionToFind[1] / 32)) {

return true;
}
}
return false;
}

https://jsfiddle.net/bfc4tsrh/1/

关于javascript - JQuery Draggable - 防止网格对象进入同一位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35820338/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com