CSS3 動畫基礎

註:本文為作者發表於 OpenFoundry 之 CSS3 動畫基礎一文的備份。

在 JSConf.Asia 2013 , Lea Verou 介紹了 CSS in the 4th dimension (影片) ,引發了整個 Web 界對 CSS 動畫的期盼;在 CSS動畫簡介一文也已經把重點整理好了。

以下我們將會介紹主要兩個 CSS3 在動畫的屬性: Transition 與 Animation ,並配合實例來練習這些技術,後面我也會介紹一些不錯的相關開發工具。

Transition

在以往 HTML 元素在兩種外觀之間的變換,只能從一種外觀直接跳到另一種外觀,瀏覽者並沒有辦法感受到這兩種外觀中間平滑的轉換,造成了視覺上的不適。

基本的 transition

而 CSS 為了補足這方面的視覺轉換特效,特別加入 transition 屬性。 一個簡易的動畫效果就是在想要變化的狀態上,加入一個 transition 屬性,而其值為變化需歷時的秒數。

div:hover {
    ...
    transition: 1s;
}

這麼一來, transition 就會自動幫我們補足中間的過場動畫。例如我們希望上面的例子能平順地轉換,歷時一秒:

我們也可以讓高度以外的屬性有動畫效果,例如顏色:

transition 屬性詳解

transition 屬性其實跟 fontbackground 屬性一樣是簡寫屬性,它是以下四個屬性的總和:

  • transition-property: 要做變換的 CSS 屬性
  • transition-duration: 變換需要的時間,單位為 sms
  • transition-delay: 延遲多久後開始變換,單位為 sms
  • transition-timing-function: 稱為 Timing Funciton ,用名稱來定義變換時的加速度。

這些屬性可以分開寫,也可以將它們的值同時寫在 transition 屬性裡;唯一要注意的是 transition-durationtransition-delay 的值寫在一起時有前述的順序關係。前面例子中的 transition: 1s ,其 1s 即為 transition-duration 的值。

transition-property 可使用 transition 的屬性

不是所有 CSS 屬性都可以使用 transition ,可以參考這篇 CSS animated properties 得知有哪些屬性可以使用 transition

transition 預設是對所有可套用的屬性做轉場效果,也就是關鍵字 all ;但其實也可以只針對某個屬性做 transition 變化,其他屬性則維持原來的直接變化。

針對不同屬性同時做 transition

如果希望對兩個以上的屬性做 transition ,可是又不希望影響其他屬性時,可以用逗號 , 將要做 transition 的屬性分隔開來。

transition-delay 延遲變換

有時候我們需要先變換一個屬性,再變換另一個屬性,這時候就需要對後者加入一個延遲時間;它需要加在原先我們定義好的歷時時間之後。

transition-timing-function Timing Funciton

Timing Funciton 包含數種模式,下圖可以看出它們的加速度曲線。

  • linear: 匀速
  • ease: 急加速後減速 (預設值)
  • ease-in: 加速
  • ease-out: 减速
  • ease-in-out: 較平緩的 ease
  • cubic-bezier: 自定義速度模式

cubic-bezier 函式

利用貝茲曲線函式來定義加速曲線,可以直接使用線上工具 cubic-bezier() 來找出需要的數值。

雙向的 transition

Transition 的效果只會作用在有加入 transition 屬性的那個狀態,一旦要回復至原來的狀態時,就會失去 Transition 的平順效果了。這時我們需要對原先的狀態,也加入 transition

Transition 的限制

transition 的開始和結束都必須是具體數值;例如以下的 CSS 屬性值之間是無法被計算的,就無法使用 transition

  • height: auto (不確定的值) 至 height: 100px (具體數值)
  • display: nonedisplay: block
  • background: url(foo.jpg)background: url(bar.jpg)

另外 transition 需要事件來觸發它的動作,所以沒辦法在一進頁面自動產生效果。所以如果不透過 JavaScript 事件處理的話,就只能配合與事件有關的 Pseudo Classes (偽類別,即 :hover:focus 等) 來呈現效果了。

搭配 jQuery

如果搭配 jQuery 等可以操作 DOM 元素的 library ,我們就可以做更複雜的操作。

瀏覽器支援

目前包含 IE 10+ 的主流瀏覽器都已經支援 transition ,可參考 Can I use

Animation

雖然 transition 屬性簡單易用,但也有上述的侷限。因此就有了 animation 這個屬性來彌補其不足。

基本的 Animation

最基本的 animation 要指定動畫持續的時間,還有動畫的名稱。

div:hover {
  animation: 1s fat;
}

