Yijen's blog

關於部落格
繪圖 | 食記 | Web前端技術 | HTML | CSS | JavaScript 研究
  • 320473

    累積人氣

  • 1

    今日人氣

    0

    訂閱人氣

CSS動畫(css @keyframes + animation) 練習與進階實作

定義好了,那麼該如何使用呢? @keyframes 要搭配的語法叫做 animation

HTML
<div class="window"></div>
CSS
.window {
    width: 50px;
    height: 50px;
    background-color: #000000;

    /* Point */
    animation-name: bigger;
    animation-duration: 12s;
}

設定動畫名稱,動畫過程 0~100% 要花12秒的時間去完成

Demo

 

範例:滾動球

接下來的範例就要一次加入比較多一點東西了

<div class="box">
    <div class="ball"></div>
</div>
CSS
@keyframes go {
    from {
        left: 0;
        transform: rotate(0deg);
    }
    to {
        left: 100%;
        transform: rotate(2160deg);
    }
}
.box {
    border-bottom: 5px solid #DDDDDD;
}
.ball {
    width: 50px;
    height: 50px;
    line-height: 50px;
    box-shadow: 15px 15px 20px 10px orange inset;
    text-align: center;
    background-color: #ffc836;
    border-radius: 50%;
    top: 0;
    position: absolute;
    cursor: pointer;
}
.ball.go {
    animation-name: go;
    animation-duration: 4s;

    /* Point */
    animation-fill-mode: forwards;
}

Demo

請 click 橘色球以展示動畫

B

這裡用到了一個新的屬性叫做 animation-fill-mode: forwards 用處在於,我們規範了當這個動畫結束之後,它會停在結尾的影格。(若沒設此參數,球滾完之後會瞬移至原位)

CSS Syntax

此屬性完整可用的值在此列表

animation-fill-mode: none|forwards|backwards|both|initial|inherit;

重複的動畫

animation-iteration-count

意思就是我們想重複播放動畫,可以控制它要作幾次。那麼我們就拿上例來修改吧,距離縮小一半,一次的移動是去了再回來,我們一共讓球滾三次 XDDD

CSS
@keyframes go_and_back {
    0% {
        left: 0;
        transform: rotate(0deg);
    }
    50% {
        left: 100%;
        transform: rotate(1080deg);
    }
    100% {
        left: 0;
        transform: rotate(0deg);
    }
}
.ball2.go {
    animation-name: go_and_back;
    animation-duration: 1.5s;
    
    /* Point */
    animation-iteration-count: 3;
}

Demo

請 click Poke Ball(?) 以展示動畫,它將會跑3次

P

無限loop的動畫

有的時候,你也會想要它的效果是一直不斷的循環的 :)

