CSS動畫,2D和3D模塊


CSS3提供了豐富的動畫類屬性,使我們可以不通過flash甚至JavaScript,就能實現很多動態的效果。它們主要分為三大類:transform(變換),transition(過渡),animation(動畫)。其中transform又分為2D變換和3D變換,它賦予了我們不通過專業設計軟件制作平面或者立體圖形的能力。

 

一  過渡

 

  通過給元素設置transition屬性設置它的過渡效果。過渡實際定義的是元素從一種狀態變成另一種狀態的過程,比如寬度從100px變成300px,背景顏色從red變成orange等等。

 1 div{
 2  width:200px;
 3  height:200px;
 4  background-color:red;
 5  transition-property:width,background-color;
 6     /*該屬性指定需要變換的元素屬性,不同屬性用逗號隔開*/
 7  transition-duration:1s;
 8     /*該屬性指定整個過程花費的時間,如需單獨為每個變化的屬性設置時間,請使用逗號隔開*/
 9  transition-timing-function:ease;
10     /*該屬性設置變化的速度曲線,默認值即是ease,表示慢-快-慢,還有幾個其他的取值:linear,勻速;ease-in,慢-快,ease-out,快-慢,ease-in-out,慢-快-慢,肉眼效果和ease相似*/
11  transition-delay:1s;
12     /*延遲時間*/
13 }  

  元素的屬性設置好以后,需要某些操作觸發了指定屬性的變化才能看到效果,比如:hover,或者JS事件。

  另外,transition實際是一個復合屬性,多個屬性過渡可以簡寫:

1 div{
2  width:200px;
3  height:200px;
4  transition:width 2s 1s,background-color 2s;
5     /*transition-property和transition-duration是必須的,另外兩個是可選的*/
6 }
7 div:hover{
8  width:400px 9 }

  當有多個屬性需要設置過渡,並且持續事件,速度曲線,延遲時間均相同時,你可以如下簡寫:

1 div{
2     /*some code*/
3  transition:all 2s;
4     /*所有發生變化的屬性都設置過渡效果*/
5 }

 

二  動畫

 

  動畫其實和過渡一樣,都是用來給元素設置動態效果的,不同的是,過渡需要人為的觸發才能被執行,而動畫不需要人為觸發。

  在給元素設置動畫之前,我們首先應該創建一個動畫效果,即開始是什么狀態,結束是什么狀態。

1 @keyframes sport{/*通過@keyframs 定義一個動畫,sport是動畫的名稱,可以自定義*/
2  from{ 3  width:200px;
4     }
5  to{
6  width:400px;
7     }
8 /*除了使用from...to的方式,你還可以使用百分比創建更加豐富的動畫過程,0%表示開始時,100%表示結束時*/
9 }

  創建好動畫之后,你就可以為元素設置諸如動畫持續時長,速度曲線,重復次數等屬性了。

 1 div{
 2  animation-name:sport;
 3     /*規定元素需要執行的動畫名稱,即使用@keyframs創建的那個*/
 4  animation-duration:5s;
 5     /*規定動畫完成一個周期所花費的秒或毫秒*/
 6  animation-timing-function:ease;
 7     /*規定動畫的速度曲線,可選值同過渡*/
 8  animation-delay:3s;
 9     /*規定動畫延遲時間*/
10  animation-iteration-count:5;
11     /*規定動畫被播放的次數,infinite表示一直循環播放*/
12  animation-direction:alternate;
13     /*規定動畫是否在下一周期逆向地播放,normal是默認取值,表示不逆向播放,逆向播放一次也會在animation-iteration-count屬性值中減1*/
14  animation-play-state:paused;
15     /*規定動畫是否正在運行或暫停,默認值是running,表示正在運行*/
16  animation-fill-mode:forwards;
17     /*規定動畫結束后元素的狀態,forwards,保持動畫停止時的狀態,backwards,回到開始時的狀態,none,保持默認。一般沒有指定該屬性時,動畫結束后會回到開始時的狀態。不同瀏覽器可能有不同表現*/
18 }

   animation 也是一個復合屬性,可以如下簡寫:

1 div{
2     animation:sport 5s ease 2s infinite alternate forwords;
3 }
4 /* animation-play-state 一般通過偽類或JS來動態的控制動畫的暫停或繼續 */

 

