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