Search code examples
javascripthtmljquerycssoverlapping

How to check if two round divs are overlapping


This is my codepen. I want to check if the divs are overlapping each other with jQuery. I wrote a code for that but it doesn't work with round boxes. it only works with squares and rectangles. how can I make it work with round divs?

const coordinates = (className) => {
  const val = document.querySelector(className);
  
  return {
      y: val.offsetTop,
      x: val.offsetLeft,
      yh: val.offsetTop + val.offsetHeight,
      xw: val.offsetLeft + val.offsetWidth,
  }
}

const cm = coordinates(".circle.small");
const cl = coordinates(".circle.large");

const offset_x = cm.x < cl.x && cm.xw > cl.x;
const offset_xw = cm.x < cl.xw && cm.xw > cl.xw;
const offset_cx = cm.x < cl.xw && cm.xw < cl.xw;
const offset_cy = cm.y < cl.yh && cm.yh < cl.yh;
const offset_y = cm.y < cl.y && cm.yh > cl.y;
const offset_yh = cm.y < cl.yh && cm.yh > cl.yh;

const is_x = offset_x || offset_xw || offset_cx;
const is_y = offset_y || offset_yh || offset_cy;

console.log(is_x, is_y);
.circle {
  width: var(--square);
  height: var(--square);
  background: var(--bg);
  border-radius: 50%;
}

.parent {
  margin-left: 5px;
}

.parent2 {
  margin-left: 15px;
}

.small {
  --square: 50px;
  --bg: red;
  margin-bottom: -5px;
}

.large {
  --square: 100px;
  --bg: green;
}
<div class="parent">
  <div class="circle small"></div>
</div>
<div class="parent2">
  <div class="circle large"></div>
</div>


Solution

  • Your logic to calculate the delta between circle positions isn't quite right. You need to get the X and Y from the centre of each circle, then work out if the hypotenuse calculated from those two points is less than half of the combined radii.

    Here's a working example. Note that I only added jQuery/jQueryUI to make dragging the circles around easier for testing - neither of these libraries are required for production use.

    let $label = $('.overlap-label span');
    
    const hasOverlap = (x0, y0, r0, x1, y1, r1) => Math.hypot(x0 - x1, y0 - y1) <= r0 + r1;
    const coordinates = (className) => {
      const el = document.querySelector(className);
      const rect = el.getBoundingClientRect();
      const radius = el.offsetHeight / 2;
      return {
        y: rect.top + radius,
        x: rect.left + radius,
        r: radius
      }
    }
    const checkForOverlap = () => {
      const cm = coordinates(".circle.small");
      const cl = coordinates(".circle.large");
      $label.text(hasOverlap(cm.x, cm.y, cm.r, cl.x, cl.y, cl.r));
    }
    
    $('.parent').draggable().on('drag', checkForOverlap);
    .circle {
      width: var(--square);
      height: var(--square);
      background: var(--bg);
      border-radius: 50%;
      display: inline-block;
    }
    
    .parent {
      display: inline-block;
    }
    
    .small {
      --square: 50px;
      --bg: red;
    }
    
    .large {
      --square: 100px;
      --bg: green;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/themes/base/jquery-ui.min.css" />
    
    <div class="overlap-label">Circles are overlapping? <span>false</span></div>
    <div class="parent">
      <div class="circle small"></div>
    </div>
    <div class="parent">
      <div class="circle large"></div>
    </div>