如何检测两个div是否正在接触/碰撞检测



我已经在谷歌和这里搜索了这个,但没有找到适合我问题的答案

(这是一个非常简化的解释) 我有两个div 可以由用户移动(使用 JavaScript 和点击事件)我需要检测两个div 是否相互接触/重叠,以及它们是否要触发一个函数我在这里看到了答案,但它们都使用 jQuery,我想使用纯 JS

可能有用的一点是,两个div 都有位置绝对值和在 css 中设置的不同 z 索引

编辑:为了澄清问题,因为我的解释很差,两个div中的一个是静止的,第二个只能在Y方向上移动,但是在Y方向上移动的div使用案例动画旋转

可能有更好的方法(这不是很干),但它应该有效,只需将"div1"和"div2"替换为您的div ID:

let div1 = document.getElementById('div1').getBoundingClientRect();
let div1Top = div1.top;
let div1Left = div1.left;
let div1Right = div1.right
let div1Bottom = div1.bottom
let div2 = document.getElementById('div2').getBoundingClientRect();
let div2Top = div1.top;
let div2Left = div1.left;
let div2Right = div1.right
let div2Bottom = div1.bottom
if ((div2Top > div1Top && div2Top < div1Bottom)||(div2Bottom > div1Top && div2Bottom < div1Bottom)) {
let verticalMatch = true
} else{
let verticalMatch = false
}
if ((div2Right > div1Left && div2Right < div1Right)||(div2Left < div1Right && div2Left > div1Left)) {
let horizontalMatch = true
} else {
let horizontalMatch = false
}
if (horizontalMatch && vertialMatch){
let intersect = true
} else {
let intersect = false
}

这类似于当前的正确答案,但我为解决这个问题所做的工作如下。

let div1 = document.getElementById('div1').getBoundingClientRect();
let div2 = document.getElementById('div2').getBoundingClientRect();
function touching(d1,d2){
let ox = Math.abs(d1.x - d2.x) < (d1.x < d2.x ? d2.width : d1.width);
let oy = Math.abs(d1.y - d2.y) < (d1.y < d2.y ? d2.height : d1.height);
return ox && oy;
}
var t = touching(div1,div2) // should return whether they are touching

请注意,此函数不能很好地处理转换。

试试 Element.getBoundingClientRect() 在两个div及其坐标上,您可以进行碰撞检测

您可以使用Anand Thangappan在这篇文章中描述的过程来获取元素的计算位置。然后,您可以使用getComputedStyle()(此处的文档)获取计算出的宽度和高度,并使用简单的不等式检查来测试它们是否相交。

编辑:或者,您可以直接读取它们的位置值,因为您使用的是绝对位置。然后,您可以跳过获取元素计算位置的更复杂的方法。

由于您允许用户移动 DIV,并且它们都是绝对的,因此您必须有权访问 DIV 的 STYLE 属性。

获取顶部、左侧、宽度和高度属性。

计算底部和右侧属性。现在,您拥有所有四个角坐标。

由于它们都是矩形,因此您可以检查dev A的顶部或底部是否在div B的顶部和底部之间,以及左侧或右侧是否在dev B的左侧和右侧之间。

这样做的一个好处是,您只需要检查 A -> B,因为在两个测试中都会检测到任何重叠。

这是有效的,因为形状的直线性质。如果这些是三角形或五边形,或者如果它们不是凸形,则会更加复杂。

值得注意的是,如果你使用的是CSS/JS动画,如果你有物体高速移动,你可能希望扩大"碰撞区域"。否则,项目可能会在两次检查之间通过。

最新更新