1 /** 2 * Hilo 3 * Copyright 2015 alibaba.com 4 * Licensed under the MIT License 5 */ 6 7 /** 8 * @language=en 9 * @class Matrix class is a transforming matrix, which declare how points in one coordinate maped to another coordinate. 10 * @param {Number} a The value affects pixel positioning alongside the x axis when Scale or rotate images. 11 * @param {Number} b The value affects pixel positioning alongside the y axis when rotate or skew images. 12 * @param {Number} c The value affects pixel positioning alongside the x axis when rotate or skew images. 13 * @param {Number} d The value affects pixel positioning alongside the y axis when Scale or rotate images. 14 * @param {Number} tx The distance to move every point alongside the x axis. 15 * @param {Number} ty The distance to move every point alongside the y axis. 16 * @module hilo/geom/Matrix 17 * @requires hilo/core/Class 18 */ 19 var Matrix = Class.create(/** @lends Matrix.prototype */{ 20 constructor: function(a, b, c, d, tx, ty){ 21 this.a = a; 22 this.b = b; 23 this.c = c; 24 this.d = d; 25 this.tx = tx; 26 this.ty = ty; 27 }, 28 29 /** 30 * @language=en 31 * Link a Matrix to current Matrix, in order to make geometry effects on these two composed more effective. 32 * @param {Matrix} mtx Matrix that link to the source matrix. 33 * @returns {Matrix} A Matrix Object. 34 */ 35 concat: function(mtx){ 36 var args = arguments, 37 a = this.a, b = this.b, c = this.c, d = this.d, 38 tx = this.tx, ty = this.ty; 39 40 if(args.length >= 6){ 41 var ma = args[0], mb = args[1], mc = args[2], 42 md = args[3], mx = args[4], my = args[5]; 43 }else{ 44 ma = mtx.a; 45 mb = mtx.b; 46 mc = mtx.c; 47 md = mtx.d; 48 mx = mtx.tx; 49 my = mtx.ty; 50 } 51 52 this.a = a * ma + b * mc; 53 this.b = a * mb + b * md; 54 this.c = c * ma + d * mc; 55 this.d = c * mb + d * md; 56 this.tx = tx * ma + ty * mc + mx; 57 this.ty = tx * mb + ty * md + my; 58 return this; 59 }, 60 61 /** 62 * @language=en 63 * Rotate the Matrix Object. 64 * @param {Number} angle The angle to rotate. 65 * @returns {Matrix} A Matrix object. 66 */ 67 rotate: function(angle){ 68 var sin = Math.sin(angle), cos = Math.cos(angle), 69 a = this.a, b = this.b, c = this.c, d = this.d, 70 tx = this.tx, ty = this.ty; 71 72 this.a = a * cos - b * sin; 73 this.b = a * sin + b * cos; 74 this.c = c * cos - d * sin; 75 this.d = c * sin + d * cos; 76 this.tx = tx * cos - ty * sin; 77 this.ty = tx * sin + ty * cos; 78 return this; 79 }, 80 81 /** 82 * @language=en 83 * Scale the Matrix. 84 * @param {Number} sx The value to multiply those object scale alongside the x axis. 85 * @param {Number} sy The value to multiply those object scale alongside the y axis. 86 * @returns {Matrix} A Matrix object. 87 */ 88 scale: function(sx, sy){ 89 this.a *= sx; 90 this.d *= sy; 91 this.c *= sx; 92 this.b *= sy; 93 this.tx *= sx; 94 this.ty *= sy; 95 return this; 96 }, 97 98 /** 99 * @language=en 100 * Translate the Matrix alongside x axis and y axis by dx and dy. 101 * @param {Number} dx Translate Matrix alongside the x axis to the right (measured in px). 102 * @param {Number} dy Translate Matrix alongside the y axis to the right (measured in px). 103 * @returns {Matrix} A Matrix object. 104 */ 105 translate: function(dx, dy){ 106 this.tx += dx; 107 this.ty += dy; 108 return this; 109 }, 110 111 /** 112 * @language=en 113 * Set each Matrix property a value to trigger null transform. The Matrix after applying identity matrix transformation will be exactly the same as original. 114 * @returns {Matrix} A Matrix object. 115 */ 116 identity: function(){ 117 this.a = this.d = 1; 118 this.b = this.c = this.tx = this.ty = 0; 119 return this; 120 }, 121 122 /** 123 * @language=en 124 * Apply an invert transformation of original Matrix. Using this invert transformation, you can reset a Matrix to a state before it had been apply some Matrix. 125 * @returns {Matrix} A Matrix object. 126 */ 127 invert: function(){ 128 var a = this.a; 129 var b = this.b; 130 var c = this.c; 131 var d = this.d; 132 var tx = this.tx; 133 var i = a * d - b * c; 134 135 this.a = d / i; 136 this.b = -b / i; 137 this.c = -c / i; 138 this.d = a / i; 139 this.tx = (c * this.ty - d * tx) / i; 140 this.ty = -(a * this.ty - b * tx) / i; 141 return this; 142 }, 143 144 /** 145 * @language=en 146 * Return the result after apply a Matrix displaying transform on the point. 147 * @param {Object} point Point need to transform. 148 * @param {Boolean} round Whether ceil the coordinate values of the point. 149 * @param {Boolean} returnNew Whether return a new point. 150 * @returns {Object} 由应用矩阵转换所产生的点。 151 */ 152 transformPoint: function(point, round, returnNew){ 153 var x = point.x * this.a + point.y * this.c + this.tx, 154 y = point.x * this.b + point.y * this.d + this.ty; 155 156 if(round){ 157 x = x + 0.5 >> 0; 158 y = y + 0.5 >> 0; 159 } 160 if(returnNew) return {x:x, y:y}; 161 point.x = x; 162 point.y = y; 163 return point; 164 } 165 166 }); 167