detecting "collision" between 2 divs javascript

I want to detect a collision between two divs and I’ve tried to do that using the offsetLeft and offsetTop of each one of the divs and by using getBoundingClientRect(). but none of these work

Is there a way I can get the exact coordinates in which these two elements touch?

How can I do this?

codepen -> https://codepen.io/mullerz/pen/vYNjXWQ

<button type="button">Start Game</button>
    <div class="big">
        <div class="blue"></div>
        <div class="red"></div>
    </div>
.big{
        width:400px;
        height:400px;
        outline : 1px solid red;
        margin: 0 auto;
        position: relative;
    }

    .blue{
        width:20px;
        height:20px;
        background:blue;
        position:absolute;
    }
    .red{
        width:20px;
        height:20px;
        background:red;
        position:absolute;
    }
const bigDiv = document.querySelector(".big")
        const blue = document.querySelector(".blue")
        const startBtn = document.querySelector("button")
        const red = document.querySelector(".red")
        const bigDivDimensions = bigDiv.getBoundingClientRect();
        let speed = 5;
        //let counter = 0;


        let bigDivLeft = bigDivDimensions.left;

        startGame();
function random(){return Math.floor(Math.random()*(bigDivDimensions.width-40));}

function startGame(){
    //let randomSnake = Math.floor(Math.random()*(bigDivDimensions.width-40));
    //let randomApple = Math.ceil(Math.random()*(bigDivDimensions.width -40));
    blue.style.left = random() + "px"
    blue.style.top = random() + "px"
    red.style.left = random()+ "px"
    red.style.top = random() + "px"
    }

function move(e){
    let blueX = blue.offsetLeft;
    let blueY = blue.offsetTop;
    let key = e.keyCode;

    if(key !== 37 && key !== 38 && key !== 39 && key !== 40 ){return}   
    else if(key === 37 && blueX > 3){ blueX -= speed; }
    else if(key === 38 && blueY > 3){ blueY -= speed; }
    else if(key === 39 &&  blueX < (bigDivDimensions.width - 25) ){ blueX  += speed; }  
    else if(key === 40 && blueY < (bigDivDimensions.height -23)){ blueY += speed; }

    blue.style.left = blueX + "px";
    blue.style.top = blueY + "px";
    colision(blueX, blueY)
}

function colision(blueX,blueY){
    /* let redX = red.offsetLeft;
       let redY = red.offsetTop; 
       if(redY === blueY || redX == blueX){console.log("hit")}  */

       let redRect = red.getBoundingClientRect();
       let blueRect = blue.getBoundingClientRect();

      if((redRect.top < blueRect.bottom) ||(redRect.bottom < blueRect.top) || (redRect.right > blueRect.left) || (redRect.left < blueRect.right)){
        console.log("hit")
      } 
}

startBtn.addEventListener("click", startGame)
document.addEventListener("keydown", move)

6 thoughts on “detecting "collision" between 2 divs javascript”

  1. Two rectangles do collide when their

    horizontal side and vertical side

    overlap.

    Consider the following answer: Checking for range overlap

    // l1 (line 1) --> [x1, x2]
    // l2 (line 2) --> [x1, x2]
    function checkOverlap(l1, l2) {
      return ((l1[1] - l2[0]) > 0 && (l2[1] - l1[0]) > 0) ? true : false;
    }
    

    Check collision with range overlap for the x-side and y-side:

    // Rectangle a --> [[x1, x2], [y1, y2]]
    // Rectangle b --> [[x1, x2], [y1, y2]]
    function collide(a, b) {
      return (checkOverlap(a[0], b[0]) && checkOverlap(a[1], b[1]));
    }
    

    Spoiler

    SVG-Example

    var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
    var width = 200;
    var height = 200;
    svg.setAttribute("width", width);
    svg.setAttribute("height", height);
    document.body.appendChild(svg);
    
    function createRect(svg, width, height, x, y, style, id) {
      var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
      rect.setAttribute("width", width);
      rect.setAttribute("height", height);
      rect.setAttribute("x", x);
      rect.setAttribute("y", y);
      rect.setAttribute("style", style);
      rect.setAttribute("id", id);
      svg.appendChild(rect);
    }
    
    function createSquare(svg, side, x, y, style, id) {
      createRect(svg, side, side, x, y, style, id);
    }
    
    function getRandomNumber(a, b) {
      return Math.round(Math.random() * (b - a)) + a;
    }
    
    function createRandomSquare(svg, xRange, yRange, side, style, id) {
      var x = getRandomNumber(xRange[0], xRange[1]);
      var y = getRandomNumber(yRange[0], yRange[1]);
      createSquare(svg, side, x, y, style, id);
      return [
        [x, x + side],
        [y, y + side]
      ];
    }
    
    function checkOverlap(l1, l2) {
      return ((l1[1] - l2[0]) > 0 && (l2[1] - l1[0]) > 0) ? true : false;
    }
    
    // [[x1, x2], [y1, y2]]
    function collide(a, b) {
      return (checkOverlap(a[0], b[0]) && checkOverlap(a[1], b[1]));
    }
    
    function getCoordinates(arr) {
      return {
        "top-left": [arr[0][0], arr[1][0]],
        "top-right": [arr[0][1], arr[1][0]],
        "bottom-right": [arr[0][1], arr[1][1]],
        "bottom-left": [arr[0][0], arr[1][1]]
      }
    }
    
    function run() {
      var bs = document.getElementById("blueSquare");
      var rs = document.getElementById("redSquare");
      if (bs !== null && rs !== null) {
        var parent = bs.parentNode;
        parent.removeChild(bs);
        parent.removeChild(rs);
      }
    
      var side = 30;
      var blueSquare = createRandomSquare(svg, [0, (width - side)], [0, (height - side)], side, "fill:blue", "blueSquare");
      var redSquare = createRandomSquare(svg, [0, (width - side)], [0, (height - side)], side, "fill:red", "redSquare");
      console.log("Collision? " + collide(blueSquare, redSquare));
      console.log("Blue square: ",
        getCoordinates(blueSquare));
      console.log("Red square: ", getCoordinates(redSquare));
    }
    
    var button = document.createElement("button");
    button.setAttribute("id", "button");
    button.textContent = "Run";
    button.addEventListener("click", run);
    document.body.appendChild(button);
    svg {
      border: 1px solid;
    }
    Reply

Leave a Comment