天天看點

css貝塞爾曲線 多個點_2019 年了,你還不會 CSS 動畫?

(給前端大全加星标,提升前端技能)

作者:前端工匠 公号 / 老姚

今年我面試了很多同學,隻要看到履歷上寫“熟練掌握CSS3”的,我都會問問動畫相關知識。然而我發現:都 2019 年了,還有很多同學不會 

CSS

 動畫。

我經常愛問的一個問題是,實作如下的效果:

css貝塞爾曲線 多個點_2019 年了,你還不會 CSS 動畫?

即,一個小球從向右勻速移動 

200px

,然後移動回來,再移動過去,最後停留在 

200px

 處。

動圖效果如下:

css貝塞爾曲線 多個點_2019 年了,你還不會 CSS 動畫?

就是需求這麼簡單的一個動畫,然而絕大多數人卻不能答對。

不賣關子,我的答案是:

css貝塞爾曲線 多個點_2019 年了,你還不會 CSS 動畫?

大部分面試者說,關于 

CSS

 動畫,也看過一些教程,工作中卻不怎麼使用,是以就忘了。這裡,我準備為對 

CSS

 動畫掌握不深的小夥伴補充一下相關知識。歡迎大佬們拍闆。

正文開始

通過開發者工具可以發現,

animation

(動畫)屬性是 8 個屬性的簡寫。

css貝塞爾曲線 多個點_2019 年了,你還不會 CSS 動畫?

這 8 個屬性具體含義如下:

css貝塞爾曲線 多個點_2019 年了,你還不會 CSS 動畫?

下面我們一個個仔細說明,各個動畫屬性都是用來做什麼的,以及需要注意的地方。

CSS動畫,也稱關鍵幀動畫。通過 

@keyframes

 來定義關鍵幀。幀的概念,想必大家很清楚,比如電影就是一幀幀圖檔在播放,利用圖像在人腦中短時間停留來形成動态效果。

CSS

  動畫也是利用這個原理。不過開發者不需要給出每一幀的定義。隻需要定義一些關鍵的幀即可。因為其餘的幀,浏覽器會根據計時函數插值計算出來。

比如我們一個 

div

 旋轉一圈,隻需要定義開始和結束兩幀即可:

css貝塞爾曲線 多個點_2019 年了,你還不會 CSS 動畫?

其中,

rotate

 是我給這個動畫起的名字,

from

 表示最開始的那一幀,

to

 表示結束時的那一幀。 準确地說,

CSS

 動畫用百分比來刻畫一個動畫周期,

from

 其實是 

0%

 的别稱,

to

 是 

100%

 的别稱。是以關鍵幀 

rotate

 等價于:

css貝塞爾曲線 多個點_2019 年了,你還不會 CSS 動畫?

定義好了關鍵幀後,下來就可以直接用它了:

或者:

通過 animation-name 來指定動畫使用的關鍵幀,這個是必須的。用 JS 來了解的話,相當于:隻有變量聲明是不行的,還需要使用。

另外上述代碼還指定了動畫運作的時間 

animation-duration

 為 

2s

。最後運作效果如下:

css貝塞爾曲線 多個點_2019 年了,你還不會 CSS 動畫?

動圖的效果不是太明顯,方塊在旋轉時,不是勻速的。因為此時刻畫動畫速度的屬性 

animation-timing-function

 預設值是 

ease

,即先快後慢。 下面動圖示範了計時函數屬性一些值的情形:

css貝塞爾曲線 多個點_2019 年了,你還不會 CSS 動畫?

animation-timing-function

 常見值有:

linear

ease

ease-in

ease-out

ease-in-out

。這些值其實都是 

cubic-bezier(n,n,n,n)

 的特例。它們被稱為貝塞爾曲線。除了開發者工具外,《CSS揭秘》作者也寫了的一個線上調試貝塞爾曲線的網站:cubic-bezier.com。貝塞爾曲線這個知識點很有用,

canvas

 裡也有相應的 

API

。可以展開的點其實比較多,這裡隻是初步介紹。

需要提一下,計時函數屬性另外的一個好玩的值是 

steps

 函數,可以用來實作逐幀動畫:

css貝塞爾曲線 多個點_2019 年了,你還不會 CSS 動畫?

計時函數屬性介紹到此,後面一律使用值 

linear

,即表示勻速動畫。回到關鍵幀,我們除了指定開頭和結束位置的關鍵幀(如果不指定 

0%

 和 

100%

,浏覽器會自動推斷),當然也可以指定任意百分比的幀是什麼情況,比如開篇例子的另一種實作:

