UNPKG

jquery-flapper

Version:

A split-flap (Solari) display for numbers and words using jQuery

336 lines (299 loc) 8.23 kB
/////////////////////////////////////////////////////// // Matrix /////////////////////////////////////////////////////// (function($, window, document, undefined) { /** * Matrix object for creating matrices relevant for 2d Transformations * @var Object */ if (typeof($.matrix) == 'undefined') { $.extend({ matrix: {} }); } var $m = $.matrix; $.extend( $m, { /** * A 2-value vector * @param Number x * @param Number y * @constructor */ V2: function(x, y){ if ($.isArray(arguments[0])) { this.elements = arguments[0].slice(0, 2); } else { this.elements = [x, y]; } this.length = 2; }, /** * A 2-value vector * @param Number x * @param Number y * @param Number z * @constructor */ V3: function(x, y, z){ if ($.isArray(arguments[0])) { this.elements = arguments[0].slice(0, 3); } else { this.elements = [x, y, z]; } this.length = 3; }, /** * A 2x2 Matrix, useful for 2D-transformations without translations * @param Number mn * @constructor */ M2x2: function(m11, m12, m21, m22) { if ($.isArray(arguments[0])) { this.elements = arguments[0].slice(0, 4); } else { this.elements = Array.prototype.slice.call(arguments).slice(0, 4); } this.rows = 2; this.cols = 2; }, /** * A 3x3 Matrix, useful for 3D-transformations without translations * @param Number mn * @constructor */ M3x3: function(m11, m12, m13, m21, m22, m23, m31, m32, m33) { if ($.isArray(arguments[0])) { this.elements = arguments[0].slice(0, 9); } else { this.elements = Array.prototype.slice.call(arguments).slice(0, 9); } this.rows = 3; this.cols = 3; } }); /** generic matrix prototype */ var Matrix = { /** * Return a specific element from the matrix * @param Number row where 1 is the 0th row * @param Number col where 1 is the 0th column * @return Number */ e: function(row, col) { var rows = this.rows, cols = this.cols; // return 0 on nonsense rows and columns if (row > rows || col > rows || row < 1 || col < 1) { return 0; } return this.elements[(row - 1) * cols + col - 1]; }, /** * Taken from Zoomooz * https://github.com/jaukia/zoomooz/blob/c7a37b9a65a06ba730bd66391bbd6fe8e55d3a49/js/jquery.zoomooz.js */ decompose: function() { var a = this.e(1, 1), b = this.e(2, 1), c = this.e(1, 2), d = this.e(2, 2), e = this.e(1, 3), f = this.e(2, 3); // In case the matrix can't be decomposed if (Math.abs(a * d - b * c) < 0.01) { return { rotate: 0 + 'deg', skewX: 0 + 'deg', scaleX: 1, scaleY: 1, translateX: 0 + 'px', translateY: 0 + 'px' }; } // Translate is easy var tx = e, ty = f; // factor out the X scale var sx = Math.sqrt(a * a + b * b); a = a/sx; b = b/sx; // factor out the skew var k = a * c + b * d; c -= a * k; d -= b * k; // factor out the Y scale var sy = Math.sqrt(c * c + d * d); c = c / sy; d = d / sy; k = k / sy; // account for negative scale if ((a * d - b * c) < 0.0) { a = -a; b = -b; //c = -c; // accomplishes nothing to negate it //d = -d; // accomplishes nothing to negate it sx = -sx; //sy = -sy //Scale Y shouldn't ever be negated } // calculate the rotation angle and skew angle var rad2deg = $.angle.radianToDegree; var r = rad2deg(Math.atan2(b, a)); k = rad2deg(Math.atan(k)); return { rotate: r + 'deg', skewX: k + 'deg', scaleX: sx, scaleY: sy, translateX: tx + 'px', translateY: ty + 'px' }; } }; /** Extend all of the matrix types with the same prototype */ $.extend($m.M2x2.prototype, Matrix, { toM3x3: function() { var a = this.elements; return new $m.M3x3( a[0], a[1], 0, a[2], a[3], 0, 0, 0, 1 ); }, /** * Multiply a 2x2 matrix by a similar matrix or a vector * @param M2x2 | V2 matrix * @return M2x2 | V2 */ x: function(matrix) { var isVector = typeof(matrix.rows) === 'undefined'; // Ensure the right-sized matrix if (!isVector && matrix.rows == 3) { return this.toM3x3().x(matrix); } var a = this.elements, b = matrix.elements; if (isVector && b.length == 2) { // b is actually a vector return new $m.V2( a[0] * b[0] + a[1] * b[1], a[2] * b[0] + a[3] * b[1] ); } else if (b.length == a.length) { // b is a 2x2 matrix return new $m.M2x2( a[0] * b[0] + a[1] * b[2], a[0] * b[1] + a[1] * b[3], a[2] * b[0] + a[3] * b[2], a[2] * b[1] + a[3] * b[3] ); } return false; // fail }, /** * Generates an inverse of the current matrix * @param void * @return M2x2 * @link http://www.dr-lex.be/random/matrix_inv.html */ inverse: function() { var d = 1/this.determinant(), a = this.elements; return new $m.M2x2( d * a[3], d * -a[1], d * -a[2], d * a[0] ); }, /** * Calculates the determinant of the current matrix * @param void * @return Number * @link http://www.dr-lex.be/random/matrix_inv.html */ determinant: function() { var a = this.elements; return a[0] * a[3] - a[1] * a[2]; } }); $.extend($m.M3x3.prototype, Matrix, { /** * Multiply a 3x3 matrix by a similar matrix or a vector * @param M3x3 | V3 matrix * @return M3x3 | V3 */ x: function(matrix) { var isVector = typeof(matrix.rows) === 'undefined'; // Ensure the right-sized matrix if (!isVector && matrix.rows < 3) { matrix = matrix.toM3x3(); } var a = this.elements, b = matrix.elements; if (isVector && b.length == 3) { // b is actually a vector return new $m.V3( a[0] * b[0] + a[1] * b[1] + a[2] * b[2], a[3] * b[0] + a[4] * b[1] + a[5] * b[2], a[6] * b[0] + a[7] * b[1] + a[8] * b[2] ); } else if (b.length == a.length) { // b is a 3x3 matrix return new $m.M3x3( a[0] * b[0] + a[1] * b[3] + a[2] * b[6], a[0] * b[1] + a[1] * b[4] + a[2] * b[7], a[0] * b[2] + a[1] * b[5] + a[2] * b[8], a[3] * b[0] + a[4] * b[3] + a[5] * b[6], a[3] * b[1] + a[4] * b[4] + a[5] * b[7], a[3] * b[2] + a[4] * b[5] + a[5] * b[8], a[6] * b[0] + a[7] * b[3] + a[8] * b[6], a[6] * b[1] + a[7] * b[4] + a[8] * b[7], a[6] * b[2] + a[7] * b[5] + a[8] * b[8] ); } return false; // fail }, /** * Generates an inverse of the current matrix * @param void * @return M3x3 * @link http://www.dr-lex.be/random/matrix_inv.html */ inverse: function() { var d = 1/this.determinant(), a = this.elements; return new $m.M3x3( d * ( a[8] * a[4] - a[7] * a[5]), d * (-(a[8] * a[1] - a[7] * a[2])), d * ( a[5] * a[1] - a[4] * a[2]), d * (-(a[8] * a[3] - a[6] * a[5])), d * ( a[8] * a[0] - a[6] * a[2]), d * (-(a[5] * a[0] - a[3] * a[2])), d * ( a[7] * a[3] - a[6] * a[4]), d * (-(a[7] * a[0] - a[6] * a[1])), d * ( a[4] * a[0] - a[3] * a[1]) ); }, /** * Calculates the determinant of the current matrix * @param void * @return Number * @link http://www.dr-lex.be/random/matrix_inv.html */ determinant: function() { var a = this.elements; return a[0] * (a[8] * a[4] - a[7] * a[5]) - a[3] * (a[8] * a[1] - a[7] * a[2]) + a[6] * (a[5] * a[1] - a[4] * a[2]); } }); /** generic vector prototype */ var Vector = { /** * Return a specific element from the vector * @param Number i where 1 is the 0th value * @return Number */ e: function(i) { return this.elements[i - 1]; } }; /** Extend all of the vector types with the same prototype */ $.extend($m.V2.prototype, Vector); $.extend($m.V3.prototype, Vector); })(jQuery, this, this.document);