CSS 怎樣寫一個動畫(從基礎動畫到3d動畫)

貴飛發表於2019-03-12

以前看過許多教學視訊,大部分講師都是講個大概,然後就開始無厘頭的灌輸知識了。直到我後來看到一位優秀講師的視訊,他的講課模式是第一堂課展示成果。這樣下來,當我看到最終效果,我就有心思去不斷學習這個東西了。

今天我就效仿這位講師的模式,話不多說,上效果~~

1. 簡單的漸變動畫

CSS 怎樣寫一個動畫(從基礎動畫到3d動畫)

2. 稍複雜的關鍵幀動畫

CSS 怎樣寫一個動畫(從基礎動畫到3d動畫)

3. 結合transform 實現3d動畫效果

CSS 怎樣寫一個動畫(從基礎動畫到3d動畫)

看起來還行,學起來也非常容易。

那我們們就一步一步來玩把~~

transition

transition css3 的一大亮點,他常用的大概有以下一些屬性:

大致程式碼如下,省略部分程式碼:

button {
  ...
  background-color: red;
  transition-property: opacity, background-color, border-radius; /* 列表以逗號分隔 */
  transition-duration: 0.5s;
  transition-timing-function: ease; /* 預設速度效果 */
  transition-delay: 1s;
  ...
}
button:hover {
  ...
  opacity: 0.3;  background-color: #fff000;
  border-radius: 100px;
  ...
}複製程式碼
當然,這樣寫起來有些麻煩,當然你可以簡化:

button { 
 background-color: red; 
 transition: opacity  0.5s 1s ease, background-color  0.5s 1s ease, border-radius  0.5s 1s ease; 
}複製程式碼

以上程式碼每個逗號隔開4個引數,分別為 CSS 屬性、過渡時間、停頓開始時間、速度曲線。 看起來好像還有點麻煩誒:

button {
  ...  
  background-color: red;  
  transition: all 0.5s 1s ease;
  ...
}複製程式碼

這樣看起來是不是簡單多了呢?因為在大部分情況下,我們動畫的多種效果一般是同時進行,同時消失的,如果時間不同會變成怎樣的一個效果嘞?

transition: opacity  0.5s 1s ease, background-color  1.5s 2s linear, border-radius  0.5s cubic-bezier(0.215, 0.610, 0.355, 1);複製程式碼

CSS 怎樣寫一個動畫(從基礎動畫到3d動畫)

所以因此我們可以用一個all便把所有相同效果的css屬性代替啦~

CSS 怎樣寫一個動畫(從基礎動畫到3d動畫)

嘻嘻,這樣是不是又好看,程式碼還簡潔呢?

對於 transition-timing-function 這裡給大家推薦一個很好用的網站,可以隨意除錯你想要的貝塞爾速度曲線,點選GO!檢視效果。複製最上面的程式碼,就可以使用到你的程式碼啦~

點選這裡: 我也要去看看效果!

CSS 怎樣寫一個動畫(從基礎動畫到3d動畫)

animation + @keyframes

animation 才是css3動畫的一個進階,他配合@keyframes,可以實現更加複雜的你想要的動畫行為。
  • animation-name  --規定需要繫結到選擇器的 keyframe 名稱
  • animation-duration  --規定完成動畫所花費的時間,以秒或毫秒計
  • animation-timing-function  --規定動畫的速度曲線
  • animation-delay  --規定在動畫開始之前的延遲
  • animation-iteration-count  --規定動畫應該播放的次數
  • animation-direction  --規定是否應該輪流反向播放動畫
  • animation-play-state  -- paused|running  屬性規定動畫正在執行還是暫停
一個一個寫還是會略顯複雜,這裡就直接最終程式碼效果啦~

button{
  animation: ani 5s 2s infinite ease;
}