關鍵幀代碼有備援,可以進一步簡寫:

此時,動畫時長改成了 

6s

,動畫進行到三分之一處時,讓 

div

 位于 

200px

,三分之二回到開始位置,結束時移動到 

200px

 處。

這種是比較直覺的實作方式,有很多面試者一般都會想到這種。

注意 

animation: move 6s linear both;

 聲明中的 

both

。它是屬性 

animation-fill-mode

 的一個值。這個屬性容易被忽略,然而卻是 

CSS

 動畫比較重要的一個屬性。直譯為動畫填充模式,具體說的是什麼事情呢?

@keyframes

 隻是定義了動畫過程中每一幀的值,然而在動畫開始前和動畫結束後,元素改處于什麼狀态呢?

animation-fill-mode

 說的就是這個事情。除了預設值 

none

 外,還有另外 3 個值:

  • forwards,表示,動畫完成後,元素狀态保持為最後一幀的狀态。
  • backwards,表示,有動畫延遲時,動畫開始前,元素狀态保持為第一幀的狀态。
  • both,表示上述二者效果都有。

舉個例子,

div

 從 

100px

 處移動到 

200px

 處的關鍵幀定義為:

設定填充模式為 

forwards

 時,動畫最後停留在 

200px

 處:

css貝塞爾曲線 多個點_2019 年了,你還不會 CSS 動畫?

設定動畫延遲 

1s

 後執行,且填充模式為 

backwards

 時,可以看到動畫在開始前是處于 

100px

 處,動畫結束後回到 

0px

 處:

css貝塞爾曲線 多個點_2019 年了,你還不會 CSS 動畫?

最後設定填充模式為 

both

 的情形:

css貝塞爾曲線 多個點_2019 年了,你還不會 CSS 動畫?

動畫結束後,保持動畫最後一幀的狀态,這個太有用了,比如我們可以實作一個進度條:

效果如下:

css貝塞爾曲線 多個點_2019 年了,你還不會 CSS 動畫?

上面提到了可以使用 

animation-delay

 設定延遲時間。不為大家注意的是,延遲可以為負數。負延遲表示動畫仿佛開始前就已經運作過了那麼長時間。

拿上述進度條為例子,原動畫用了 

2s

 是從 

0%

 加載到 

100%

 的。如果設定延遲為 

-1s

。這動畫會從 

50%

 加載到 

100%

。仿佛已經運作了 

1s

 一樣:

css貝塞爾曲線 多個點_2019 年了,你還不會 CSS 動畫?

CSS 動畫是可以暫停的。屬性 

animation-play-state

 表示動畫播放狀态,預設值 

running

 表示播放, 

paused

 表示暫停:

css貝塞爾曲線 多個點_2019 年了,你還不會 CSS 動畫?

animation-play-state

 這個屬性非常好用,它可以與負延遲一起實作特殊的效果,比如進度條插件:

css貝塞爾曲線 多個點_2019 年了,你還不會 CSS 動畫?

目前為止還有兩個屬性沒有介紹,一個是 

animation-iteration-count

 表示動畫播放次數。它很好懂,隻有一點要注意,無限播放時使用 

infinite

。另一個是播放方向 

animation-direction

,它的意思說指定動畫按照指定順序來播放 

@keyframes

 定義的關鍵幀。其值有:

  • normal 預設值。
  • reverse 表示動畫反向播放。
  • alternate 表示正向和反向交叉進行。
  • alternate-reverse 表示反向和正向交叉進行。

示意如下:

css貝塞爾曲線 多個點_2019 年了,你還不會 CSS 動畫?

animation

 屬性以及 8 個子屬性介紹完了,另外需要說明的是它們與 

background

 及其各子屬性一樣,是支援多個值的,即在同一個元素上應用多個動畫,送給大家一個如意金箍棒:

效果如下:

css貝塞爾曲線 多個點_2019 年了,你還不會 CSS 動畫?

推薦閱讀

(點選标題可跳轉閱讀)

CSS 是如何影響浏覽器元素在文檔中的排列

你未必知道的 49 個 CSS 知識點

20 個讓你效率更高的 CSS 代碼技巧

覺得本文對你有幫助?請分享給更多人

關注「前端大全」加星标,提升前端技能

css貝塞爾曲線 多個點_2019 年了,你還不會 CSS 動畫?

好文章,我在看❤️