如何检测点是否在视图中部分与形状相交

时间:2019-06-21 08:22:01

标签: javascript css

我追求的解决方案:检测点是否落在下面的红色区域内。

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

现在,这里的困难在于红色区域不是图像,实际上是已旋转到位置的div。

rotated red box on a pink background

使用JavaScript,如何检测某个点是否落在该区域?理想情况下,以一种有效的方式,因为可能需要经常在缓慢的设备上调用此检查。

CSS详细信息:它上面有position: absolute,旋转了45 degrees,并已使用left: -135top:0进行了定位。

我目前的方法是尝试执行一些计算以确定X与视口相交的位置,这将给我Y(我可以从那里进行计算),但是我没有运气。在元素上使用getBoundingClientRect()会在形状周围返回一个正方形,但形状本身不会返回。

这怎么办?这是一个小示例(我想检测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;
}
<div class="sash"></div>
<span class="intersection">
    Some intersecting div
</span>

1 个答案:

答案 0 :(得分:2)

您可以使用document.elementFromPoint(x, y)方法,例如:

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>