JSFiddle - React, Tailwind, and code Playground

HTML

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Test</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" type="text/css" media="screen" href="./index.css" />
</head>

<body>
    <canvas id="canvas"></canvas>
    <div id="uiContainer">
        <div id="ui">
            <div id="cameraAngle"></div>
        </div>
    </div>

    <script id="2d-vertex-shader" type="notjs">
        attribute vec4 position;
        attribute vec4 color;

        uniform mat4 u_matrix;

        varying vec4 vColor;

        void main(void) {
            gl_Position = u_matrix * position;
            vColor = color;
        }
    </script>
    <script id="2d-fragment-shader" type="notjs">
        precision mediump float;

        varying vec4 vColor;

        void main(void) {
            gl_FragColor = vColor;
        }
    </script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.7.1/gl-matrix-min.js"></script>
</body>

</html>

CSS

#canvas {
    width: 900px;
    height: 600px;
}

JavaScript

function main(images) {

document.body.removeChild(document.querySelector('canvas'));

const canvas = document.createElement('canvas');
canvas.id = 'canvas';
document.body.appendChild(canvas);

const gl = canvas.getContext('webgl');
if (!gl) {
    return;
}

var AMORTIZATION = 0.95;
var drag = false;
var old_x, old_y;
var dX = 0, dY = 0;
var mouseDown = function (e) {
    drag = true;
    old_x = e.pageX;
    old_y = e.pageY;

    e.preventDefault();
    return false;
};

var mouseUp = function (e) {
    drag = false;
};

var mouseMove = function (e) {
    if (!drag) return false;
    dX = (e.pageX - old_x) * 2 * Math.PI / canvas.width;
    dY = (e.pageY - old_y) * 2 * Math.PI / canvas.height;
    THETA += dX;
    PHI += dY;
    old_x = e.pageX, old_y = e.pageY;

    e.preventDefault();
};

canvas.addEventListener('mousedown', mouseDown, false);
canvas.addEventListener('mouseup', mouseUp, false);
canvas.addEventListener('mouseout', mouseUp, false);
canvas.addEventListener('mousemove', mouseMove, false);


const vertexShaderSource = document.getElementById('2d-vertex-shader').text;
const fragmentShaderSource = document.getElementById('2d-fragment-shader').text;

const program = gl.createProgram();

const vShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vShader, vertexShaderSource);
gl.compileShader(vShader);

const fShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fShader, fragmentShaderSource);
gl.compileShader(fShader);

gl.attachShader(program, vShader);
gl.attachShader(program, fShader);
gl.linkProgram(program);

gl.useProgram(program);

var color = gl.getAttribLocation(program, 'color');
var position = gl.getAttribLocation(program, 'position');
var u_matrix = gl.getUniformLocation(program, 'u_matrix');
gl.enableVertexAttribArray(color);
gl.enableVertexAttribArray(position);

var multiplier = 1;
const width = canvas.clientWidth * multiplier | 0;
const height = canvas.clientHeight * multiplier | 0;
canvas.width = width;
canvas.height =...