JSFiddle - React, Tailwind, and code Playground

HTML

<!DOCTYPE html>
<html>
<head>
    <title>2D Tunnel effect</title>
</head>
<body>
    <canvas id="tunnelCanvas">
    </canvas>    
    <div id="message">Click To Start</div>
    <div id="stats"></div>
 </body>
</html>

CSS

html, body
{
    width: 100%;
    height: 100%;
    font-family: "Segoe UI";
    color: white;
    margin: 0px;
    padding: 0px;
    background: black;
    overflow: hidden;
}

#stats
{
    position:absolute;
    right:10px;
    top:10px;
    color:black;
}

#message
{
    position:absolute;
    left:40px;
    right:40px;
    bottom:30px;
    text-align: center;
    color:white;
    font-size: 40px;
    text-shadow: 4px 4px 4px black;
    cursor: pointer;
}

JavaScript

(function () {
    function computeFPS() {
        if (previous.length > 60) {
            previous.splice(0, 1);
        }
        var start = (new Date).getTime();
        previous.push(start);
        var sum = 0;

        for (var id = 0; id < previous.length - 1; id++) {
            sum += previous[id + 1] - previous[id];
        }

        var diff = 1000.0 / (sum / previous.length);

        stats.innerHTML = diff.toFixed() + " fps";
    }

    var loadTexture = function (name, then) {
        var texture = new Image();
        var textureData;
        var textureWidth;
        var textureHeight;
        var result = {};

        // on load
        texture.addEventListener('load', function () {
            var textureCanvas = document.createElement('canvas'); // off-screen canvas

            // Setting the canvas to right size
            textureCanvas.width = this.width; //<-- "this" is the image
            textureCanvas.height = this.height;

            result.width = this.width;
            result.height = this.height;

            var textureContext = textureCanvas.getContext('2d');
            textureContext.drawImage(this, 0, 0);

            result.data = textureContext.getImageData(0, 0, this.width, this.height).data;

            then();
        }, false);

        // Loading
        texture.src = name;

        return result;
    };

    var renderingLoop = function () {
        var textureIndex;
        var radius, u, v, w;
        var canvasIndex;

        // Compute FPS
        if (render)
            computeFPS();

        var index = 0;
        for (var y = -canvasHeight / 2; y < canvasHeight / 2; y++) {
            for (var x = -canvasWidth / 2; x < canvasWidth / 2; x++) {
                radius = Math.sqrt(x * x + y * y);

                u = ((5.0 + 40.0 * Math.abs(Math.cos(angle))) / radius);
                v = 0.5 * atans[index++];
                w = radius * 0.01;

                u = u * texture.width + zoom;
                v =...