JSFiddle - React, Tailwind, and code Playground
by blparker
HTML
<div class="items">
<!--<div class="item">Foo</div>
<div class="item">Bar</div>
<div class="item">Biz</div>
<div class="item">Baz</div>
<div class="item">Qux</div>
<div class="item">Quoo</div>-->
</div>
CSS
.item { border: 1px solid #aaa; background: #eee; text-align: center; }
.items { position: relative; border: 1px solid blue; width : 500px; height : 1000px; }
JavaScript
function setup(numBlocks) {
var $cont = $('.items');
$cont.css('position', 'relative');
for(var i = 0; i < numBlocks; i++) {
var $i = $('<div />')
.addClass('item')
.css({
'width' : random(100, 200),
'height' : random(100, 200),
'position' : 'absolute'
})
.html('Item ' + i);
$cont.append($i);
}
}
function random(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
function Packer(w, h) {
this.root = { x : 0, y : 0, w : w, h : h };
}
Packer.prototype = {
fit : function(blocks) {
var n, node, block;
for(n = 0; n < blocks.length; n++) {
block = blocks[n];
if(node = this.findNode(this.root, block.w, block.h)) {
block.fit = this.splitNode(node, block.w, block.h);
}
}
},
findNode : function(root, w, h) {
if(root.used) {
return this.findNode(root.right, w, h) || this.findNode(root.down, w, h);
} else if((w <= root.w) && (h <= root.h)) {
return root;
} else {
return null;
}
},
splitNode : function(node, w, h) {
node.used = true;
node.down = { x : node.x, y : node.y + h, w : node.w, h : node.h - h };
node.right = { x : node.x + w, y : node.y, w : node.w - w, h : h };
return node;
}
};
function getBlocks($blocks) {
var blocks = [];
$blocks.each(function() {
var $t = $(this);
blocks.push({
w : $t.width(),
h : $t.height()
});
});
return blocks;
}
setup(5);
var p = new Packer(500, 1000);
var blocks = getBlocks($('.items .item'));
p.fit(blocks);
layout(blocks);
console.log(blocks);
function layout(blocks) {
var $els = $('.items .item');
for(var i = 0; i < blocks.length; i++) {
...