这东西在各浏览器的差异性真大,叫人怎么整合与测试啊!
$.require("ready,css",function(){// mass Framework by 司徒正美 var $el = $("#test") var matrix = $el.css("transform","rotate(90deg)").data("matrix",void 0, true) //打印浏览器使用getComputedStyle得到结果 $.log($el.css("transform")) //打印经过$.Matrix处理过的结果 $.log( matrix.get2D() ); //分解原始数值,得到a,b,c,e,tx,ty属性,以及返回一个包含x,y,scaleX,scaleY,skewX,skewY,rotation的对象 matrix.decompose2D(); $.log(matrix.a) $.log(matrix.b) $.log(matrix.c) $.log(matrix.d) $.log(matrix.tx) $.log(matrix.ty); });
下面测试结果
//FF12 matrix(0, 1, -1, 0, 0px, 0px) matrix(0,-1,1,0,0,0) 0 1 -1 0 0 0 //chrome20 matrix(0.0000000000000002220446049250313, 1, -1, 0.0000000000000002220446049250313, 0, 0) matrix(0,-1,1,0,0,0) 0 1 -1 0 0 0 //opera11.62 matrix(0, 1, -1, 0, 0, 0) matrix(0,-1,1,0,0,0) 0 1 -1 0 0 0 //safari5.1.5 matrix(0.0000000000000002220446049250313, 1, -1, 0.0000000000000002220446049250313, 0, 0) matrix(0,-1,1,0,0,0) 0 1 -1 0 0 0
一个放弃的矩阵类:
//http://extremelysatisfactorytotalitarianism.com/blog/?p=1002 //http://someguynameddylan.com/lab/transform-origin-in-internet-explorer.php //优化HTML5应用的体验细节,例如全屏的处理与支持,横屏的响应,图形缩放的流畅性和不失真,点触的响应与拖曳,Websocket的完善 //关于JavaScript中计算精度丢失的问题 http://rockyee.iteye.com/blog/891538 function toFixed(d){ return d > -0.0000001 && d < 0.0000001 ? 0 : /e/.test(d+"") ? d.toFixed(7) : d } function rad(value) { if(isFinite(value)) { return parseFloat(value); } if(~value.indexOf("deg")) {//圆角制。 return parseInt(value,10) * (Math.PI / 180); } else if (~value.indexOf("grad")) {//梯度制。一个直角的100等分之一。一个圆圈相当于400grad。 return parseInt(value,10) * (Math.PI/200); }//弧度制,360=2π return parseFloat(value,10) } var Matrix = $.factory({ init: function(rows,cols){ this.rows = rows || 3; this.cols = cols || 3; this.set.apply(this, [].slice.call(arguments,2)) }, set: function(){//用于设置元素 for(var i = 0, n = this.rows * this.cols; i < n; i++){ this[ Math.floor(i / this.rows) +","+(i % this.rows) ] = parseFloat(arguments[i]) || 0; } return this; }, get: function(){//转变成数组 var array = [], ret = [] for(var key in this){ if(~key.indexOf(",")){ array.push( key ) } } array.sort() ; for(var i = 0; i < array.length; i++){ ret[i] = this[array[i]] } return ret ; }, set2D: function(a,b,c,d,tx,ty){ this.a = this["0,0"] = a * 1 this.b = this["1,0"] = b * 1 this.c = this["0,1"] = c * 1 this.d = this["1,1"] = d * 1 this.tx = this["2,0"] = tx * 1 this.ty = this["2,1"] = ty * 1 this["0,2"] = this["1,2"] = 0 this["2,2"] = 1; return this; }, get2D: function(){ return "matrix("+[ this["0,0"],this["1,0"],this["0,1"],this["1,1"],this["2,0"],this["2,1"] ]+")"; }, cross: function(matrix){ if(this.cols === matrix.rows){ var ret = new Matrix(this.rows, matrix.cols); var n = Math.max(this.rows, matrix.cols) for(var key in ret){ if(key.match(/(\d+),(\d+)/)){ var r = RegExp.$1, c = RegExp.$2 for(var i = 0; i < n; i++ ){ ret[key] += ( (this[r+","+i] || 0) * (matrix[i+","+c]||0 ));//X轴*Y轴 } } } for(key in this){ if(typeof this[key] == "number"){ delete this[key] } } for(key in ret){ if(typeof ret[key] == "number"){ this[key] = toFixed(ret[key]) } } return this }else{ throw "cross error: this.cols !== matrix.rows" } }, //http://www.zweigmedia.com/RealWorld/tutorialsf1/frames3_2.html //http://www.w3.org/TR/SVG/coords.html#RotationDefined //http://www.mathamazement.com/Lessons/Pre-Calculus/08_Matrices-and-Determinants/coordinate-transformation-matrices.html translate: function(tx, ty) { tx = parseFloat(tx) || 0;//沿 x 轴平移每个点的距离。 ty = parseFloat(ty) || 0;//沿 y 轴平移每个点的距离。 var m = (new Matrix()).set2D(1 ,0, 0, 1, tx, ty); this.cross(m) }, translateX: function(tx) { this.translate(tx, 0) }, translateY: function(ty) { this.translate(0, ty) }, scale: function(sx, sy){ sx = isFinite(sx) ? parseFloat(sx) : 1 ; sy = isFinite(sy) ? parseFloat(sy) : 1 ; var m = (new Matrix()).set2D( sx, 0, 0, sy, 0, 0); this.cross(m) }, scaleX: function(sx) { this.scale(sx, 1) }, scaleY: function(sy) { this.scale(1, sy) }, rotate: function(angle, fix){//matrix.rotate(60)==>顺时针转60度 fix = fix === -1 ? fix : 1; angle = rad(angle); var cos = Math.cos(angle); var sin = Math.sin(angle);// a, b, c, d var m = (new Matrix()).set2D( cos,fix * sin , fix * -sin, cos, 0, 0); return this.cross(m) }, skew: function(ax, ay){ var xRad = rad(ax); var yRad; if (ay != null) { yRad = rad(ay) } else { yRad = xRad } var m = (new Matrix()).set2D( 1, Math.tan( xRad ), Math.tan( yRad ), 1, 0, 0); return this.cross(m) }, skewX: function(ax){ return this.skew(ax, 0); }, skewY: function(ay){ this.skew(0, ay); }, // ┌ ┐┌ ┐ // │ a c tx││ M11 -M12 tx│ // │ b d ty││ -M21 M22 tx│ // └ ┘└ ┘ //http://help.adobe.com/zh_CN/FlashPlatform/reference/actionscript/3/flash/geom/Matrix.html //分解原始数值,得到a,b,c,e,tx,ty属性,以及返回一个包含x,y,scaleX,scaleY,skewX,skewY,rotation的对象 decompose2D: function(){ var ret = {} this.a = this["0,0"] this.b = this["1,0"] this.c = this["0,1"] this.d = this["1,1"] ret.x = this.tx = this["2,0"] ret.y = this.ty = this["2,1"] ret.scaleX = Math.sqrt(this.a * this.a + this.b * this.b); ret.scaleY = Math.sqrt(this.c * this.c + this.d * this.d); var skewX = Math.atan2(-this.c, this.d); var skewY = Math.atan2(this.b, this.a); if (skewX == skewY) { ret.rotation = skewY/Matrix.DEG_TO_RAD; if (this.a < 0 && this.d >= 0) { ret.rotation += (ret.rotation <= 0) ? 180 : -180; } ret.skewX = ret.skewY = 0; } else { ret.skewX = skewX/Matrix.DEG_TO_RAD; ret.skewY = skewY/Matrix.DEG_TO_RAD; } return ret; } }); "translateX,translateY,scaleX,scaleY,skewX,skewY".replace($.rword, function(n){ Matrix.prototype[n.toLowerCase()] = Matrix.prototype[n] }); Matrix.DEG_TO_RAD = Math.PI/180;