简体   繁体   English

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

[英]How to detect if two divs are touching/ collision detection

I have searched all over Google and here for this but haven't found an answer that suits my problem我已经在谷歌和这里搜索了这个,但没有找到适合我的问题的答案

(This is a really simplified explanation) I have two divs which can be moved by the user (using JavaScript and click events) I need to detect if the two divs are touching/on top of each other and if they are to trigger a function I have seen answers on here but they all use jQuery and I want to use pure JS (这是一个非常简单的解释)我有两个可以由用户移动的 div(使用 JavaScript 和点击事件)我需要检测这两个 div 是否相互接触/重叠,以及它们是否要触发一个功能我在这里看到了答案,但他们都使用 jQuery,我想使用纯 JS

Something that might be useful is that both divs have position absolute and different z-indexes set in css可能有用的是,两个 div 都在 css 中设置了绝对位置和不同的 z 索引

EDIT: to clear things up since my explanation was very poor one of the two divs is stationary and the second can only move in the Y direction but the div that moves in the Y direction is rotating using a case animation编辑:澄清一下,因为我的解释很差,两个 div 中的一个是静止的,第二个只能在 Y 方向上移动,但在 Y 方向上移动的 div 正在使用案例动画旋转

There's probably a better way (this isnt very DRY) but it should work, simply replace "div1" and "div2" with your div IDs:可能有更好的方法(这不是很干)但它应该可以工作,只需用您的 div ID 替换“div1”和“div2”:

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
}

在两个 div 上尝试Element.getBoundingClientRect()并使用它们的坐标进行碰撞检测

This is similar to the current correct answer but what I did to solve this problem follows.这类似于当前的正确答案,但我为解决此问题所做的工作如下。

let d1 = document.getElementById('div1').getBoundingClientRect();
let d2 = document.getElementById('div2').getBoundingClientRect();

function touching(div1,div2){
    let ox = Math.abs(d1.x - d2.x) < (d1.x < d2.x ? d2.width : d1.width);
    let ox = Math.abs(d1.y - d2.y) < (d1.y < d2.y ? d2.height : d1.height);
    return ox && oy;
}

var t = touching(d1,d2) // should return whether they are touching

Note that this function will not work with transformations very well.请注意,此函数不适用于转换。

You could use the process described in this post by Anand Thangappan to get the computed location of the element.您可以使用 Anand Thangappan 在这篇文章中描述的过程来获取元素的计算位置。 You could then get the computed width and height using getComputedStyle() ( documentation here ), and test if they intersect using simple inequality checks.然后,您可以使用 getComputedStyle()( 此处的文档)获取计算的宽度和高度,并使用简单的不等式检查测试它们是否相交。

EDIT: Alternatively, you can just read their location values directly, since you're using absolute position.编辑:或者,您可以直接读取它们的位置值,因为您使用的是绝对位置。 Then you can skip the more complicated way of getting the computed location of the element.然后你可以跳过更复杂的获取元素计算位置的方法。

Since you are allowing the user to move the DIVs and they're both absolute, you must have access to the STYLE attributes of the DIVs.由于您允许用户移动 DIV 并且它们都是绝对的,因此您必须有权访问 DIV 的 STYLE 属性。

Get the the top, left, width and height properties.获取顶部、左侧、宽度和高度属性。

Calculate the bottom and right properties.计算底部和右侧的属性。 Now you have all four corner coordinates.现在您拥有所有四个角坐标。

Since they're both rectangles, you can check to see if the top or bottom of dev A is between the top and bottom of div B AND if the left or right is between the left and right of dev B.由于它们都是矩形,因此您可以检查 dev A 的顶部或底部是否在 div B 的顶部和底部之间,以及左侧或右侧是否在 dev B 的左侧和右侧之间。

The one good part about this is that you only have to check A -> B because any overlap would be detected in both tests.关于这一点的一个好处是,您只需检查 A -> B,因为在两个测试中都会检测到任何重叠。

This works because of the rectilinear nature of the shapes.这是因为形状的直线性。 It would be more complicated if these were triangles or pentagons, or if they were not convex shapes.如果这些是三角形或五边形,或者不是凸形,情况会更加复杂。

It's worth noting that if you're using CSS / JS animation, you may wish to enlarge the 'collision area' if you have objects moving at high speed.值得注意的是,如果您正在使用 CSS/JS 动画,如果您有物体高速移动,您可能希望扩大“碰撞区域”。 Otherwise, items might go through between checks.否则,项目可能会在两次检查之间通过。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM