JSFiddle - React, Tailwind, and code Playground

by secretgspot

HTML

<div id="viewport" >
        <div id="world" >
        </div>
    </div>
    
    <div id="options">
        <a href="#" id="closeBtn" class="button" >X</a>
        <div id="optionsContent">
            <div class="actions" >
                <a class="button" href="#" id="generateBtn" >Generate clouds</a> <a class="button" href="#" id="showTextureControlsBtn" >Show texture controls</a> <a class="button" href="#" id="fullscreenBtn" >Fullscreen</a>
            </div>
            <div id="textureControls" >
                <h2>Texture list</h2>
                <p>Select one or more textures to create clouds. The more the merrier!</p>
                <ul id="textureList" >
                </ul>
            </div>
            <h2>Presets</h2>
            <div class="presets" >
                <a href="#" class="left button" id="cloudsPreset" >Clouds</a>
                <a href="#" class="middle button" id="stormPreset" >Storm</a>
                <a href="#" class="middle button" id="boomPreset" >Boom</a>
                <a href="#" class="right button" id="bayPreset" >Michael Bay</a>
            </div>
            <div style="clear:both; height: 20px; display: block" ></div>
        </div>
    </div>

CSS

*{ 
        box-sizing: border-box; 
        margin: 0; 
        padding: 0 
    }
    body {
        color: #eee;
        text-shadow: 0 -1px 0 rgba( 0, 0, 0, .6 );
        font-family: 'Open Sans', sans-serif;
        font-size: 13px;
        line-height: 16px;
        overflow: hidden;
    }
    #viewport {
        -webkit-perspective: 1000; 
        -moz-perspective: 1000px; 
        -o-perspective: 1000; 
        position: absolute;
        left: 0;
        top: 0;
        right: 0;
        bottom: 0;
        overflow: hidden;
        background-image: linear-gradient(bottom, rgb(69,132,180) 28%, rgb(31,71,120) 64%);
        background-image: -o-linear-gradient(bottom, rgb(69,132,180) 28%, rgb(31,71,120) 64%);
        background-image: -moz-linear-gradient(bottom, rgb(69,132,180) 28%, rgb(31,71,120) 64%);
        background-image: -webkit-linear-gradient(bottom, rgb(69,132,180) 28%, rgb(31,71,120) 64%);
        background-image: -ms-linear-gradient(bottom, rgb(69,132,180) 28%, rgb(31,71,120) 64%);

        background-image: -webkit-gradient(
            linear,
            left bottom,
            left top,
            color-stop(0.28, rgb(69,132,180)),
            color-stop(0.64, rgb(31,71,120))
        );
    }

    #world {
        position: absolute;
        left: 50%;
        top: 50%;
        margin-left: -256px;
        margin-top: -256px;
        height: 512px;
        width: 512px;
        //border: 1px solid rgb( 255, 0, 0 );
        -webkit-transform-style: preserve-3d;
        -moz-transform-style: preserve-3d;
        -o-transform-style: preserve-3d;
        pointer-events: none;
    }
    
    #world div {
        -webkit-transform-style: preserve-3d;
        -moz-transform-style: preserve-3d;    
        -o-transform-style: preserve-3d;    
    }
    
    .cloudBase {
        //border: 1px solid #ff00ff;
        position: absolute;
        left: 256px;
        top: 256px;
        width: 20px;
        height: 20px;
        margin-left: -10px;
...

JavaScript

(function() {
        var lastTime = 0;
        var vendors = ['ms', 'moz', 'webkit', 'o'];
        for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
            window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
            window.cancelRequestAnimationFrame = window[vendors[x]+
              'CancelRequestAnimationFrame'];
        }

        if (!window.requestAnimationFrame)
            window.requestAnimationFrame = function(callback, element) {
                var currTime = new Date().getTime();
                var timeToCall = Math.max(0, 16 - (currTime - lastTime));
                var id = window.setTimeout(function() { callback(currTime + timeToCall); }, 
                  timeToCall);
                lastTime = currTime + timeToCall;
                return id;
            };

        if (!window.cancelAnimationFrame)
            window.cancelAnimationFrame = function(id) {
                clearTimeout(id);
            };
    }())

    var layers = [],
        objects = [],
        textures = [],
        
        world = document.getElementById( 'world' ),
        viewport = document.getElementById( 'viewport' ),
        
        d = 0,
        p = 400,
        worldXAngle = 0,
        worldYAngle = 0,
        computedWeights = [];
    
    var links = document.querySelectorAll( 'a[rel=external]' );
    for( var j = 0; j < links.length; j++ ) {
        var a = links[ j ];
        a.addEventListener( 'click', function( e ) {
            window.open( this.href, '_blank' );
            e.preventDefault();
        }, false );
    }
    
    viewport.style.webkitPerspective = p;
    viewport.style.MozPerspective = p + 'px';
    viewport.style.oPerspective = p;
    
    textures = [
        { name: 'white cloud',     file: 'http://www.clicktorelease.com/code/css3dclouds/cloud.png'        , opacity: 1, weight: 0 },
        { name: 'dark cloud',     file:...