JSFiddle - React, Tailwind, and code Playground
by Johan Muller
HTML
<div class="box-parent">
<div class="box size1x1">1</div>
<div class="box size2x1">2</div>
<div class="box size1x1">3</div>
<div class="box size1x1">4</div>
<div class="box size1x2">5</div>
<div class="box size2x1">6</div>
<div class="box size2x1">7</div>
<div class="box size1x2">8</div>
<div class="box size1x1">9</div>
<div class="box size1x1">10</div>
<div class="box size1x1">1</div>
<div class="box size2x1">2</div>
<div class="box size1x1">3</div>
<div class="box size1x1">4</div>
<div class="box size1x2">5</div>
<div class="box size2x1">6</div>
<div class="box size2x1">7</div>
<div class="box size1x2">8</div>
<div class="box size1x1">9</div>
<div class="box size1x1">10</div>
</div>
SCSS
html, body {
width: 100%;
height: 100%;
background: #fff;
}
.box-parent {
position: relative;
background: yellow;
transition: yellow .2s 0s;
}
.box {
display: block;
position: absolute;
background: green;
box-shadow: inset 0px 0px 5px 3px orange;
color: #fff;
transition: top .2s, left .2s;
&.size1x1 {
width: 100px;
height: 100px;
}
&.size2x1 {
width: 200px;
height: 100px;
}
&.size1x2 {
width: 100px;
height: 200px;
}
}
JavaScript
var masterBox = function() {
var $boxParent = $('.box-parent');
var $box = $boxParent.find('.box');
var i; // universal index
var canvasWidth = $boxParent.width();
var cellWidth = 100;
var cellHeight = 100;
var matrixGradeX = parseInt(canvasWidth / cellWidth);
var matrixGradeY = 10; // max height cells
var matrixArray = new Array(matrixGradeX);
var matchHeight = 0;
for (i = 0; i < matrixGradeX; i++) {
matrixArray[i] = new Array(matrixGradeY);
}
var cellChecking = function(matchArray, cx, cy) {
// matchArray for detecting size or className
// cursorArray for detecting width overflow
var noResult = true;
var string = matchArray[0];
var sizex = matchArray[1];
var sizey = matchArray[2];
if (noResult && string == 'size1x1') {
noResult = false;
}
if (noResult && string == 'size1x2') {
noResult = false;
}
if (noResult && string == 'size2x1') {
noResult = false;
}
matrixArray[cx][cy] = true;
return true;
};
$box.each(function(boxIndex, boxElement) {
var $b = $(boxElement);
var style;
var thisBoxMatch = $b.attr('class').match(/size(\d+)x(\d+)/);
var cx, cy;
var hasResult = false;
for (cy = 0; cy < matrixGradeY; cy++) {
for (cx = 0; cx < matrixGradeX; cx++) {
// undefined == free cell in matrix
if (!matrixArray[cx][cy]) {
hasResult = cellChecking(thisBoxMatch, cx, cy);
}
if (hasResult) {
break;
}
}
if (hasResult) {
break;
}
}
if (hasResult) {
style = 'top:' + (cy * cellHeight) + 'px;left:' + (cx * cellWidth) + 'px;';
matchHeight = cy;
} else {
style = 'top:0px;left:0px;background:red;opacity:.2';
}
$b.attr('style', style);
});
var parentStyle = 'height:' + ((matchHeight + 1) * cellHeight) + 'px;';
$boxParent.attr('style', parentStyle);
...