HTML
<div class="rainbow"></div>
CSS
@keyframes colorful {
     0% { background-color: #FF0000; } /* 紅 */
    14% { background-color: #FF7F00; } /* 橙 */
    28% { background-color: #FFFF00; } /* 黃 */
    43% { background-color: #00BC3F; } /* 綠 */
    57% { background-color: #0068FF; } /* 藍 */
    82% { background-color: #7A00E5; } /* 靛 */
   100% { background-color: #D300C9; } /* 紫 */
}
.bridge {
    animation-name: colorful;
    animation-duration: 7s;

    /* Point */
    animation-iteration-count: infinite;
    animation-direction: alternate;
}

Demo

 

此例我們延用了上例所教的 animation-iteration-count 屬性;
但這次,不是給數字,而是給予 infinite 的值,如此一來,它的動畫就會一直loop下去 :D

那另外一個又是做甚麼用的

animation-direction: alternate;

如果你仔細看這個範例,彩虹的顏色,第一次是 紅橙黃綠藍靛紫 → 這樣變化的;但第二次播放時,它反過來了!紫靛藍綠黃橙紅 →,而這個結果就是 animation-direction: alternate 的作用了,奇數次 play(1,3,5) 是 0% → 100%, 偶數次 play(2,4,6) 是 100% → 0%

它的兄弟參數則是 alternate-reverse,作用是反過來的,第1,3,5次是反向播,第2,4,6次是正向播。
當然如果你沒有設置這個參數,也就是預設值的話,它就會 0-100%, 0-100%, 0-100%, 每一次都是紅橙黃綠藍靛紫了(但100%瞬移到0%比較不好看)

小結

CSS Animation 除了可以控制播放次數,也可以控制動畫執行的方向

CSS Animation-timing-function

接著這個範例要複雜得多,就是控制 CSS動畫的加速模式,預設值是 ease

CSS Syntax

animation-timing-function: linear|ease|ease-in|ease-out|ease-in-out|step-start|step-end|steps(int,start|end)|cubic-bezier(n,n,n,n)|initial|inherit;

我們一樣用神奇寶貝球滾動比賽來練習這個屬性 :D

首先練習幾個標準的加速方式

  • linear
  • ease(default)
  • ease-in
  • ease-out
  • ease-in-out

HTML

<div class="poke_ball p1">linear</div>
<div class="poke_ball p2">ease</div>
<div class="poke_ball p3">ease-in</div>
<div class="poke_ball p4">ease-out</div>
<div class="poke_ball p5">ease-in-out</div>

CSS

@keyframes gogo {
    from {
        left: 0;
        transform: rotate(0deg);
    }
    to {
        left: 560px;
        transform: rotate(1440deg);
    }
}
.poke_ball {
    width: 70px;
    height: 70px;
    border-radius: 50%;

    /* Point */
    position: relative;
    left: 0;
}
.poke_ball.go {
    animation-name: gogo;
    animation-duration: 2s;
    animation-fill-mode: forwards;
}
.poke_ball.p1.go { animation-timing-function: linear; }
.poke_ball.p2.go { animation-timing-function: ease; }
.poke_ball.p3.go { animation-timing-function: ease-in; }
.poke_ball.p4.go { animation-timing-function: ease-out; }
.poke_ball.p5.go { animation-timing-function: ease-in-out; }

Demo

linear
ease
ease-in
ease-out
ease-in-out

當然,以上的5種加速方式,也可以透過 cubic-bezier(n,n,n,n) 函數來定義,有興趣深入研究的人可以至這裡

動畫延遲

animation-delay

代表這個動畫要延遲多久才開始,使用的單位是數字(秒),預設值是0(馬上開始)

完整CSS3動畫定義與縮寫法

以上介紹了CSS3動畫如何定義,以及它如何被使用。然而和大多數屬性一樣,它有標準的寫法也有簡易的寫法,請參考下例。

/* 自訂動畫 */
@keyframes move {
    from { left: 0; }
    to { left: 300px; }
}
/* 逐一定義動畫屬性 */
.box {
    animation-name: move;
    animation-duration: 2s;
    animation-timing-function: ease;
    animation-delay: 1s;
    animation-iteration-count: infinite;
    animation-direction: normal;
}
/* 或是牢記順序,簡寫一次定義 */
.box { animation: move 2s ease 2s infinite normal; }

CSS animation 語法

animation: name duration timing-function delay iteration-count direction;

CSS動畫的條件觸發

以上大致上說明了所有 @keyframes 以及 animation 的定義及如何使用。接下來要補充的是在實務上我們如何精確操作我們所寫好的CSS3動畫

CSS動畫的使用大概會有幾種類型

  1. 主動型:頁面一載入就主動播放
  2. 延遲型:同上,但可能要等動一下子才執行
  3. 互動型:當使用者對頁面的元素作了某些事件(event)後,動畫才被觸發(trigger)
    • :hover, :active, :target 等 CSS pseudo class dom 狀態改變時
    • dom element class/rel attr 變化時(通常搭配 javascript 來操作)

如同版主上面寫的幾個範例,css animation 都是定義在一個 .class 底下,意謂著該元素一開始是沒有任何動畫的,然後再透過 javascript(jQuery) 經由使用者手動加上 class 好讓 css animation 可以順利觸發。

Sample

HTML


<div class="ball"></div>


<div class="ball ani"></div>

CSS

.ball {
    /* 定義 ball 的外觀 */
}
.ball.ani {
    /* 定義 CSS animation */
    animation: move 2s ease 4s 1 normal;
}

JS

$(".button").on("click", function(){
    $(".ball").addClass("ani");
});

browser capabilities

依慣例,也要來寫一下各大瀏覽器對 @keyframes 與 animation 的支援程度

  • IE10+
  • Chrome
  • Safari 4+
  • Firefox
  • Opera

最新版本的 browser 幾乎皆可使用 css animation 了,若您想支援較舊版本的瀏覽器可以在語句前方撰寫 prefix -webkit- for chrome/safari, -moz- for firefox or -o- for opera

詳細的支援內容請見caniuse.com查詢

References
相簿設定
標籤設定
相簿狀態