Rectangle Overlap

Algorithm for detecting the overlap between two rectangles and deriving a third rectangle representing the intersection.

by soulwire

HTML

<div class="box" id="boxA"></div>
<div class="box" id="boxB"></div>
<div class="box" id="boxC"></div>

CSS

.box {
    position: absolute;
    display: block;
    pointer-events: none;
}
  
#boxA {
    top: 200px;
    left: 120px;
    width: 100px;
    height: 100px;
    background: rgba(255,0,255,0.25);
}

#boxB {
    width: 80px;
    height: 120px;
    background: rgba(0,255,255,0.25);
}

#boxC {
    width: 200px;
    height: 100px;
    background: rgba(0,255,0,0.25);
    border: 1px dashed rgba(0,0,0,0.1);
}

JavaScript

$boxA = $('#boxA');
$boxB = $('#boxB');
$boxC = $('#boxC');

var rectA = {
    x: $boxA.offset().left,
    y: $boxA.offset().top,
    width: $boxA.width(),
    height: $boxA.height()
};

var rectB = {
    x: $boxB.offset().left,
    y: $boxB.offset().top,
    width: $boxB.width(),
    height: $boxB.height()
};

function getOverlap(r1, r2) {

    if(r1.x > r2.x + r2.width || r2.x > r1.x + r1.width || r1.y > r2.y + r2.height || r2.y > r1.y + r1.height) {
        return null;
    }

    return {
        x: Math.max(r1.x, r2.x),
        y: Math.max(r1.y, r2.y),
        width: Math.min(r1.x + r1.width, r2.x + r2.width) - Math.max(r1.x, r2.x),
        height: Math.min(r1.y + r1.height, r2.y + r2.height) - Math.max(r1.y, r2.y)
    };
}

function onMouseMove(event) {

    rectB.x = event.offsetX - rectB.width / 2;
    rectB.y = event.offsetY - rectB.height / 2;
    
    $boxA.css({
        top: rectA.y,
        left: rectA.x,
        width: rectA.width,
        height: rectA.height
    });
    
    $boxB.css({
        top: rectB.y,
        left: rectB.x,
        width: rectB.width,
        height: rectB.height
    });
    
    var overlap = getOverlap(rectA, rectB);
    
    if(overlap) {
        $boxC.css({
          top: overlap.y - 1,
          left: overlap.x - 1,
          width: overlap.width,
          height: overlap.height,
          display: 'block'
        });
    } else {
        $boxC.css('display', 'none');
    }
}

window.addEventListener('mousemove', onMouseMove);