而動畫的定義則是用 @keyframes 這個屬性,例如:

@keyframes fat {
  0% { width: 100px; }
  50% { width: 150px; }
  100% { width: 200px; }
}

@keyframes 中可以定義多個狀態,範圍可從 0%100% 。另外 0% 可寫成 from100% 可寫成 to ,其他狀態還是使用數字百分比。

animation 屬性詳解

animation 屬性和 transition 屬性一樣,都是簡寫屬性。它代表以下屬性的總和:

  • animation-name: 動畫名稱
  • animation-duration: 播放一次動畫需要的時間,單位為 sms
  • animation-timing-function: 動畫的加速度曲線
  • animation-delay: 延遲多久後啟始動畫
  • animation-iteration-count: 動畫播放次數,可用 infinite
  • animation-direction: 動畫播放方向
  • animation-fill-mode: 指定動畫播放前後的狀態
  • animation-play-state: 指定動畫播放或暫停

其中 animation-durationanimation-timing-functionanimation-delay 可參考上面 transition 相似屬性的介紹。

animation-iteration-count 播放次數

預設 animationtransition 一樣只會動作一次,但我們可以加入數字來指定動畫效果播放的次數。

或是以 infinite 這個關鍵字來無限次播放。

animation-direction 播放方向

所謂的播放方向是指從動畫效果 0% 到 100% 的方向,同時也是預設的 normal 值。可供設定的值如下:

  • normal :每次播放都是從 0% 至 100%
  • reverse :每次播放都是從 100% 至 0%
  • alternate :播放兩次以上的話,會從 0% 至 100% ,再從 100% 回到 0% ,以此類推
  • alternate-reverse :跟 alternate 相反,會先從 100% 開始播放

animation-direction: reverse

animation-direction: alternate

animation-direction: alternate-reverse

animation-fill-mode 動畫播放前後的狀態

如果想要控制動畫播放完後的最終狀態,可以用 animation-fill-mode 屬性,它可設定的值如下:

  • none :回到未播放動畫效果前的狀態
  • forwards :停在動畫的最後一個狀態上
  • backwards :停在動畫的第一個狀態上 (實測不出來)
  • both :視 animation-direction 來決定停在哪一個狀態上。

註: backwards 這個值我在 Chrome 和 Firefox 都試不出來。

animation-play-state 指定動畫播放或暫停

animation-play-state 有兩個屬性值: runningpaused ,其中 running 是預設值。

這個屬性必須獨立定義,無法被放在 animation 屬性裡。

瀏覽器支援

animation 屬性目前在 IE 10+ 以上主流瀏覽器都可以執行,但採用 Webkit 引擎的瀏覽器必須加上 -webkit- 前綴字串。

div:hover {
  -webkit-animation: 1s name;
  animation: 1s name;
}

@-webkit-keyframes name {
    ...
}

@keyframes name {
    ...
}

實例

接下來我們用 Animation 搭配 Transform 來做簡單的旋轉動畫。 Transform 是用來讓 HTML 元素變形的屬性,雖然跟動畫沒有直接的關係,但它是可以套用動畫效果的。這邊我不打算詳細介紹它,只會用到旋轉的效果。

它的語法如下:

div {
    transform: rotate(θ);
    transform-origin: x y;
}

rotate(θ) 是指讓指定元素以參考點為中心軸 2D 旋轉 θ 度, transform-origin 會將 (x, y) 設為參考點。當我們把 transform: rotate(θ) 放到 @keyframes 中時, animation 就會改變 θ 值來做出動畫效果。

以下模擬簡單的太陽、地球、月亮的週期變化。

更酷的範例參考:

開發工具

CSS 3.0 Maker

CSS 3.0 Marker 可以讓我們調整 CSS3 相關屬性的參數,並預覽效果。確認後就可以產生對應的 CSS 碼,套用到專案上。

Animate.css

Animate.css 這個 CSS framework 提供很多組已經定義好動畫效果的 CSS class ,讓我們可以直接套在 HTML 元素上,或是搭配 jQuery 來操作 class 來產生動畫效果。

Animate Mixin for Compass/SASS

Animate Mixin for Compass/SASS 提供了一組很棒的 CSS3 Animation mixins ,讓我們可以直接套用。它其實就是從 Animation.css 移植過來的。

AniJS

AniJS 是一個宣告式的 CSS 動畫 library ,它讓我們可以在 HTML 元素中加入一個 data-anijs 屬性,並用敘述式來定義動作事件、動畫效果、以及要作用在哪個元素上。要特別注意的是,它也必須搭配 Animation.css 使用。


CSS

2014-06-03 10:28 +0800