JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://www.dropbox.com/s/m6ydli04zmndnk7/sylvester.js?dl=1"></script>
<script src="https://www.dropbox.com/s/p5396sbgfrs3js8/glUtils.js?dl=1"></script>

<style type="text/css">
.dragdrop
{
    text-align: center;
	border-style: dashed; 
	border-width: 1px; 
	width: 200px; 
	height: 200px;
    float: left;
}

.dd_hover
{
    text-align: center;
	border-style: solid;
    background-color: yellow;
	border-width: 1px; 
	width: 200px; 
	height: 200px;
    float: left;
}

.btn
{
    border-style: solid; 
	border-width: 2px;
    background-color:#0FF;
    text-align: center;
	width: 50px; 
	height: 50px;
    clear: both;
    cursor: pointer;
}

.spacer
{
    width: 25px;
    height: 25px;
    float: left;
}
</style>

<script src="sylvester.js" type="text/javascript"></script>
<script src="glUtils.js" type="text/javascript"></script>
<script src="scripts.js" type="text/javascript"></script>

<script id="shader-fs" type="x-shader/x-fragment">
varying highp vec2 vTextureCoord;

uniform sampler2D uSampler;

void main(void)
{
    gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
}
</script>

<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec2 aTextureCoord;

uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;

varying highp vec2 vTextureCoord;

void main(void)
{
    gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
    vTextureCoord = aTextureCoord;
}

</script>

<body onload="init_dd()">
<canvas id="glCanvas" width="500" height="500">
</canvas>
<div>
<DIV id="drop_front" class="dragdrop">
<canvas id="cnv_front">
</DIV>
<div class="spacer"></div>
<DIV id="drop_back" class="dragdrop">
<canvas id="cnv_back">
</DIV>
</div>
<div style="width: 425">Drag and drop the front and back images of your coin to the squares above and press "Go!". You can rotate the ring with arrow keys and Z/X keys.</div>
<DIV id="status" class="btn" onclick="start()">Go!</DIV>
</body>
</html>

JavaScript

var gl;

//'http://i.imgur.com/8WxhHfd.jpg'
//img_names = ["coin.jpg", "coin.jpg", "coin.jpg", "coin.jpg"];
img_names = ['http://i.imgur.com/8WxhHfd.jpg', 'http://i.imgur.com/8WxhHfd.jpg', 'http://i.imgur.com/8WxhHfd.jpg', 'http://i.imgur.com/8WxhHfd.jpg'];
coin_images = [];
buffers = [];

var mvMatrix;
var shaderProgram;
var vertexPositionAttribute;
var perspectiveMatrix;

var coinImageFront;

var textureCoordAttribute;

var coinImageBack;

var rotation_lr = 0.0;
var rotation_ud = 0.0;
var rotation_fb = 0.0;

////////////////////////////////
//drag and drop coin images
var drop_front, drop_back;

function init_dd()
{
    drop_front = document.getElementById("cnv_front");
    drop_back = document.getElementById("cnv_back");
    
    drop_front.addEventListener("dragover", FileDragHover, false);
	drop_front.addEventListener("dragleave", FileDragHover, false);
	drop_front.addEventListener("drop", FileSelectHandler, false);
    
    drop_back.addEventListener("dragover", FileDragHover, false);
	drop_back.addEventListener("dragleave", FileDragHover, false);
	drop_back.addEventListener("drop", FileSelectHandler, false);
    
    start();
}

function FileDragHover(e)
{
	e.stopPropagation();
	e.preventDefault();
    
    var holder = document.getElementById(div_ids[e.target.id]);
	holder.className = (e.type == "dragover" ? "dd_hover" : "dragdrop");
}

var img_nums = {"cnv_front": 0, "cnv_back": 1};
var div_ids = {"cnv_front": "drop_front", "cnv_back": "drop_back"};
 
function FileSelectHandler(e)
{
	FileDragHover(e);
	var files = e.target.files || e.dataTransfer.files;
	var file = files[0];
    
    var targ = e.target;
    var target_id = e.target.id;
    
    var gw = target_id.offsetWidth;
	var gh = target_id.offsetHeight;
	var w;
	var h;
		
	if(file.type.indexOf("image") == 0)
	{
		var reader = new FileReader();
		reader.onload = function(e)
		{
			var image = new Image();
			image.onload = function(e)
			{
				w = this.width;
				h = this.height;
				var coeff =...