Rectangle Intersection
function testRectIntersection(divA, divB) {
const rectA = divA.getBoundingClientRect();
const rectB = divB.getBoundingClientRect();
return (
rectA.left < rectB.right &&
rectA.right > rectB.left &&
rectA.top < rectB.bottom &&
rectA.bottom > rectB.top
);
}
function rect(color, x, y, width = 100, height = 100) {
const el = document.body.appendChild(document.createElement('div'));
Object.assign(el.style, {
position: 'absolute',
left: `${x}px`,
top: `${y}px`,
width: `${width}px`,
height: `${height}px`,
background: color
});
return el;
}
const redBox = rect('red', 20, 20, 100, 100);
const mover = rect('green', 130, 20, 100, 100);
// with a `mousemove` only this won't be _great_ on mobile
document.addEventListener('mousemove', e => {
Object.assign(mover.style, {
left: `${e.clientX - parseFloat(mover.style.width) / 2}px`,
top: `${e.clientY - parseFloat(mover.style.height) / 2}px`
});
if (testRectIntersection(mover, redBox)) {
redBox.style.background = 'blue';
} else {
redBox.style.background = 'red';
}
});
Move your mouse so that the green rectangle touches the red.
This snippet shows how to test the if two non-rotated rectangles are intersecting. The only real part of the code that does this is:
rectA.left < rectB.right &&
rectA.right > rectB.left &&
rectA.top < rectB.bottom &&
rectA.bottom > rectB.top
With an understanding of how x/y
coordinates work on the web, it can be fun to draw this out and figure out why it works on your own.
I’ve used getBoundingClientRect
to obtain the rectangles of two divs here. In the rare case where you need to calculate many many intersections frequently, getBoundingClientRect
should be avoided if possible as it can get slow for a variety of reasons. The alternative to getBoundingClientRect
is to keep track of all the rectangle coordinate and size information yourself.