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 =...