給本身出了一道題以下:css
在某個大矩形中心有一個黃色
的矩形,對該黃色矩形進行一系列transform
變換獲得灰色矩形;html
以大矩形中心爲座標原點
,屏幕水平向左爲X 軸正方向
,屏幕垂直向上爲Y 軸正方向
,黃色矩形初始位置中心在座標原點,根據其寬高能夠獲得其初始位置四個頂點的座標initPoints
;css3
那麼求黃色矩形通過一系列變換後新的頂點座標。git
在線地址:newbieyoung.github.io/CSS_learn/t…github
其實無論 CSS3 transform 屬性 有多複雜,都是能夠經過getComputedStyle
直接得到最終變換矩陣的,具體方法實現以下:web
//得到transform屬性對應的矩陣形式
function getTransformMatrix(transform){
var $div = document.createElement('div');
$div.style.visibility = 'hidden';
$div.style.position = 'fixed';
//處理transform屬性的兼容性
var transformProperty = 'transform';
if('transform' in $div.style){
transformProperty='transform'
} else if( 'WebkitTransform' in $div.style ){
transformProperty='webkitTransform'
} else if('MozTransform' in $div.style){
transformProperty='MozTransform'
} else if('OTransform' in $div.style){
transformProperty='OTransform'
}
$div.style[transformProperty] = transform;
document.body.appendChild($div);
var style = window.getComputedStyle($div);
var matrix = style[transformProperty];
document.body.removeChild($div);
return matrix;
}
複製代碼
經過getTransformMatrix
函數能夠得到如下形式的變換矩陣:bash
matrix(a, b, c, d, e, f);
matrix(0.430963, 1.01542, -0.234879, 1.76697, 5, 40)
複製代碼
轉換爲三階矩陣:app
[a, c, e,
b, d, f,
0, 0, 1];
複製代碼
不知道你們想過沒有,明明是2D
變換,轉換爲三階
矩陣幹啥?wordpress
其實這裏是引入了一個齊次座標
的概念,用N+1
維的向量來表示N
維向量;函數
好比在2D
座標系中某個點(x, y)
能夠在邏輯上表示爲(x*w, y*w, w)
,w
即爲新增的那個量。
引入齊次座標的好處在於能夠把縮放
、旋轉
、平移
等變換都統一轉換成矩陣乘法的形式,這樣無論進行多少次變換,均可以表示成矩陣連乘的形式了。
若是某個 2D 座標系中點爲(x, y)
,轉換爲齊次座標(x, y, 1)
,那麼通過上述變換後的新座標爲(nx, ny, nz)
:
nx = a * x + c * y + 1 * e;
ny = b * x + d * y + 1 * f;
nz = 0 + 0 + 1;
複製代碼
再把齊次座標還原,最終座標爲(nx, ny)
。
具體方法實現以下:
//計算矩陣變換後的座標點
function getMatrixPoints(p,matrix){
var mat = matrixAnalyze(matrix);
// var mat3 = [mat[0],mat[2],mat[4],
// mat[1],mat[3],mat[5],
// 0,0,1];
// var mat3 = [a,c,e,
// b,d,f,
// 0,0,1];
// var newX = a * x + c * y + 1 * e;
// var newY = b * x + d * y + 1 * f;
// var newZ = 0 + 0 +1;
//計算變換後點座標
var newX = mat[0] * p.x + mat[2] * p.y + 1 * mat[4];
var newY = mat[1] * p.x + mat[3] * p.y + 1 * mat[5];
var newZ = 0 + 0 +1;
return {x:newX/newZ,y:newY/newZ};
}
複製代碼
已知初始座標initPoints
和變換矩陣matrix
相乘便可獲得matrixPoints
,到這裏我覺得這個題目已經解完了;
直到我嘗試着在大矩形中用紅色
直線把計算獲得的matrixPoints
連起來才發現:新座標鏈接獲得的圖形和 CSS3 transform 變換獲得灰色圖形並不重合
;
這也就意味着上述計算過程有問題
!
在走了很多彎路以後我才意識到一個問題:CSS3 2D transform 座標系和題目中設定的座標系的 Y 軸正方向是相反的
;
題目中設置的座標系 Y 軸正方向是屏幕垂直向上而 CSS3 2D transform 座標系的 Y 軸正方向是屏幕垂直向下。
所以在計算新座標以前,須要對getComputedStyle
獲得的變換矩陣進行鏡像變換
,從而轉換爲題目中設定座標系的變換矩陣,也就是示例中fixedMatrix
,最後計算的新座標爲fixedPoints
。
用藍色
直線繪製出來就能夠看到和灰色圖形徹底重合了。
聊矩陣不聊座標系都是耍流氓!
此外張鑫旭
大神2012
年的這篇文章理解CSS3 transform中的Matrix(矩陣)應該是有比較大問題的。
文中屢次出現方向不明、座標軸錯誤
的座標系,若是有看到建議改下。