JSFiddle - React, Tailwind, and code Playground

HTML

<!DOCTYPE html>
<html>
<head>
<title>orthogonal projection and clip space</title>
</head>
<script id='vshader' type="x-shader/x-vertex">
attribute vec3 a_vertex;

// orthogonal projection matrix
uniform mat4 u_pMatrix;
// model view matrix
uniform mat4 u_mvMatrix;


void main(){
  gl_Position = u_pMatrix * u_mvMatrix * vec4(a_vertex, 1);
}
</script>

<script id='fshader' type="x-shader/x-fragement">
void main(){
  gl_FragColor = vec4(1, 0, 1, 1);
}
</script>
<body style='margin:0'>
<canvas id='canvas'></canvas>

<script>
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
// shim layer with setTimeout fallback
window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame    ||
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();


// init webgl
var canvas = document.getElementById('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);

// vertices, rectangle, triangle strip
var squareSize = 50;
var vertices = [
  squareSize, 0,          0,
  0,          0,          0,
  squareSize, squareSize, 0,
  0,          squareSize, 0
];

// the depth will be the canvas width.
var depth = canvas.width;
// transpose of the orthogonal project matrix, y axis flipped to achieve top left as origin
var orthoMatrix = [
  2/canvas.width, 0,                0,        0,
  0,             -2/canvas.height,  0,        0,
  0,              0,                2/depth,  0,
 -1,              1,               -1,        1
];

// setup shader and program
var vshader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vshader, document.getElementById('vshader').textContent);
gl.compileShader(vshader);
var fshader =...