Tips:閲讀提示!!!
- 首先,本文針對的是3D transform變換的學習,所以你需要對 2D transform變換 有一定的瞭解
- 其次,需要説明的是,代碼是一種需要自己不斷實踐的學科,建議各位在開始學習本篇文檔的時候,先創建一個
html頁面來邊讀邊練,
相信這樣,一定會給你留下一個非常直觀且深刻的印象!
本文練習一些公共代碼
鑑於本文貼了不少代碼來演示,所有這裏提前放一個所有演示的公共代碼片段
// 公共DOM元素,後續均為此寫樣式表
// 舞台容器
<div class="stage">
// 變換元素
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
// 樣式兼容的各個瀏覽器屬性頭,有需要的在各自代碼中添加
// 下列測試代碼使用Chorme運行
-webkit- /* Safari 和 Chrome */
-ms- /* IE */
-moz- /* Firefox */
-o- /* Opera */
實現3D變換的基礎 -- 透視(perspective)
當我們步入CSS3動畫殿堂之時,我們一般都會從一些簡單動的東西開始學習,比如元素的位移,旋轉,放大縮小之類的2D transform變換,
那麼如何在一個2D的屏幕上實現3D的變換呢,這裏我們就先需要有一個概念,就是 透視
從一個最簡單的 透視 説起,我們小時候的數學課上,數學老師一定會給我們畫一個立體正方形,能夠在2D平面上看出3D效果就是 透視 的作用
用一張直觀的圖片來説明一下
透視的類型有以下幾種
那麼在CSS3中如何用代碼實現透視呢?
- 主要是通過
perspective屬性來實現定義透視距離 perspective屬性定義3D元素距視圖的距離,以像素計,該屬性允許您改變3D元素查看3D元素的視圖- 透視距離可以這麼理解,如果你的顯示器寬度是
1920px的分辨率,那麼2000px的透視距離就近似於,從顯示器平面開始,一個顯示器寬度的距離 - 默認值是
0px,可以理解為初始位置 - 注意!!!當為元素定義 perspective 屬性時,其子元素會獲得透視效果,而不是元素本身
-
它有兩種寫法,單個元素時候看似效果相同,但是多元素在同一個舞台上呈現時,就會出現問題了
- 第一種,是寫在舞台元素上,定義
perspective屬性 - 第二種,是配合
transform屬性一起,例如:transform: perspective(600px) rotateY(45deg) - 參考下方示例,您可以在自己的demo中測試效果區別,你會發現第二種所有元素都是同一角度的旋轉,
這是因為第一種透視點是.stage中央,第二種透視點是每一個.box中央
// 第一種寫法 .stage { width: 100%; height: 100%; perspective: 1000px; -webkit-perspective: 500px; } .stage .box { width: 100px; height: 100px; margin: 100px 100px; background-color: #55ffff; display: inline-block; transform: rotateY(65deg); -webkit-transform: rotateY(65deg); } // 第二種寫法 .stage { width: 100%; height: 100%; } .stage .box { width: 100px; height: 100px; margin: 100px 100px; background-color: #55ffff; display: inline-block; transform: perspective(1000px) rotateY(65deg); -webkit-transform: perspective(1000px) rotateY(65deg); } - 第一種,是寫在舞台元素上,定義
透視基點位置屬性(perspective-origin)
- 既然我我們有透視距離的概念,那麼這個透視基點的意思就是,我們所看的舞台或者元素的中心
perspective(透視)屬性必須和perspective-origin(透視基點)屬性一同使用-
perspective-origin: x-axis y-axis,xy可以分別是這些值:- left
- right
- center
- length,像素
- %,百分比
- 舉個不恰當的例子,透視基點類似看足球比賽中那個球的位置,因為所有人眼都會盯着場上的足球,你和球的距離理解為透視距離就好,當然這並不恰當,不要在意
- 該屬性必須與
perspective屬性一同使用,而且隻影響3D轉換元素,它可以定義在元素中,並且同perspective屬性一樣,定義在哪裏影響哪裏 - 默認值是
50% 50%,表示 xy 中心位置 -
下面我們利用一個示例來看看,你依舊可以通過修改demo中的參數,看到效果的變化
// 50% 50% 正好是變換元素的中心點,也是默認值 .stage { width: 100%; height: 100%; perspective: 604px; -webkit-perspective: 604px; // 使用百分比 perspective-origin: 50% 50%; -webkit-perspective-origin: 50% 50%; // 使用像素 // perspective-origin: 200px 100px; // -webkit-perspective-origin: 200px 100px; // 使用位置 // perspective-origin: left center; // -webkit-perspective-origin: left center; // 也可以混用 // perspective-origin: 200px 10%; // -webkit-perspective-origin: 200px 10%; } .stage .box { width: 100px; height: 100px; margin: 100px 100px; background-color: #55ffff; display: inline-block; transform: rotateY(65deg); -webkit-transform: rotateY(65deg); }
透視盲區
在我們進行3D變換的時候還會遇到透視盲區的問題,比如一個正方形,旋轉45°之後,正好和你的視線完全平行,那麼這個面你就看不到,這就是視覺盲區
你可以利用下方代碼在自己的demo中查看一下效果
// 我的電腦分辨率是`1920*1080`,透視距離是`604px`
// 如果你看不到效果,可以嘗試修改旋轉角度或透視距離,找一下出現盲區的角度
.stage {
width: 100%;
height: 100%;
perspective: 604px;
-webkit-perspective: 604px
}
.stage .box {
width: 100px;
height: 100px;
margin: 100px 100px;
background-color: #55ffff;
display: inline-block;
transform: rotateY(65deg);
-webkit-transform: rotateY(65deg);
}
實現靜態的3D變換 -- 轉換(transform)
相信在2D變換的學習中對於transform屬性一定不陌生了,它不僅可以進行2D變換,也可以進行3D變換,只不過需要藉助上一個透視的屬性,我們才可以在屏幕中看到變換的效果
先來説明一個三維座標系的概念,通俗點來説,z軸對應垂直方向,x軸對應前後方向,y軸對應左右方向
後續我們所説的繞軸變化,你就可以參考這個圖例,想象一下發生的變換
接下來我們來看看transform支持的變換類型,如果對此您有疑問,可以參考w3school的可測試教程:
-
2D類型
轉換(位移)
translate(x,y)/translateX(x)/translateY(y)
縮放scale(x,y)/scaleX(x)/scaleY(y)
旋轉rotate(angle)/rotateX(angle)/rotateY(angle)
傾斜skew(x-angle,y-angle)/skewX(angle)/skewY(angle)
matrix(),把所有 2D 變換方法組合為一個,可接受六個參數,matrix(scaleX(),skewY(),skewX(),scaleY(),translateX(),translateY()) -
3D類型
轉換(位移)
translate3d(x,y,z)/translateZ(z),主要是垂直距離的位移
縮放scale3d(x,y,z)/scaleZ(z),同樣是垂直距離的縮放
旋轉rotate3d(x,y,z,angle)/rotateX(angle)/rotateY(angle)/rotateZ(angle)
rotateX/rotateY/rotateZ三種函數分別意思是繞着XYZ軸做旋轉運動,angle參數為單位為deg的角度
rotate3d函數定義一個變換,它將元素圍繞固定軸移動而不使其變形,運動量由指定的角度定義,
如果為正,運動將為順時針,如果為負,則為逆時針,想要了解更多可以參考 這篇文檔中的動態示例) 理解
2D變換請參考 本文Tips中的鏈接 或百度教程,下面我們來詳細看下實現靜態3D變換的代碼
.stage {
width: 100%;
height: 100%;
perspective: 500px;
-webkit-perspective: 500px;
perspective-origin: 50% 50%;
-webkit-perspective-origin: 50% 50%;
}
.stage .box {
width: 100px;
height: 100px;
margin: 100px 100px;
background-color: #55ffff;
display: inline-block;
// 這裏表示繞Y軸做旋轉65度的變換
transform: rotate3d(0, 1, 0, 65deg);
-webkit-transform: rotate3d(0, 1, 0, 65deg);
}
轉換基點位置屬性(transform-origin)
transform-origin屬性允許您改變被轉換元素的位置,2D轉換元素能夠改變元素xy軸,3D轉換元素還能改變其z軸-
transform-origin: x-axis y-axis z-axis,這定義了視圖被置於xyz軸的何處,z值只能是length,xy可以分別是這些值:- left
- right
- center
- length,像素
- %,百分比
transform-origin屬性必須和transform屬性一同使用- 默認值是
50% 50% 0,表示轉換基點位於 xy 中心以及 z軸 0 的位置 -
下面我們利用一個示例來看看,你依舊可以通過修改demo中的參數,看到效果的變化
.stage { width: 100%; height: 100%; perspective: 500px; -webkit-perspective: 500px; perspective-origin: 50% 50%; -webkit-perspective-origin: 50% 50%; } .stage .box { width: 100px; height: 100px; margin: 100px 100px; background-color: #55ffff; display: inline-block; transform: rotate3d(0, 1, 0, 65deg); -webkit-transform: rotate3d(0, 1, 0, 65deg); // 表示旋轉元素的基準點在 x 100px y 100px z -900px 位置 // 值類型自由使用,不做過多説明,參考上方透視基點屬性 transform-origin: 100px 100px -900px; -webkit-transform-origin: 100px 100px -900px; }
轉換如何呈現屬性(transform-style)
transform-style屬性規定如何在3D空間中呈現被嵌套的元素transform-style: flat | preserve-3d,flat表示子元素將不保留其3D位置,preserve-3d表示子元素保留其3D位置- 默認值是
flat,不保留3D位置 -
下面用一個不同於上面幾個示例的示例來展示整個屬性的效果,你可以在demo中修改幾個屬性來查看效果
<div class="stage"> <div class="box"> <div class="box-out"> <div class="box-in"></div> </div> </div> </div>.stage { width: 100%; height: 100%; perspective: 1600px; -webkit-perspective: 1600px; } .stage .box { width: 400px; height: 400px; margin: 100px 100px; background-color: #55ffff; transform: rotate3d(0, 1, 0, 65deg); -webkit-transform: rotate3d(0, 1, 0, 65deg); // 這裏會展示3D效果 transform-style: preserve-3d; -webkit-transform-style: preserve-3d; // 不展示3D效果 // transform-style: flat; // -webkit-transform-style: flat; } .stage .box .box-out { width: 90%; height: 90%; background-color: #ffff00; transform: rotate3d(0.5, 1, 0, 85deg); -webkit-transform: rotate3d(0.5, 1, 0, 85deg); } .stage .box .box-out .box-in { width: 150%; height: 150%; background-color: #aaff7f; transform: rotate3d(0.1, 1, 0.5, 85deg); -webkit-transform: rotate3d(0.1, 1, 0.5, 85deg); }
背面是否可見屬性(backface-visibility)
backface-visibility屬性定義當元素不面向屏幕時是否可見backface-visibility: visible | hidden,visible表示背面是可見的,hidden表示背面不可見- 該屬性主要用於不想展示被旋轉元素的背面時使用,通常用於一些翻轉動效,比如爐石的抽卡,就屬於背面可見
-
下面我們可以通過翻拍效果示例來理解一下這個屬性的作用
<div class="stage"> <div class="box"> <div class="box-prev"></div> <div class="box-next"></div> </div> </div>.stage { width: 100%; height: 100%; perspective: 1600px; -webkit-perspective: 1600px; } .box { width: 400px; height: 400px; margin: 100px 100px; position: relative; transition: 0.5s all; transform-style: preserve-3d; -webkit-transform-style: preserve-3d; } .box-prev, .box-next { width: 100%; height: 100%; position: absolute; transition: 0.5s all; backface-visibility: hidden; } .box-prev { background-color: #ffff00; z-index: 1; } .box-next { background-color: #aaff7f; transform: rotateY(180deg); z-index: 0; } .box:hover{ transform: rotateY(180deg); }
做一些簡單的循環動效
學習了上述代碼之後,我們可以做一些簡單的循環動效了,這裏我們用一個簡單的翻書效果來練習,當然還有很多奇思妙想期待你自己去實踐啦!
<div class="stage">
<div class="box">
<div class="box-prev"></div>
<div class="box-midd"></div>
<div class="box-next">
<span></span>
<span></span>
</div>
</div>
</div>
.stage {
width: 100%;
height: 100%;
}
.box {
width: 400px;
height: 400px;
margin: 100px 100px;
position: relative;
transition: 0.5s all;
transform-style: preserve-3d;
}
.box-prev,
.box-midd,
.box-next {
width: 100%;
height: 100%;
position: absolute;
transition: 3s all;
}
.box-prev {
background-color: #ffff9b;
z-index: 2;
}
.box-midd {
background-color: #aaff7f;
z-index: 1;
}
.box-next {
display: flex;
justify-content: space-between;
z-index: 0;
}
.box-next span {
width: 50%;
height: 100%;
}
.box-next span:nth-child(1) {
background-color: #ffff9b;
}
.box-next span:nth-child(2) {
background-color: #aaff7f;
}
.box:hover .box-prev {
transform: perspective(800px) rotateY(-180deg);
transform-origin: perspective(800px) 50% 50% 0;
}
.box:hover .box-midd {
transform: perspective(800px) rotateY(-180deg);
transform-origin: perspective(800px) 50% 50% 0;
}
參考文檔一 ———— 帶你玩轉css3的3D!
參考文檔二 ———— 好吧,CSS3 3D transform變換,不過如此!
參考文檔三 ———— CSS perspective 屬性
參考文檔三 ———— CSS perspective-origin 屬性
參考文檔五 ———— CSS transform 屬性
參考文檔六 ———— CSS transform-origin 屬性
參考文檔七 ———— CSS transform-style 屬性
參考文檔八 ———— CSS backface-visibility 屬性
參考文檔九 ———— CSS3中設置3D變形的transform-style屬性詳解
我是 fx67ll.com,如果您發現本文有什麼錯誤,歡迎在評論區討論指正,感謝您的閲讀!
如果您喜歡這篇文章,歡迎訪問我的 本文github倉庫地址,為我點一顆Star,Thanks~ :)
轉發請註明參考文章地址,非常感謝!!!