JSFiddle - React, Tailwind, and code Playground

by XGundam05

HTML

<div id="tools" class="dEditUI">
    <div id="brushes">brushes</div>
    <div class="tabset">
        <div id="floors" class="tab">
            <input type="radio" id="tab-floors" name="tab-group-1" checked>
            <label for="tab-floors">F</label>
            <div class="content">
                floors
            </div>
        </div>
        <div id="walls" class="tab">
            <input type="radio" id="tab-walls" name="tab-group-1">
            <label for="tab-walls">W</label>
            <div class="content">
                walls
            </div>
        </div>
        <div id="ceiling" class="tab">
            <input type="radio" id="tab-ceiling" name="tab-group-1">
            <label for="tab-ceiling">C</label>
            <div class="content">
                ceiling
            </div>
        </div>
        <div id="objects" class="tab">
            <input type="radio" id="tab-objects" name="tab-group-1">
            <label for="tab-objects">O</label>
            <div class="content">
                objects
            </div>
        </div>
    </div>
</div>
<div id="viewport" class="dEditUI">
    <canvas id="view"></canvas>
</div>
<div id="dataGui" class="dEditUI">
</div>

CSS

::-webkit-scrollbar{
  width: 7px;
  height: 7px;
}

::-webkit-scrollbar-track{
  background-color:#141a25;
}

::-webkit-scrollbar-thumb{
  background-color:#888e94;
}

body{
  background-color: #282e34;
  padding: 0;
  margin: 0;
}

div.dEditUI{
  background-color: #484e54;
  border: solid 1px black;
  float: left;
}

#dataGui{
  float: right;
  width: 245px;
}

#tools{
  width: 100px;
}

#viewport{
  float: left;
  width: calc(100% - 351px);
  height: calc(100% - 2px);
  overflow: auto;
  position: relative;
}

#view{
  position: absolute;
  top: calc(50% - 75px);
  left: calc(50% - 150px);
}

#brushes{
  height: 35px;
  border-bottom: solid 1px black;
}

.tabset{
  position: relative;
  min-height: calc(100% - 38px);
  clear: both;
  font-family: sans-serif;
  color: #dedede;
}

.tab{
  float: left;
}

.tab label{
  background: #383e44;
  border-left:solid 1px black;
  border-top:solid 1px black;
  border-bottom:solid 1px black;
  position: relative;
  margin-left:-1px;
  left:0px;
  display: block;
  width: 25px;
  height: 17px;
  text-align:center;
}

.tab [type=radio]{
  display: none;
}

.tab .content{
  position: absolute;
  top: 19px;
  left: 0;
  right: 0;
  bottom: 0;
  background: #686e74;
  padding: 5px;
}

[type=radio]:checked ~ label{
  background: #686e74;
  border-bottom: solid 1px #686e74;
}

[type=radio]:checked ~ label ~ .content{
  z-index: 1;
}

JavaScript

// mouse.js
// ==========================
// MOUSE
// - Mouse object for handling mouse input automagically
// ====================================================
function Mouse(){
  this.x = 0;
  this.y = 0;
  this.buttons = [false, false, false, false];
}

Mouse.prototype.isInside = function(el){
  var rect = el.getBoundingClientRect();
  return (this.x < rect.right) && (this.x > rect.left) &&
    (this.y < rect.bottom) && (this.y > rect.top);
};

Mouse.prototype.relativePos = function(el){
  var rect = el.getBoundingClientRect();
  return {
    x: this.x - rect.left,
    y: this.y - rect.top
  };
};

Mouse.prototype.updatePos = function(e){
  this.x = e.clientX;
  this.y = e.clientY;
};

Mouse.prototype.createDotCursor = function(el){
  var canv = document.createElement('canvas');
  canv.width = 2; canv.height = 2;
  var mctx = canv.getContext('2d');
  mctx.fillStyle = 'red';
  mctx.fillRect(0,0,2,2);
  el.style.cursor = 'url(' + canv.toDataURL() + '), auto';
};

Mouse.prototype.AddEventHandlers = function(element){
  var that = this;
  element.addEventListener('mousemove', function(e){
    that.updatePos(e);
  })

  element.addEventListener('mousedown', function(e){
    that.buttons[e.which] = true;
  })

  element.addEventListener('mouseup', function(e){
    that.buttons[e.which] = false;
  })
};

// inspector.js
// =======================
function ArrayInspector(gui, array, type){
  this.gui = gui;
  this.__array = array;
  this.__valueType = type;
  this.__controls = [];
}

ArrayInspector.prototype = {
  __defaultValue: function(){
    if (this.__valueType === undefined)
      return '';
    if (this.__valueType.constructor === String)
      return '';
    if (this.__valueType.constructor === Number)
      return 0;
    if (this.__valueType.constructor === Boolean)
      return false;
    if (this.__valueType.constructor === Array)
      return [];
      
    return new this.__valueType.constructor();
  },
  
  __addObjectGUI: function(obj, index){
   ...