CSS同行間:
你是否是有這樣的感受:哎呀呀,天天就是對着設計圖切頁面,貌似技術沒有獲得實質性地提高啊,或者以爲往後高度有限!css
咱們應該都知道二八法則(巴萊多定律),即任何一組東西中,最重要的只佔其中一小部分,約20%,其他80%的儘管是多數,倒是次要的。若是你有上述的感受,那你就屬於那80%, 一抓一大把,沒有特點的頁面仔。html
CSS門檻低,無需程序基礎或數學邏輯能力,也能作出點自我感受不錯的東西。然而,你本身也應該清楚的,通常你能輕鬆學到的東西,別人也能夠。所以,若是你想擠進那20%的行列,就要學到通常人學不到的深度,學到通常人學不了的東西。天然,是須要更多額外的努力的。若是每次你都比別人努力一點點,何愁不比他人高出幾等。人年輕的時候,貴在堅持!css3
而這裏的CSS矩陣就是展示你與其餘芸芸同行差別的好契機。不少人看到名字就畏懼了,看到奇怪的數學書寫就嚇退了;而你沒有,迎難而上,把搖手機的時間用在理解矩陣上。天然,你就冒尖了一點。相似的,不少其餘CSS方面的東西,你也比別人多深刻學習一點,怎麼可能就是個普通的頁面仔呢?web
所以,從這裏開始,擺脫那80%的行列吧!算法
僞同行間:
雖然都是從事計算機,雖然都是從事互聯網,雖然都是寫代碼的,(聽說)寫JAVA的瞧不起寫JavaScript的,寫JavaScript的瞧不起寫CSS的。這能夠理解,雖然養雞養鴨成爲富翁的不在少數,可是,一說你是農村養雞的,怎麼樣?上海專業的丈母孃們的視線立馬降低60°——被BS了。倒不是由於你是幹農業的,而是「雞」的問題;若是說你是飼養斯里蘭卡藍孔雀的,得,挑剔的丈母孃們說不定就會正臉看看(唷,斯里蘭卡,國外貨;唷,孔雀,高檔貨)。canvas
一樣的,若是你掌握的CSS都是些「砌磚頭」的活(雖然砌磚頭也是大學問),被無視也情理之中。可是,矩陣這個東西,就是扭轉乾坤(網稱「逆襲」)的好東西:CSS中也是有複雜的高檔貨的。再忽悠些「圖形算法、位置計算」之類的詞句,嘿嘿,立馬見解從變成。瀏覽器
矩陣能夠理解爲方陣,只不過,平時方陣裏面站的是人,矩陣中是數值:
→ide
而所謂矩陣的計算,就是兩個方陣的人(能夠想象成古代的方陣士兵)相互衝殺。wordpress
CSS3中的矩陣
CSS3中的矩陣指的是一個方法,書寫爲matrix()
和matrix3d()
,前者是元素2D平面的移動變換(transform),後者則是3D變換。2D變換矩陣爲3*3, 如上面矩陣示意圖;3D變換則是4*4的矩陣。函數
有些迷糊?恩,我也以爲上面講述有些不合時宜。那好,咱們先看看其餘東西,層層漸進——transform
屬性。
具體關於transform
屬性具體內容能夠點擊這裏補個課。稍微熟悉的人都知道,transform中有這麼幾個屬性方法:
.trans_skew { transform: skew(35deg); } .trans_scale { transform:scale(1, 0.5); } .trans_rotate { transform:rotate(45deg); } .trans_translate { transform:translate(10px, 20px); }
斜拉(skew),縮放(scale),旋轉(rotate)以及位移(translate)。
那你有沒有想過,爲何transform:rotate(45deg);
會讓元素旋轉45°, 其後面運做的機理是什麼呢?
下面這張圖能夠解釋上面的疑問:
不管是旋轉仍是拉伸什麼的,本質上都是應用的matrix()
方法實現的(修改matrix()
方法固定幾個值),只是相似於transform:rotate
這種表現形式,咱們更容易理解,記憶與上手。
換句話說,理解transform
中matrix()
矩陣方法有利於透徹理解CSS3的transform
屬性,這就與那80%的也會應用但只知表象的人拉開了差距!
OK,如今上面提到的CSS3矩陣解釋應該說得通了。
雖然題目寫的是「transform
中的Matrix
」,實際上,在CSS3以及HTML5的世界裏,這玩意仍是涉獵蠻廣的,如SVG
以及canvas
.
事實上,關於矩陣,我以前曾經介紹過,是在介紹IE瀏覽器下的Matrix矩陣濾鏡的時候說過,IE的濾鏡矩陣與CSS中的矩陣雖然寫法上差別較大,可是,矩陣計算的原來是一致的。只是以前的介紹主要是IE下的旋轉與縮放,同時也不是很深刻,所以還有有些侷限的。
transform
與座標系統用過transform
旋轉的人能夠發現了,其默認是繞着中心點旋轉的,而這個中心點就是transform-origin
屬性對應的點,也是全部矩陣計算的一個重要依據點(下圖參考自dev.opera.com)。
當咱們經過transform-origin
屬性進行設置的時候,矩陣相關計算也隨之發生改變。反應到實際圖形效果上就是,旋轉拉伸的中心點變了!
舉例來講,若是偶們設置:
-webkit-transform-origin: bottom left;
則,座標中心點就是左下角位置。因而動畫(例如圖片收縮)就是基於圖片的左下角這一點了:
上圖效果能夠點擊這裏查看(Chrome瀏覽器)。
再舉個稍微難理解的例子,咱們若是這樣設置:
transform-origin: 50px 70px;
則,中心點位置有中間移到了距離左側50像素,頂部70像素的地方(參見下圖),而此時的(30, 30)
的座標爲白點所示的位置(這個位置後面會用到)。
仔細看看,是否是很快就理解了哈~~
CSS3 transform
的matrix()
方法寫法以下:
transform: matrix(a,b,c,d,e,f);
嚇住了吧,這多參數,一個巴掌都數不過來。好吧,若是你把a~f
這6個參數想象成女神的名詞,你會以爲,世界不過如此嘛~~
實際上,這6參數,對應的矩陣就是:
注意書寫方向是豎着的。
上面提過,矩陣能夠想象成古代的士兵方陣,要讓其發生變化,只有與另一個士兵陣火拼就能夠了,即便這是個小陣。
反應在這裏就是以下轉換公式:
其中,x
, y
表示轉換元素的全部座標(變量)了。那後面的ax+cy+e
怎麼來的呢?
//zxx:大學時候線性代數知識,懂的人這裏能夠直接跳過
很簡單,3*3矩陣每一行的第1個值與後面1*3的第1個值相乘,第2個值與第2個相乘,第3個與第3個,而後相加,以下圖同色標註:
那ax+cy+e
的意義是什麼?
記住了,ax+cy+e
爲變換後的水平座標,bx+dy+f
表示變換後的垂直位置。
又迷糊了?不急,一個簡單例子就明白了。
假設矩陣參數以下:
transform: matrix(1, 0, 0, 1, 30, 30); /* a=1, b=0, c=0, d=1, e=30, f=30 */
如今,咱們根據這個矩陣偏移元素的中心點,假設是(0, 0)
,即x=0
, y=0
。
因而,變換後的x
座標就是ax+cy+e = 1*0+0*0+30 =30
, y
座標就是bx+dy+f = 0*0+1*0+30 =30
.
因而,中心點座標從(0, 0)
變成了→(30, 30)
。對照上面有個(30, 30)
的白點圖,好好想象下,原來(0,0)
的位置,移到了白點的(30, 30)
處,怎麼樣,是否是往右下方同時偏移了30像素哈!!
實際上transform: matrix(1, 0, 0, 1, 30, 30);
就等同於transform: translate(30px, 30px);
. 注意:translate
,rotate
等方法都是須要單位的,而matrix
方法e, f
參數的單位能夠省略。
一例勝萬語,您能夠狠狠地點擊這裏:matrix(1,0,0,1,30,30)實例demo
在現代瀏覽器下,會有相似下面動圖的效果:
效果只是表象的,我想到了一個更好的idea去表現矩陣究竟是如何變換的,您能夠狠狠地點擊這裏:matrix分解變換演示
爲了提升性能,demo中每一個單元分解成了5px * 5px
的區域。演示分兩步,先是演示每一個單元的位置是如何計算的,接着動畫表現其位置的偏移。
這個demo所作的工做就是把瀏覽器瞬間完成的計算和渲染變成了可控的分步顯示,這樣,你們就能夠很直觀地看出,這個矩陣計算究竟是如何起做用的。下圖爲正在演示過程當中的截圖:
//zxx:因爲默認100毫秒間隔不斷渲染,所以若是你電腦CPU或是瀏覽器hold不住,能夠取消「自動演示」的勾選,而後,點擊左邊的按鈕手動分步查看。
總結
聰明的你可能以及意識到了,尼瑪matrix表現偏移就是:
transform: matrix(與我無關, 哪位, 怎麼不去高考, 打麻將去吧,水平偏移距離, 垂直偏移距離);
你只要關心後面兩個參數就能夠了,至於前面4個參數,是牛是馬,是男是女都沒有關係的。
偏移是matrix效果中最簡單,最容易理解的,所以,上面很詳盡地對此進行展開說明。下面,爲了進一步加深對matrix的理解,會簡單講下matrix矩陣與縮放,旋轉以及拉伸效果。
縮放(scale)
上面的偏移只要關心最後兩個參數,這個縮放也是隻要關心兩個參數。哪兩個呢?
若是你足夠明察秋毫,應該已經知道了,由於上面屢次出現的:
transform: matrix(1, 0, 0, 1, 30, 30);
已經出賣了。
發現沒,matrix(1, 0, 0, 1, 30, 30);
的元素比例與原來同樣,1:1, 而這幾個參數中,有兩個1
, 啊哈哈!沒錯,這兩個1
就是縮放相關的參數。
其中,第一個縮放x
軸,第二個縮放y
軸。
用公式就很明白了,假設比例是s
,則有matrix(s, 0, 0, s, 0, 0);
,因而,套用公式,就有:x' = ax+cy+e = s*x+0*y+0 = s*x;
y' = bx+dy+f = 0*x+s*y+0 = s*y;
也就是matrix(sx, 0, 0, sy, 0, 0);
,等同於scale(sx, sy)
;
好了,至此,無需多說了……
眼見爲實,所以demo仍是要滴,您能夠狠狠地點擊這裏:matrix矩陣與縮放demo
爲了不元素比例放大時候遮蓋上面的文本框以及描述位子,所以,將元素的座標原點遷至了左上角。
旋轉(rotate)
旋轉相比前面兩個要更高級些,要用到(可能勾起學生時代陰影的)三角函數。
方法以及參數使用以下(假設角度爲θ
):
matrix(cosθ,sinθ,-sinθ,cosθ,0,0)
結合矩陣公式,就有:
x' = x*cosθ-y*sinθ+0 = x*cosθ-y*sinθ y' = x*sinθ+y*cosθ+0 = x*sinθ+y*cosθ
這個與IEMatrix濾鏡中的旋轉是有些相似的(M11表示矩陣第1行第1個(參數a),M21表示矩陣第2行第一個(參數b)……):
filter:progid:DXImageTransform.Microsoft.Matrix(M11=cosθ,M21=sinθ,M12=-sinθ,M22=cosθ');
哎呀呀,四個參數,我記不住啊!莫慌,咱們能夠這樣子記憶:
CS-SC:初三-上牀,對稱結構,這下忘不了了吧~~
您能夠狠狠地點擊這裏:transform matrix矩陣與旋轉demo
不過,說句老實話,就旋轉而言,rotate(θdeg)
這種書寫形式要比matrix
簡單多了,首先記憶簡單,其次,無需計算。例如,旋轉30°,前者直接:
transform:rotate(30deg);
而使用matrix
表示則還要計算cos
, sin
值:
transform: matrix(0.866025,0.500000,-0.500000,0.866025,0,0);
拉伸(skew)
拉伸也用到了三角函數,不過是tanθ
,並且,其至於b, c
兩個參數相關,書寫以下(注意y
軸傾斜角度在前):
matrix(1,tan(θy),tan(θx),1,0,0)
套用矩陣公式計算結果爲:
x' = x+y*tan(θx)+0 = x+y*tan(θx) y' = x*tan(θy)+y+0 = x*tan(θy)+y
對應於skew(θx + "deg",θy+ "deg")
這種寫法。
其中,θx
表示x
軸傾斜的角度,θy
表示y
軸,二者並沒有關聯。
仍是靠實例說話吧,您能夠狠狠地點擊這裏:matrix矩陣與拉伸demo
在Chrome下能夠很動態地查看不一樣傾斜角度對應的拉伸的效果:
我想有人會奇怪,既然CSS3 transform中提供了像skew
, rotate
, …
效果,那還須要掌握和熟悉讓人頭大的矩陣方法幹嗎呢?
好問題,確實,對於通常地交互應用,transform
屬性默認提供的些方法是足夠了,可是,一些其餘的效果,若是transform
屬性沒有提供接口方法,那你又該怎麼辦呢?比方說,「鏡像對稱效果」!
沒轍了吧,這是,就只能靠matrix
矩陣了。要知道,matrix矩陣是transform
變換的基礎,能夠應付不少高端的效果,算是一種高級應用技巧吧。掌握了基礎,才能兵來將擋水來土掩啊。
OK,這裏就演示下,如何使用CSS3 transform
matrix
矩陣實現鏡像效果。
這個有點難度,所以,咱們先看demo,您能夠狠狠地點擊這裏:matrix與鏡像對稱效果demo
框框中輸入旋轉的角度值(用來肯定鏡像的對稱軸),而後失去焦點,就會呈現出對應的鏡像對稱效果了:
您能夠在FireFox或是Chrome等瀏覽器上體驗下matrix
實現的鏡像漸變效果。
demo頁面中的一個軸是爲了便於理解我加上的效果,實際上,在鏡像對稱的時候軸是看不見的。
軸圍繞的那個點就是CSS3中transform
變換的中心點,天然,鏡像對稱也不例外。由於該軸永遠通過原點,所以,任意對稱軸均可以用y = k * x
表示。則matrix
表示就是:
matrix((1-k*k) / (1+k*k), 2k / (1 + k*k), 2k / (1 + k*k), (k*k - 1) / (1+k*k), 0, 0)
這個如何獲得的呢?
啊,高中數學來了,就當再高考一次吧,以下圖,已經y=kx
,而且知道點(x, y)座標,求其對稱點(x’, y’)的座標?
很簡單,一是垂直,二是中心點在軸線上,所以有:
(y-y') / (x - x') = -1/ k → ky-ky' = -x+x'
(x + x') / 2 * k = y + y' → kx+kx' = y+y'
很簡單的,把x'
和y'
提出來,就有:
x' = (1-k*k)/(k*k+1) *x + 2k/(k*k+1) *y;
y' = 2k/(k*k+1) *x + (k*k-1)/(k*k+1) *y;
再結合矩陣公式:x' = ax+cy+e;
y' = bx+dy+f;
咱們就能夠獲得:a = (1-k*k)/(k*k+1);
b = 2k/(k*k+1);
c = 2k/(k*k+1);
d = (k*k-1)/(k*k+1);
也就是上面matrix方法中的參數值啦!
下圖爲本身計算的草稿:
3D變換雖然只比2D多了一個D,可是複雜程度不僅多了一個。從二維到三維,是從4到9;而在矩陣裏頭是從3*3變成4*4, 9到16了。
其實,本質上不少東西都與2D一致的,只是複雜度不同而已。這裏就舉一個簡單的3D縮放變換的例子。
對於3D縮放效果,其矩陣以下:
代碼表示就是:
transform: matrix3d(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1)
您能夠狠狠地點擊這裏:matrix3d下的3D比例變換demo
補充於2013-04-24
關於3D變換,能夠參見邪惡的這篇文章:「CSS3 3D transform變換,不過如此!」