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

你可以戳這裡插卡演示demo

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

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

1. 簡單的漸變動畫

2. 稍複雜的關鍵幀動畫

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

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

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

transition

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

  • transition-property --規定設置過渡效果的 CSS 屬性的名稱
  • transition-duration --規定完成過渡效果需要多少秒或毫秒
  • transition-timing-function --規定速度效果的速度曲線
  • transition-delay --定義過渡效果何時開始

大致代碼如下,省略部分代碼:

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;
...
}

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

button {
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);
}

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

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

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

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

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代表無限)、速度曲線。

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裝好了~~

這裡是效果圖。。。。

???

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

.aniBox {
position: relative;
width: 220px;
height: 220px;
}
.aniBox>div {
position: absolute;
width: 100%;
height: 100%;
}

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

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

.ani1 {
background: #4879dc;
transform: translateZ(110px) /*前*/
}

咦 好像沒什麼變化哎,我明明把 #4879dc

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

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

.aniBox {
position: relative;
transform-style: preserve-3d;
width: 220px;
height: 220px;
}

哈哈哈,效果出來了。

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

.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) /*下*/
}

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

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

.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的整數倍,這樣他就可以看起來無縫銜接 */
}
}

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

.aniBox {
animation: box-3d 5s infinite linear;
}

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

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

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

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

就是這個正方體,你可以當作你的房間大小,而 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;}

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

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

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

.perBox { perspective: 400px;}

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

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

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

.perBox { perspective: 100px;}

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

燃燒你的GPU!

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


推薦閱讀:
相關文章