Using Web-GL with TypeScript

Sample 1 - Base sample code to display a single coloured triangle.

This page demonstrates the basic setup required to display geometry using WebGL, running this example will display a blue rotating rectangle.
I have used the gl-matrix.js library to handle the matrix manipulations and calculations.
The HTML code below contains the basic shader initialisation code for both the Vertex and Fragment shaders and attaches gl-matrix.js & the transpiled TypeScript file: app.js.
The example can be downloaded from Github Git
            
                <!DOCTYPE html>
                <html lang="en">
                <head>
                    <meta charset="utf-8" />
                    <title>TypeScript HTML App</title>
                    <link rel="stylesheet" href="app.css" type="text/css" />
                    <script id="shader-vs" type="x-shader/x-vertex">
                        attribute vec3 aVertexPosition;
                        uniform mat4 mVMatrix;
                        uniform mat4 pMatrix;
                        void main(void) {
                            gl_Position = pMatrix * mVMatrix * vec4(aVertexPosition, 1.0);
                        }
                    </script>
                    <script id="shader-fs" type="x-shader/x-fragment">
                        precision mediump float;
                        void main(void) {
                            gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
                        }
                    </script>
                    <script src="gl-matrix.js"></script>
                    <script src="app.js"></script>
                </head>
                <body>
                    <canvas id="CanvasGL" style="border: none;" width="500" height="500"></canvas>
                </body>
                </html>
            
        
The TypeScript code below initialises the canvas, buffers, shaders, camera.
            
                declare var mat4: any;
                declare var vec3: any;
                class Plane {
                    private gl: WebGLRenderingContext;
                    private zNear: number = 0.1;
                    private zFar: number = 100.0;
                    private projectionMatrix: any = mat4.create();
                    private aspect: number = 0;
                    // In radians
                    private fieldOfView: number = 45 * Math.PI / 180;
                    private shaderProgram;
                    private mvMatrix = mat4.create();
                    private pMatrix = mat4.create();
                    private vertexPositionBuffer;
                    private vertexIndexBuffer;
                    private vertices;
                    private indices;
                    constructor() {
                        var canvas = document.getElementById("CanvasGL");
                        this.InitGL(canvas)
                        this.InitShaders();
                        this.InitBuffers();
                        this.SetUpCamera();
                        this.gl.clearColor(0.0, 0.0, 0.0, 1.0);
                        this.gl.enable(this.gl.DEPTH_TEST);
                        mat4.translate(this.mvMatrix, this.mvMatrix, vec3.fromValues(0, 0, -7.0))
                        setInterval(() => this.DrawScene(), 10);
                    }
                    private SetUpCamera(): void {
                        this.aspect = this.gl.canvas.clientWidth / this.gl.canvas.clientHeight;
                        mat4.perspective(this.pMatrix,
                            this.fieldOfView,
                            this.aspect,
                            this.zNear,
                            this.zFar);
                    }
                    private InitGL(canvas) {
                        var names = ["webgl", "experimental-webgl", "webkit-3d", "mozwebgl"];
                        for (var i = 0; i < names.length; ++i) {
                            try {
                                this.gl = canvas.getContext(names[i]);
                            } catch (e) { }
                            if (this.gl) {
                                break;
                            }
                        }
                        if (this.gl == null) {
                            alert("Could not initialise WebGL");
                            return null;
                        }
                    }
                    private InitShaders() {
                        var fragmentShader = this.GetShader(this.gl, "shader-fs");
                        var vertexShader = this.GetShader(this.gl, "shader-vs");
                        this.shaderProgram = this.gl.createProgram();
                        this.gl.attachShader(this.shaderProgram, vertexShader);
                        this.gl.attachShader(this.shaderProgram, fragmentShader);
                        this.gl.linkProgram(this.shaderProgram);
                        if (!this.gl.getProgramParameter(this.shaderProgram, this.gl.LINK_STATUS)) {
                            alert("Could not initialise shaders");
                        }
                        this.gl.useProgram(this.shaderProgram);
                        this.shaderProgram.vertexPositionAttribute = this.gl.getAttribLocation(this.shaderProgram, "aVertexPosition");
                        this.gl.enableVertexAttribArray(this.shaderProgram.vertexPositionAttribute);
                        this.shaderProgram.pMatrixUniform = this.gl.getUniformLocation(this.shaderProgram, "pMatrix");
                        this.shaderProgram.mvMatrixUniform = this.gl.getUniformLocation(this.shaderProgram, "mVMatrix");
                    }
                    private GetShader(gl, id) {
                        var shaderScript = (document.getElementById(id));
                        if (!shaderScript) {
                            return null;
                        }
                        var str = "";
                        var k = shaderScript.firstChild;
                        while (k) {
                            if (k.nodeType == 3) {
                                str += k.textContent;
                            }
                            k = k.nextSibling;
                        }
                        var shader;
                        if (shaderScript.type == "x-shader/x-fragment") {
                            shader = gl.createShader(gl.FRAGMENT_SHADER);
                        } else if (shaderScript.type == "x-shader/x-vertex") {
                            shader = gl.createShader(gl.VERTEX_SHADER);
                        } else {
                            return null;
                        }
                        gl.shaderSource(shader, str);
                        gl.compileShader(shader);
                        if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
                            alert(gl.getShaderInfoLog(shader));
                            return null;
                        }
                        return shader;
                    }

                    private InitBuffers() {
                        this.vertexPositionBuffer = this.gl.createBuffer();
                        this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexPositionBuffer);

                        this.vertices = [
                            -1.0, -1.0, 0.0,  //v0
                             1.0, -1.0, 0.0,  //v1
                             0.0,  1.0, 0.0,  //v2
                        ];
                        this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(this.vertices), this.gl.STATIC_DRAW);
                        this.vertexPositionBuffer.itemSize = 3;
                        this.vertexPositionBuffer.numItems = 4;

                        this.vertexIndexBuffer = this.gl.createBuffer();
                        this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.vertexIndexBuffer);
                        this.indices = [0, 1, 2];
                        this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(this.indices), this.gl.STATIC_DRAW);

                        this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null);
                    }

                    private DrawScene() {
                        this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);

                        this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexPositionBuffer);
                        this.gl.vertexAttribPointer(this.shaderProgram.vertexPositionAttribute, this.vertexPositionBuffer.itemSize, this.gl.FLOAT,
                            false, 0, 0);

                        this.SetMatrixUniforms();

                        this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.vertexIndexBuffer);

                        this.gl.drawElements(this.gl.TRIANGLES, this.indices.length, this.gl.UNSIGNED_SHORT, 0);
                    }

                    private SetMatrixUniforms() {
                        this.gl.uniformMatrix4fv(this.shaderProgram.pMatrixUniform, false, this.pMatrix);
                        this.gl.uniformMatrix4fv(this.shaderProgram.mvMatrixUniform, false, this.mvMatrix);
                    }
                }

                window.onload = () => {
                    var plane = new Plane();
                }