JSFiddle - React, Tailwind, and code Playground

by Paul Draper

HTML

<div id="top"></div>
<div id="bottom"></div>

CSS

#top, #bottom {
    position: absolute;
    left: 0;
    right: 0;
    overflow: auto;    
}

#top { 
    top: 0;  
    bottom: 50%;
    border-bottom: 1px solid black;
}

#bottom {
    top: 50%;
    bottom: 0;
    border-top: 1px solid black;
}

JavaScript

function minBoxes(boxes) {
    var result = [];

    boxes.forEach(function(box1) {
        var bestCombinedBox,
            bestIndex;
        result.reduce(function(bestSavings, box2, i) {
            var x = Math.min(box1.x, box2.x),
                y = Math.min(box1.y, box2.y),
                w = Math.max(box1.x + box1.w, box2.x + box2.w) - x,
                h = Math.max(box1.y + box1.h, box2.y + box2.h) - y;
            var savings = box1.w * box1.h + box2.w * box2.h - w * h;
            if(savings > bestSavings) {
                bestCombinedBox = {x:x, y:y, w:w, h:h};
                bestIndex = i;
                return savings;
            }
            return bestSavings;
        }, 0);
        if(bestCombinedBox) {
            result[bestIndex] = bestCombinedBox; //faster than splicing and pushing
        } else {
            result.push(box1);
        }
    });

    return result;
}

function randInt(x) {
    return Math.floor(x * Math.random());
} 

function drawBoxes(parent, boxes) {
    boxes.forEach(function(box) {
        var div = document.createElement('div');
        div.style.backgroundColor = 'rgba(' + randInt(250) + ',' + randInt(250) + ',' + randInt(250) + ',.8)';
        div.style.position = 'absolute';
        div.style.left = box.x + 'px';
        div.style.top = box.y + 'px';
        div.style.width = box.w + 'px';
        div.style.height = box.h + 'px';
        parent.appendChild(div);
    });
}

var boxes = [];
while(boxes.length < 10) {
    boxes.push({x:randInt(600), y:randInt(300), w:randInt(300), h:randInt(200)});
}

drawBoxes(document.getElementById('top'), boxes);
drawBoxes(document.getElementById('bottom'), minBoxes(boxes));