2

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

Something that might be useful is that both divs have position absolute and different z-indexes set in css

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

kriskotoo BG
  • 313
  • 5
  • 16
  • 1
    Well, then you have all coordinates and sizes of both boxes, you have just 4 inequalities to check, right? I mean, these are just two rectangles in Cartesian coordinates. – Frax May 16 '18 at 19:53
  • @NiVeR it's not a duplicate of post 5419134 since they asked for a solution with jQuery and I'm asking for a solution without jQuery – kriskotoo BG May 16 '18 at 20:02

5 Answers5

3

There's probably a better way (this isnt very DRY) but it should work, simply replace "div1" and "div2" with your div IDs:

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
}
Cory Baker
  • 167
  • 1
  • 13
2

This is similar to the current correct answer but what I did to solve this problem follows.

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

Note that this function will not work with transformations very well.

1

try Element.getBoundingClientRect() on both divs and with their coordinates you can do collision detection

chrystian
  • 831
  • 7
  • 15
0

You could use the process described in this post by Anand Thangappan to get the computed location of the element. You could then get the computed width and height using getComputedStyle() (documentation here), and test if they intersect using simple inequality checks.

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.

Thomas Cohn
  • 462
  • 3
  • 12
0

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.

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.

The one good part about this is that you only have to check A -> B because any overlap would be detected in both tests.

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. Otherwise, items might go through between checks.

Sean Munson
  • 343
  • 2
  • 9