三  2D變換

 

  通過給元素設置 transform 屬性,可以對元素進行2D變換。很多地方把 transform 翻譯成轉換,該單詞在英語中的含義是使改變,使變形。我更傾向於把它翻譯成變換,通過CSS變換,我們可以對元素進行移動、縮放、轉動、拉伸等操作。

 

  1,translate(x,y) 

1 div{
2  transform:translate(50px,100px);
3 }
4 /*div在水平方向基於原位置移動50px,垂直方向移動100px*/

  translate方法接收兩個參數,分別表示在水平和垂直正方向上的偏移量,可以接收負值,表示向反方向偏移。

 

  2,rotate(deg)

1 div{
2  transform:rotate(30deg);
3 }
4 /*順時針方向旋轉元素30度*/

  rotate方法接收一個參數,表示元素旋轉的角度,可以接收負值,表示逆時針方向旋轉。rotate方法實際是通過修改元素的坐標系來達到旋轉元素的目的,比如:

1 div{
2  transform:rotate(45deg) translate(50px,0);
3     /*多屬性復合形式寫法*/
4 }
5 /*元素先旋轉45度,然后向瀏覽器x軸正方向偏下45度的方向移動50px*/

  默認情況下,元素都是以自己的中心點為圓心旋轉,我們可以通過transform-origin屬性修改該參考點。

1 div{
2  width:200px;
3  height:200px;
4  transform:rotate(30deg);
5  transform-origin:0px 0px;/*以左上角為圓點旋轉*/
6     /*取值200px 0px即以右上角為圓點旋轉。改屬性取值也可以是百分比或關鍵字。top,botton,left,right,center*/
7 }

  

  3,scale(x,y)

1 div{
2  transform:scale(2,3);
3 }
4 /*元素寬度放大2倍,高度放大3倍*/

  scale方法接收兩個參數,分別表示元素寬高需要縮放的比例,如果參數介於0到1之間則表示縮小,如果小於0,實際效果相當於翻轉元素,感興趣的朋友可以自行測試,觀察效果。

  

  4,skew(x,y)

1 div{
2  transform:skew(30deg,30deg);
3 }
4 /*元素在水平和垂直方向均傾斜30度*/

  skew方法接收兩個參數,分別表示X軸和Y軸傾斜的角度,如果第二個參數為空,則默認為0,參數為負表示向相反方向傾斜。

 

四  3D變換

 

  要想使元素以3D效果呈現,你需要給元素的父元素添加transform-style屬性

1 .father{
2  transform-style:preserve-3d;
3 }
4 .son{
5     /*some code*/
6 }

  transform-style屬性的默認值是flat,即平面的意思。通過設置其值為preserve-3d即可讓子元素以3D模式呈現。

  事實上,我們是通過配合使用rotate方法,最終實現3D立體效果的。

  我們知道,在2D空間,坐標軸只有x和y兩根軸,而在3D空間,一共有x,y,z三根軸。我們上面講解的rotate方法實際上都是圍繞z軸在旋轉,這也是該方法的默認方式。另外,其實我們還可以通過rotateX(),rotateY(),改變元素默認的旋轉軸向。改變旋轉軸向配合perspective屬性使用效果更佳。

 1 .father{
 2     perspective:500px;
 3     /*perspective屬性取值是一般是一個像素值,設置后可以實現旋轉后元素近大遠小的效果*/
 4 }
 5 .son{
 6     width:200px;
 7     height:200px;
 8     transform:rotateX(45deg);
 9 }
10 /*注意,perspective屬性需要設置在旋轉元素的祖先元素上,通常我們把它設置在其父元素上。*/

  下面是兩個3D立方體的示例代碼:

  HTML部分:

 1 <div class="D3">
 2     <ul>
 3         <li>1</li>
 4         <li>2</li>
 5         <li>3</li>
 6         <li>4</li>
 7         <li>5</li>
 8         <li>6</li>
 9     </ul>
10     <ul>
11         <li>1</li>
12         <li>2</li>
13         <li>3</li>
14         <li>4</li>
15         <li>5</li>
16         <li>6</li>
17     </ul>
18 </div>

  CSS部分:

 1 body{
 2  background-color: #ccc;
 3  perspective: 800px;
 4 }
 5 .D3{
 6  width:550px;
 7  height: 200px;
 8  margin:100px auto;
 9 }