@keyframes ani {
  20%{    opacity: 0.3;  }
  40%{    border-radius: 100px;  }
  60%{    background-color: #fff000;  }
}複製程式碼

這裡的keyframes就像是你宣告瞭一個動畫函式,ani就是你的函式名。animation就是去這個button中去執行函式。5個引數分別代表 動畫函式名、過渡時間、停頓開始時間、動畫的次數(infinite代表無限)、速度曲線。

CSS 怎樣寫一個動畫(從基礎動畫到3d動畫)


animation+transform 3d動畫

終於到達最激動人心的時刻了。前面的簡單動畫可能大部分人都會,不過3d動畫可能還是有少數人使用的,它涉及一些3d思想,可能對一些童鞋們較為抽象。不過今天我們們就一點點的來學。其實也很簡單~~

話不多說,我們們要實現一個正方體,當然是需要6個平面嘛?(emmmm 這不廢話,幼兒園就會了);

老闆,給我來六個花花綠綠的div!

<p>客觀,您要的div:</p>
<div class="aniBox">  
  <div class="ani1"></div> 
  <div class="ani2"></div>
  <div class="ani3"></div>
  <div class="ani4"></div>
  <div class="ani5"></div>
  <div class="ani6"></div>
</div>

.aniBox {
  width: 220px;
  height: 220px;
}
.aniBox>div {
  width: 100%;
  height: 100%;
}
.ani1 {
  background: #4879dc;
}
.ani2 {
  background: #3bd168;
}
.ani3 {
  background: #e31653;
}
.ani4 {
  background: #1ed3eb;
}
.ani5 {
  background: #e9c80f;
}
.ani6 {
  background: #821fd3;
}複製程式碼

好嘞客官,這是您的div,我給您放到一個大div裝好了~~

這裡是效果圖。。。。

CSS 怎樣寫一個動畫(從基礎動畫到3d動畫)

???

emmmm 老闆,都從袋子出來了,給我包好~~

.aniBox {
  position: relative;
  width: 220px;
  height: 220px;
}
.aniBox>div {
  position: absolute;
  width: 100%;
  height: 100%;
}複製程式碼

CSS 怎樣寫一個動畫(從基礎動畫到3d動畫)

好了,6個div都放到一起啦,開始搞6個面嘍;用transform來旋轉位移它。

CSS 怎樣寫一個動畫(從基礎動畫到3d動畫)

中間的紅色,你可以想象成文件流的平面。現在想要將第一個面向前移動div一半的距離:

.ani1 {
  background: #4879dc;
  transform: translateZ(110px) /*前*/
}複製程式碼

CSS 怎樣寫一個動畫(從基礎動畫到3d動畫)

咦 好像沒什麼變化哎,我明明把 #4879dc CSS 怎樣寫一個動畫(從基礎動畫到3d動畫) 顏色的移動到最前面的位置了呀?經過研究,最後我找到了一個屬性transform-style: preserve-3d,這個屬性規定如何在 3D 空間中呈現被巢狀的元素。必須設定在父元素身上,並且父元素有轉換(就是有變形),並且子元素也得有轉換(變形)才能看得到效果。

  • transform-style: flat  --子元素將不保留其 3D 位置 
  • transform-style: preserve-3d  --子元素將保留其 3D 位置

┗|`O′|┛ 嗷~~ 這樣就懂啦:

.aniBox {
  position: relative;
  transform-style: preserve-3d;
  width: 220px;
  height: 220px;
}複製程式碼

CSS 怎樣寫一個動畫(從基礎動畫到3d動畫)

哈哈哈,效果出來了。

好的! 開始其他的五個面~~~

.ani2 {
  background: #3bd168;
  transform: translateZ(-110px)  /*後*/
}
.ani3 {
  background: #e31653;
  transform: rotateY(90deg) translateZ(110px)  /*右*/
}
.ani4 {
  background: #1ed3eb;
  transform: rotateY(-90deg) translateZ(110px)  /*左*/
}
.ani5 {
  background: #e9c80f;
  transform: rotateX(90deg) translateZ(110px)  /*上*/
}
.ani6 {
  background: #821fd3;
  transform: rotateX(-90deg) translateZ(110px)  /*下*/
}複製程式碼

咦,好像被擋住了看不出什麼效果誒~~~ 算了 我們們直接在控制檯玩把:

CSS 怎樣寫一個動畫(從基礎動畫到3d動畫)

哈哈,成功了,看起來有效果了,好了 我們們給他加上動畫把~~

.aniBox {
  position: relative;
  margin: 30px auto;
  transform-style: preserve-3d;
  width: 220px;
  height: 220px;
  animation: box-3d 5s infinite;
}
@keyframes box-3d {
  100% {
    transform: rotateX(360deg) rotateZ(-720deg)
     /* 讓他的結束角度 都為360的整數倍,這樣他就可以看起來無縫銜接 */  
  }
}複製程式碼

CSS 怎樣寫一個動畫(從基礎動畫到3d動畫)

咦,這個動畫好像先快後慢誒?加個linear把 這樣就看起來均勻了:

.aniBox {
  animation: box-3d 5s infinite linear;
}複製程式碼

CSS 怎樣寫一個動畫(從基礎動畫到3d動畫)

本來以為已經完工了,可是總覺得有點不對勁。網上找了找,嗷~~還差一個近大遠小的效果!

  • perspective  --屬性定義 3D 元素距檢視的距離,以畫素計。該屬性允許您改變 3D 元素檢視 3D 元素的檢視。當為元素定義 perspective 屬性時,其子元素會獲得透視效果,而不是元素本身。

emmmm 網上的說法好難理解。我自己用自己的想法給大家解釋一下。

我把perspective看作一個房屋從中間到人面前的距離。(額~~還是不懂,算了,上圖把!)

CSS 怎樣寫一個動畫(從基礎動畫到3d動畫)

就是這個正方體,你可以當作你的房間大小,而 perspective 你可以當作這個 紅面與面ABCD 的距離。

既然是房間,那就需要包裝一下這個立方體咯~:

<div class="perBox">
      <div class="aniBox">
        <div class="ani1"></div>
        <div class="ani2"></div>
        <div class="ani3"></div>
        <div class="ani4"></div>
        <div class="ani5"></div>
        <div class="ani6"></div>
      </div>
</div>

.perBox {  perspective: 800px;}複製程式碼

CSS 怎樣寫一個動畫(從基礎動畫到3d動畫)

是不是立體了好多呢????

什麼 看起來沒啥效果???

這好辦,你想想,加入一個杯子放在一間屋子的最中間,而你站在房屋的窗玻璃處,是不是房屋越小,你看著越具體? 好的 我們們把房屋弄小一點把!

.perBox {  perspective: 400px;}複製程式碼

CSS 怎樣寫一個動畫(從基礎動畫到3d動畫)

哦吼吼~~夠立體了把! ?

什麼你想看這個盒子內部? 這個div的寬為220px,一半也就是110px;

那麼,只要我們們小於110px,就能看裡面了把?  試試來~~

.perBox {  perspective: 100px;}複製程式碼

CSS 怎樣寫一個動畫(從基礎動畫到3d動畫)

啊哈哈哈,有沒有暈?有沒有顯示卡燃燒的感覺!!!?

燃燒你的GPU!

我們們的動畫也就講到這啦,下來我們們看看perspective這玩意的相容性:

CSS 怎樣寫一個動畫(從基礎動畫到3d動畫)

哦no~  可怕 。

附加 幾個好玩的 demo:

github.com/evelope/CSS…

github.com/evelope/My-…

相關文章