本文主要是總結了筆者在學習3D transform所收穫的經驗,但願經過筆者認爲合理的知識點安排,可以讓你們少走彎路,本文並不涉及2D transform,想了解相關知識的讀者能夠google查閱相關資料。但願看完以後可以有所收穫,不正確地方,也但願你們不吝指教。css
在剛接觸透視這個詞語的時候,能夠說大腦是一片空白。到底透視是個什麼概念?爲何給元素設置了perspective屬性,元素就能表現出3D空間?這事還得從繪畫提及。html
有一種現象,因爲咱們從小就己經習慣了,也就從不以爲奇怪,那就是:一樣規格的電線杆原本是同樣高的,但在路上看起來,卻近高遠低;一樣型號的汽車本應是同樣大小的,但在路上看起來卻近大遠小;全部的茶杯、水桶底原本都是平的,但咱們時常看到的倒是不一樣的弧線;火車的兩條路軌原本都是同樣寬的, 但咱們時常看到的倒是兩條路軌向前延伸時,會愈來愈窄乃至合攏成一點等。這種視覺現象就是透視現象,總結來講就是:前端
咱們都知道現實世界是3D的,經過光線的直線傳播最後在視網膜呈現的是平面圖像,可是這種圖像卻富有立體空間感,以致於不讓咱們撞到牆,掉到河裏去。能夠說人眼看到的畫面都是透視圖。而咱們若是想要在平面的紙上,表現出這種變化,表現出如咱們視覺所反映出的、富有立體空間感的景物,簡單的辦法就是:固定你的眼睛位置,隔着透明玻璃窗將你所見的景物的形狀依樣描在玻璃上,這描下來的圖形就會較準確地反映這種現象,就存在着客觀的透視規律。所以,「透視」的含義就是:透過(假設的)透明平面去觀察景物,研究物體在立體空間中的形態變化,即「透而視之」,用這種觀察方法,能夠在只有兩度空間的透明平面上錄畫出具備三度空間特徵的景物圖形。這個圖形叫透視圖,最先研究透視的畫家,就是採用這種辦法來作的,透過總結透視圖中的規律得出繪畫透視圖科學的方法,咱們稱之爲透視學。因此說只要你在二維平面採用透視學中的方法,畫出知足透視學的圖畫。就能欺騙人的眼睛,讓圖畫富有立體空間感。以下圖所示css3
在透視圖中有不少專業的術語,瞭解他們可讓咱們更加容易理解css 3D transform。bash
視點:就是畫者眼睛的位置。wordpress
中視線:由視點做出的射向景物的任何一條直線均爲視線,其中引向正前方的視線爲中視線,中視線始終垂直於畫面。咱們能夠把畫面當成是屏幕,perspective屬性值就是中視線的長度。函數
主點:中視線與視平線的交點(也叫心點).學習
滅點(消失點 Vanish Point):透視圖中,滅點是一個很重要的概念。在透視圖中相互平行的直線延長會相交於一點,這點就是滅點,也叫消失點(Vanish Point)。根絕透視圖滅點的數量能夠分爲一點透視,兩點透視,三點透視。perspective-origin就是定義滅點位置。動畫
更多關於透視的基礎概念,但願你們自行google畢竟咱們的重點仍是專一於前端。google
在瞭解透視以前,首先要先了解座標軸。3D變形與2D變形最大的不一樣就在於其參考的座標軸不一樣。2D變形的座標軸是平面的,只存在x軸和y軸,而3D變形的座標軸則是x、y、z三條軸組成的立體空間,x軸正向、y軸正向、z軸正向分別朝向右、下和屏幕外。
面向用戶的是z軸,垂直方向是Y軸,水平是X軸。rotateX, rotateY, rotateZ三個方法就是將元素沿着相應的軸進行旋轉。
在瞭解了一些基本的概念以後咱們開始真正進入3D transform的世界。3D變形涉及的屬性主要是transform-origin、transform、transform-style、perspective、perspective-origin、backface-visibility。
Value: none | <number>
Initial: none
Inherited: no
複製代碼
我並不想直接引用規範裏的介紹來講明perspective屬性。簡單來講就是設置了perspective屬性的元素,該元素就具備立體空間的表現能力。不過僅對該元素的子元素有效,元素自己並不具備立體空間表現能力.perspective值定義了中視線的長度,直觀說法就是用戶眼睛到屏幕的距離,官方說法就是z=0的平面和用戶之間的距離,每個3d元素z>0則越大,z<0則越小,3d效果的強烈程度隨着perspective值得增大而減少,當perspective值爲none,小於或等於0不存在 3d變形。
See the Pen no-perspective by joker (@sponia-joker) on CodePen.
建議在進行3d transform時候,採用上面的html結構。舞臺元素,容器元素,變形元素這樣可讓模型保持簡單並且容易理解。在上面demo中,咱們將子元素沿Y軸旋轉了45deg,可是頁面並無表現出咱們期待的效果,實際效果是變形元素的寬度縮小。這是由於咱們並無給父元素設置perspective屬性,元素不具有立體空間的表現能力,最終表現的是元素沿Y軸旋轉以後再屏幕上的投影,因此寬度會縮小。但咱們打開註釋後,就會是咱們期待的效果。你們能夠在codepen上手動實踐下。
perspective
屬性有兩種書寫形式,一種用在舞臺元素上(動畫元素們的共同父輩元素);第二種就是用在當前變形元素上,與transform的其餘屬性寫在一塊兒。以下所示
See the Pen perspective-function by joker (@sponia-joker) on CodePen.
最後的效果和在父元素上設置perspective屬性是如出一轍。但兩個屬性仍是有很大區別,之因此上面效果是同樣,是由於舞臺上只有一個元素,若是有多個元素就會表現出差別。
See the Pen perspective-vs-perspective-function by joker (@sponia-joker) on CodePen.
顯然當具備多個元素時候,perspective和perspective()函數具備不一樣表現效果。主要是由於在父元素上設置perspective屬性,全部子元素具備相同的視點,而配合transform使用的perspective函數每一個元素都擁有各自不一樣的視點。能夠理解成1我的看 vs 5我的看。更加難以想象的是但設置perspective爲100px時,給父元素設置perspective屬性的demo中,倒數第二個元素會消失,這裏讀者能夠仔細思考下,若是想不明白能夠評論留言。
總結來講就是perspective賦予了元素3d空間展現的能力,能夠說:無透視,不成3D。更多關於perspective屬性的說明,強烈建議讀者去規範和MDN瞭解。
value:flat | preserve-3d
Initial:flat
Inherited:no
複製代碼
Transform-style屬性定義了嵌套元素如何在3D空間進行渲染,當設置爲flat時,元素全部子元素都被渲染在元素所在的2D平面,所以,圍繞X軸或Y軸旋轉元素,將致使位於正或負Z位置的子元素出如今元素的平面上,而不是在元素的前面或後面。若是transform-style值爲preserve-3d,那麼這種扁平化不會被執行,子元素會在3D空間中保持本身的位置。 元素默認會保持扁平化,又由於該屬性沒法繼承,所以爲了在3D空間中保存元素的層次結構須要在層次結構中的每一個祖先元素都設置transform-style值爲preserve-3d.因爲transform-style只會影響元素的子元素,因此層次結構中的葉子節點不須要設置。 通常咱們都是設置transform-style屬性值爲preserve-3d,爲了演示二者的不一樣,能夠經過點擊codepen中的按鈕交替顯示
See the Pen transform-style by joker (@sponia-joker) on CodePen.
value:x-axis y-axis
Initial:50% 50%
Inherited:no
複製代碼
perspective-origin屬性比較簡單,他設置視點x,y軸座標。簡單來講就是決定了咱們看實物的角度。更詳細說明能夠參考
css-tricks有關該屬性的介紹。
value:visible | hidden
Initial:visible
Inherited:no
複製代碼
「backface-visibility」屬性決定轉換後的元素的「背面」是否對用戶可見。就比如一枚硬幣,當咱們沿Y軸旋轉180deg時候,此時是背面朝向咱們,backface-visibility就是用來設置背面是否可見。backface-visibility常常用來實現一些翻轉效果
See the Pen perspect-visibility by joker (@sponia-joker) on CodePen.