How to detect if point intersects with shape partially in view

Viewed 60

The solution I'm after: to detect if a point falls within the red area below.

red triangle in the top left corner with X and Y marked on the image

Now the difficulty here is that the red area isn't an image, it's actually a div that has been rotated into position.

rotated red box on a pink background

Using JavaScript, how can I detect if a point lands in this area? And ideally in an efficient manner as this check might need to be called often and on slow devices.

CSS details: It has position: absolute on it, rotated 45 degrees and has been positioned using left: -135 and top:0.

My current approach has been to try and perform some calculation to determine where X intersects with the viewport, which will then give me Y (and I can calculate from there) but I have had no luck. Using getBoundingClientRect() on the element returns a square around the shape, but not of the shape itself.

How can this be done? Here is a small example (I want to detect if the top left corner of the intersecting element intersects with the red triangle):

body {
    background: #ffd0ff;
    padding: 12px;
    margin: 0;
}

.sash {
    position: absolute;
    width: 270px;
    height: 80px;
    top: 0;
    left: -135px;
    background-color: #e10a0a;
    opacity: 0.5;
    transform: rotate(-45deg);
}

.intersection {
    background: rgba(0, 255, 0, 0.5);
    padding: 12px;
    display: inline-block;
}
<div class="sash"></div>
<span class="intersection">
    Some intersecting div
</span>

1 Answers

You can make use of the document.elementFromPoint(x, y) method, e.g.:

function isPointInElement(x, y, selector) {

  let element = document.querySelector(selector);
  let elementFromPoint = document.elementFromPoint(x, y);
  return element == elementFromPoint;
}

function isIntersecting(selector1, selector2) {

  let element1 = document.querySelector(selector1);
  let element1Coords = element1.getBoundingClientRect();
  return isPointInElement(element1Coords.top, element1Coords.left, selector2);
}

let isIntersectionInRedArea = isIntersecting('.intersection', 'div.sash');
console.log(`.intersection and div.sash are ${ isIntersectionInRedArea ? '' : 'not '}intersecting.`);


let isNonIntersectionInRedArea = isIntersecting('.non-intersection', 'div.sash');
console.log(`.non-intersection and div.sash are ${ isNonIntersectionInRedArea ? '' : 'not '}intersecting.`);
body {
  background: #ffd0ff;
  padding: 12px;
  margin: 0;
}

.sash {
  position: absolute;
  width: 270px;
  height: 80px;
  top: 0;
  left: -135px;
  background-color: #e10a0a;
  opacity: 0.5;
  transform: rotate(-45deg);
}

.intersection {
  background: rgba(0, 255, 0, 0.5);
  padding: 12px;
  display: inline-block;
}

.non-intersection {
  background: rgba(0, 0, 255, 0.5);
  padding: 12px;
  display: inline-block;
}
<div class="sash"></div>
<span class="intersection">
    Some intersecting div
</span>
<span class="non-intersection">
    Non intersecting div
</span>

Related