10 @keyframes sport{
11  from{ 12  transform: rotateX(0deg) rotateY(0deg);
13     }
14  to{
15  transform: rotateX(360deg) rotateY(360deg);
16     }
17 } 18 .D3 ul{
19  width: 200px;
20  height: 200px;
21  position: relative;
22  transform-style: preserve-3d;
23  transform: rotateX(0deg) rotateY(0deg);
24  animation: sport 10s linear infinite alternate;
25  display: inline-block;
26  margin-left:50px;
27 }
28 .D3 ul li{
29  list-style: none;
30  width:200px;
31  height: 200px;
32  position: absolute;
33  opacity: 0.3;
34  font-size: 100px;
35  line-height: 200px;
36  text-align: center;
37 }
38 .D3 ul li:nth-child(1){
39  background-color: red;
40  transform:translateZ(100px);
41 }
42 .D3 ul li:nth-child(2){
43  background-color: blue;
44  transform: rotateX(90deg) translateZ(100px);
45 }
46 .D3 ul li:nth-child(3){
47  background-color: yellow;
48  transform: rotateX(180deg) translateZ(100px);
49 }
50 .D3 ul li:nth-child(4){
51  background-color: pink;
52  transform: rotateX(270deg) translateZ(100px);
53 }
54 .D3 ul li:nth-child(5){
55  background-color: purple;
56  transform: rotateY(90deg) translateZ(-100px);
57 }
58 .D3 ul li:nth-child(6){
59  background-color: green;
60  transform: rotateY(90deg) translateZ(100px);
61 }
62 /*還記得嗎?rotate方法是通過改變坐標系來達到旋轉的目的哦!*/

 

五  transform對其他元素的影響

 

  1,提高顯示優先級

  我們知道,在標准文檔流中,如果使用負的margin值可以使一個元素覆蓋在另一個元素上,正常情況下是寫在后面的元素覆蓋前面的。但是設置了transform屬性的元素會覆蓋其他元素。

 1 .top{
 2  width: 100px;
 3  height: 100px;
 4  background-color: red;
 5  transform: rotate(0deg);
 6 }
 7 .bottom{
 8  width: 100px;
 9  height: 100px;
10  background-color: blue;
11  margin-top:-50px;
12 }
13 /*紅色的會覆蓋藍色的div 50px*/

  

  2,改變fixed定位的相對對象

  通常情況下,使用了position:fixed;屬性的元素都會相對瀏覽器窗口定位,不受滾動條的影響。但是當我們給其父元素設置了transform屬性后,這一狀況被改變了。

 1 .father{
 2  width: 500px;
 3  height: 500px;
 4  margin-left: 100px;
 5  margin-top: 100px;
 6  border: 1px solid #000;
 7  transform: rotate(0deg);
 8 }
 9 .son{
10  position: fixed;
11  top: 50px;
12  left:50px;
13  width: 100px;
14  height: 100px;
15  background-color: red;
16 }
17 /*.son不再以瀏覽器窗口作為參考點,而是以其父元素.father作為按參考點了*/

  

  3,改變absolute定位元素的寬度

  以前,如果一個元素設置了絕對定位,並且寬度設置為100%,那么該元素的實際寬度是第一個有定位屬性的祖先元素的寬度,沒有則是body的寬度。現在,如果第一個有定位屬性的祖先元素和絕對定位元素之間,有一個設置了transform屬性的元素,那么絕對定位元素的寬度繼承鏈將在該transform祖先元素處被截斷,最終絕對定位的元素寬度將繼承自transform元素。

 1 .grand{
 2  width: 500px;
 3  height: 500px;
 4  border: 1px solid #000;
 5  position: absolute;
 6 }
 7 .father{
 8  width: 100px;
 9  height: 100px;
10  background-color: red;
11  transform:rotate(0deg);
12 }
13 .son{
14  width: 100%;
15  height: 200px;
16  position: absolute;
17  background-color: yellow;
18 }
19 /*.son的寬度不是500px,而變成了100px*/

  

  寫在最后,transform是CSS3才引入的屬性,不同瀏覽器對它的實現也可能有差異,上面介紹的內容並不能保證在所有瀏覽器上均有相同的表現,具體情況請大家自行測試(我僅在Chrome 76測試)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM