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);


 ...