Source: math/Matrix2D.js

/**
 *  @class Matrix2D
 *  @memberof SQR
 *
 *  @description A matrix that implements 2D affine transformations. 
 *  Most of the method return the current instance for chaining.
 *
 *  @todo Make it column major
 */
SQR.Matrix2D = function() {

    this.data = new Float32Array(9);

    var a, b, d, x, y;

    /**
     *  @method identity
     *  @memberof SQR.Matrix2D.prototype
     *  @description Resets the matrix to identity values.
     */
    this.identity = function(d) {
        d = d || this.data;
        d[0] = 1,d[3] = 0,d[6] = 0;
        d[1] = 0,d[4] = 1,d[7] = 0;
        d[2] = 0,d[5] = 0,d[8] = 1;

        return this;
    }

    /**
     *  @method transformVector
     *  @memberof SQR.Matrix2D.prototype
     *  @description Multiplies the vector by the matrix
     *  @param v vector to multiply
     *  @returns the same vector as passed in the parameter, multiplied by this matrix
     */
    this.transformVector = function(v) {
        d = this.data;
        x = v.x,y = v.y;
        v.x = d[0] * x + d[1] * y + d[2];
        v.y = d[3] * x + d[4] * y + d[5];
        return v;
    }

    /**
     *  @method setTranslation
     *  @memberof SQR.Matrix2D.prototype
     *  @description Sets the translation values.
     *  @param tx x translation
     *  @param ty y translation
     *  @param m the matrix to set translation to, applies to this if ommited
     */
    this.setTranslation = function(tx, ty, m) {
        d = m || this.data;
        d[0] = 1,d[3] = 0,d[6] = tx;
        d[1] = 0,d[4] = 1,d[7] = ty;
        d[2] = 0,d[5] = 0,d[8] = 1;
        return this;
    }

    /**
     *  @method getTranslation
     *  @memberof SQR.Matrix2D.prototype
     *  @description Returns the translation value as 2d vector.
     *  @param {SQR.V2} v vector to use to return values in, if ommited a new vector object is returned
     *  @returns {SQR.V2} 2d vector with translation values
     */
    this.getTranslation = function(v) {
        d = this.data;
        v = v || new SQR.V2();
        v.x = d[2];
        v.y = d[5];
        return v;
    }

    /**
     *  @method setScale
     *  @memberof SQR.Matrix2D.prototype
     *  @description Sets the scale values.
     *  @param sx x scale
     *  @param sy y scale
     *  @param m the matrix to set scale to, applies to `this` if ommited
     */
    this.setScale = function(sx, sy, m) {
        d = m || this.data;
        d[0] = sx,d[3] = 0, d[6] = 0;
        d[1] = 0, d[4] = sy,d[7] = 0;
        d[2] = 0, d[5] = 0, d[8] = 1;
        return this;
    }

    /**
     *  @method setShear
     *  @memberof SQR.Matrix2D.prototype
     *  @description Sets the scale values.
     *  @param sx x shear
     *  @param sy y shear
     *  @param m the matrix to set shear to, applies to `this` if ommited
     */
    this.setShear = function(sx, sy, m) {
        d = m || this.data;
        d[0] = 1, d[3] = sx,d[6] = 0;
        d[1] = sy,d[4] = 1, d[7] = 0;
        d[2] = 0, d[5] = 0, d[8] = 1;
        return this;
    }

    /**
     *  @method setRotation
     *  @memberof SQR.Matrix2D.prototype
     *  @description Sets the rotation value.
     *  @param a angle in radians
     *  @param m the matrix to set shear to, applies to `this` if ommited
     */
    this.setRotation = function(a, m) {
        d = m || this.data;
        var r0 = Math.cos(a);
        var r1 = Math.sin(a);
        d[0] = r0,d[3] = -r1,d[6] = 0;
        d[1] = r1,d[4] = r0, d[7] = 0;
        d[2] = 0, d[5] = 0,  d[8] = 1;
        return this;
    }

    /**
     *  @method setTRS
     *  @memberof SQR.Matrix2D.prototype
     *  @description Sets the translation/rotation/scale values at once.
     *  @param tx x translation
     *  @param ty y translation
     *  @param a angle in radians
     *  @param sx x scale
     *  @param sy y scale
     */
    this.setTRS = function(tx, ty, a, sx, sy) {
        d = this.data;
        var r0 = Math.cos(a);
        var r1 = Math.sin(a);
        d[0] = r0 * sx,d[3] = -r1 * sy,d[6] = tx;
        d[1] = r1 * sx,d[4] = r0 * sy, d[7] = ty;
        d[2] = 0,      d[5] = 0,       d[8] = 1;
        return this;
    }

    /** 
     *  @method translate
     *  @memberof SQR.Matrix2D.prototype
     *  @description Applies translation to matrix
     *  @param tx x translation
     *  @param ty y translation
     */
    this.translate = function(tx, ty) {
        this.identity(SQR.Matrix2D.__temp);
        this.setTranslation(tx, ty, SQR.Matrix2D.__temp);
        return this.multiply(SQR.Matrix2D.__temp);
    }

    /** 
     *  @method rotate
     *  @memberof SQR.Matrix2D.prototype
     *  @param a angle in radians
     *  @description Applies rotation to matrix
     */
    this.rotate = function(a) {
        this.identity(SQR.Matrix2D.__temp);
        this.setRotation(a, SQR.Matrix2D.__temp);
        return this.multiply(SQR.Matrix2D.__temp);
    }

    /** 
     *  @method scale
     *  @memberof SQR.Matrix2D.prototype
     *  @param sx x scale
     *  @param sy y scale
     *  @description Applies scale to matrix
     */
    this.scale = function(sx, sy) {
        this.identity(SQR.Matrix2D.__temp);
        this.setScale(sx, sy, SQR.Matrix2D.__temp);
        return this.multiply(SQR.Matrix2D.__temp);
    }

    /** 
     *  @method shear
     *  @memberof SQR.Matrix2D.prototype
     *  @param sx x shear
     *  @param sy y shear
     *  @description Applies shear to matrix
     */
    this.shear = function(sx, sy) {
        this.identity(SQR.Matrix2D.__temp);
        this.setRotation(sx, sy, SQR.Matrix2D.__temp);
        return this.multiply(SQR.Matrix2D.__temp);
    }

    var a11, a12, a13, a21, a22, a23, a31, a32, a33;
    var b11, b12, b13, b21, b22, b23, b31, b32, b33;

    /** 
     *  @method multiply
     *  @memberof SQR.Matrix2D.prototype
     *  @param m matrix to multiply the current matrix by
     *  @description Multiples current matrix by m and stores result in current matrix.
     */
    this.multiply = function(m) {
        a = this.data, b = m.data || m;

        a11 = a[0],a12 = a[3],a13 = a[6];
        a21 = a[1],a22 = a[4],a23 = a[7];
        a31 = a[2],a32 = a[5],a33 = a[8];

        b11 = b[0],b12 = b[3],b13 = b[6];
        b21 = b[1],b22 = b[4],b23 = b[7];
        b31 = b[2],b32 = b[5],b33 = b[8];

        a[0] = a11 * b11 + a12 * b21 + a13 * b31;
        a[3] = a11 * b12 + a12 * b22 + a13 * b32;
        a[6] = a11 * b13 + a12 * b23 + a13 * b33;

        a[1] = a21 * b11 + a22 * b21 + a23 * b31;
        a[4] = a21 * b12 + a22 * b22 + a23 * b32;
        a[7] = a21 * b13 + a22 * b23 + a23 * b33;

        //a[6] = a31 * b11 + a32 * b21 + a33 * b31;
        //a[7] = a31 * b12 + a32 * b22 + a33 * b32;
        //a[8] = a31 * b13 + a32 * b23 + a33 * b33;

        return this;
    }

    /** 
     *  @method copyTo
     *  @memberof SQR.Matrix2D.prototype
     *  @param m matrix to copy values to. Can be {SQR.Matrix2D} or {Float32Array}
     *  @description Copies current matrix values to m
     */
    this.copyTo = function(m) {
        a = this.data,b = m.data || m;

        b[0] = a[0],b[1] = a[1],b[2] = a[2];
        b[3] = a[3],b[4] = a[4],b[5] = a[5];
        b[6] = a[6],b[7] = a[7],b[8] = a[8];

        return m;
    }

    /** 
     *  @method copyFrom
     *  @memberof SQR.Matrix2D.prototype
     *  @param m matrix to copy values from. Can be {SQR.Matrix2D} or {Float32Array}
     *  @description Copies values from m into the current matrix
     */
    this.copyFrom = function(m) {
        a = m.data || m,b = this.data;

        b[0] = a[0],b[1] = a[1],b[2] = a[2];
        b[3] = a[3],b[4] = a[4],b[5] = a[5];
        b[6] = a[6],b[7] = a[7],b[8] = a[8];

        return this;
    }

    this.identity();
}

SQR.Matrix2D.__temp = new Float32Array(9);