JSFiddle - React, Tailwind, and code Playground

HTML

<script type="x-shader/x-vertex" id="vertexshader">
attribute vec2 vertex;
uniform vec2 center;
uniform vec2 size;
uniform vec2 screen;
uniform float time;

/* mat4 Perspective(float fovy,float aspect,float near, float far)
 *
 * Params:
 * fov - scalar, vertical field of view
 * ar - scalar, aspect ratio. typically viewport width/height
 * n, f - scalar, near and far bounds of the frustum
 *
 * Returns: the perspective projection matrix with the given bounds
 */
mat4 Perspective(float fov,float ar,float n, float f)
{
	float t = n*tan(radians(fov));
    float r = t*ar;
	return mat4( 	 n/r,	0.0,		  0.0,				 0.0,
					 0.0,	n/t,		  0.0,				 0.0,
					 0.0,	0.0, -(f+n)/(f-n),				-1.0,
					 0.0,	0.0,(-2.0*f*n)/(f-n),			 0.0 	); 
}

/* mat3 RotateX(float a)
 *
 * Params:
 * a - angle (in degree) to rotate
 *
 * Returns: the rotates matrix by the given angle around the X axis
 */
mat3 RotateX(float a)
{
	float r = radians(a);
	float c = cos(r);
	float s = sin(r);

	return mat3(  1.0,	0.0,  0.0,
				  0.0,	  c,    s,
				  0.0,	  s,	c	);
}

/* mat3 RotateY(float a)
 *
 * Params:
 * a - angle (in degree) to rotate
 *
 * Returns: the rotates matrix by the given angle around the Y axis
 */
mat3 RotateY(float a)
{
	float r = radians(a);
	float c = cos(r);
	float s = sin(r);

	return mat3(	c,	0.0,	-s,
				  0.0,	1.0,  0.0,
				   s,	0.0,	c	);
}

void main(void) 
{	
	vec2 sp = center + (vertex/2.0) * size; // vertex in Equirectangular Space;
	float phi = radians(sp.y);
	float theta = radians(sp.x-180.0);
	vec3 p = RotateY(time/3.0) * vec3(-cos(phi)*cos(theta),sin(phi),cos(phi)*sin(theta)); // ertex in Equirectangular Space to 3D hortogonal Space
	gl_Position = Perspective( 45.0, screen.x/screen.y, 0.001, 100000.0) * vec4(p+vec3(0.0,0.0,-2.0) ,1.0);
} 
</script>

<script type="x-shader/x-fragment" id="fragmentshader">
precision mediump float;
uniform vec3 color;

void main(void) 
{
	gl_FragColor.rgb = color;
	gl_FragColor.a = 0.5;
}
</script>
<canvas id="Render"...

JavaScript

var Projects = [
	{ 	center : [ -110, 60],
		size : [100, 18],
		color : [0, 0, 1]
	},
	{ 	center : [ 10, 25],
		size : [70, 70],
		color : [1, 0, 0]
	},
	{ 	center : [ 110, 50],
		size : [100, 25],
		color : [1, 1, 0]
	},
	{ 	center : [ 100, 0],
		size : [50, 50],
		color : [0, 1, 0]
	},
	{ 	center : [-160, -15],
		size : [20, 120],
		color : [0, 1, 1]
	} ,
	{ 	center : [-90, -5],
		size : [80, 40],
		color : [1, 0, 1]
	}, 
	{ 	center : [ 0, -60],
		size : [230, 25],
		color : [0.3, 0.8, 0.1]
	} 
];
	
var canvas = document.getElementById("Render");
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
var gl = canvas.getContext("webgl");

gl.disable( gl.CULL_FACE );
gl.enable( gl.BLEND );
gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );
gl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );
gl.clearColor(0.0, 0.0, 0.0, 1.0);

var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, document.getElementById('vertexshader').textContent);
gl.compileShader(vertexShader);
if(!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) 
{
	console.error("[glProgram] - An error occurred compiling the VertexShaders: " + gl.getShaderInfoLog(vertexShader));
}

var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, document.getElementById('fragmentshader').textContent);
gl.compileShader(fragmentShader);

var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);

// activation des shaders
gl.useProgram(shaderProgram);

shaderProgram.vertexAttribute = gl.getAttribLocation(shaderProgram, "vertex");
gl.enableVertexAttribArray(shaderProgram.vertexAttribute);
shaderProgram.screenUniform = gl.getUniformLocation(shaderProgram, "screen");
shaderProgram.centerUniform = gl.getUniformLocation(shaderProgram, "center");
shaderProgram.sizeUniform =...