JSFiddle - React, Tailwind, and code Playground

by vjeux

HTML

<script src="http://www.numericjs.com/lib/numeric-1.2.6.js"></script>

<!--
  Blocked Recursive Image Composition implementation by Vjeux <http://blog.vjeux.com>
  Original paper: https://www.hpl.hp.com/techreports/2008/HPL-2008-199.pdf
-->

<div id="display"></div>

CSS

#display {
  position: relative;
}

.element {
  position: absolute;
  border: 1px solid red;
}

JavaScript

// Open your console to see the result
function example() {
  var W = 500;

  var tree =
      split('V9', 'vertical',
            split('H7', 'horizontal',
                  split('V6', 'vertical',
                        image('p1', 1.3),
                        image('p5', 0.7)
                       ),
                  image('p3', 1.3)
                 ),
            split('H8', 'horizontal',
                  image('p2', 0.8),
                  image('p4', 1.4)
                 )
           );

  var layout = compute_layout(tree, W);
  
  display_layout(tree, layout, document.getElementById('display'));
  return;
}

function display_layout(tree, layout, root_div) {
  display_node(tree, 0, 0);
  
  function display_node(node, x, y) {
    if (node.type === 'image') {
      var div = document.createElement('div');
      div.className = 'element';
      div.style.top = y + 'px';
      div.style.left = x + 'px';
      div.style.width = layout['w' + node.id] + 'px';
      div.style.height = layout['h' + node.id] + 'px';
      div.innerText = node.id;
      root_div.appendChild(div);
      return;
    }
    
    //  A
    // ---
    //  B
    if (node.alignment === 'horizontal') {
      display_node(node.left, x, y);
      display_node(node.right, x, y + layout['h' + node.left.id]);
      return;
    }

    // A | B
    if (node.alignment === 'vertical') {
      display_node(node.left, x, y);
      display_node(node.right, x + layout['w' + node.left.id], y);
      return;
    }
    
    throw 'Wtf!';
  }
  
}

// Layout implementation

function image(id, ratio) {
  return {
    type: 'image',
    id: id,
    ratio: ratio
  };
}

function split(id, alignment, left, right) {
  return {
    type: 'split',
    alignment: alignment,
    left: left,
    right: right,
    id: id
  };
}

function compute_layout(tree, W) {
  var system = new LinearSolver();

  function processNode(node) {
    if (node.type === 'image') {
      // w_node = h_node / r_node
     ...