今天在微博上看到@過氣網紅一絲 的一篇微博,codepen上貼出了twitter點贊那個動畫效果的源碼,地址 http://codepen.io/yisi/pen/LpXVJb 。我看了下效果很好看,源碼也很簡單,涉及到css3一些簡單的動畫,現在來介紹一下這個動畫所用到的一些技術。
先上效果圖,為了能看得清楚我把動畫時間間隔設置的大了一些。

把源碼貼出來:沒用到js,只用到了html以及css。
html代碼如下
<h1>Twitter heart button animation</h1> <input type="checkbox" name="" id="btn" /> <label class="btn-love" for="btn"></label> <a href="http://codepen.io/chrisgannon/pen/NGLKWO" target="_blank">The SVG version</a>
css代碼如下
1 body {
2 text-align: center;
3 }
4
5 h1 {
6 text-align: center;
7 color: #555;
8 font-weight: normal;
9 }
10
11 #btn {
12 position: absolute;
13 left: -100%;
14 top: -100%;
15 opacity: 0;
16 z-index: -1;
17 }
18
19 .btn-love {
20 position: absolute;
21 z-index: -1;
22 left: 0;
23 right: 0;
24 top: 0;
25 bottom: 0;
26 margin: auto;
27 height: 100%;
28 width: 100%;
29 cursor: pointer;
30 }
31 .btn-love:after {
32 content: "";
33 position: absolute;
34 left: 0;
35 right: 0;
36 top: 100px;
37 margin: 0 auto;
38 background: url(https://abs.twimg.com/a/1446862637/img/t1/web_heart_animation.png) 0 0 no-repeat;
39 background-size: 2900%;
40 height: 100px;
41 width: 100px;
42 }
43
44 #btn:checked + .btn-love:after {
45 -webkit-animation: heart-burst steps(28) .8s 1 both;
46 animation: heart-burst steps(28) .8s 1 both;
47 }
48
49 @-webkit-keyframes heart-burst {
50 0% {
51 background-position: left;
52 }
53 100% {
54 background-position: right;
55 }
56 }
57
58 @keyframes heart-burst {
59 0% {
60 background-position: left;
61 }
62 100% {
63 background-position: right;
64 }
65 }
css前面的代碼也很好懂,我就從31行處開始說吧。這就是給前面對應的class為”btn-love“的label標簽設置其背景圖片。可以看到背景圖片加的是一個鏈接,這個鏈接后的背景圖片就是下面這個長圖。

看到這里大家也能猜到,就是用個長圖設置開始顯示的位置和結束時的位置,並設置其變化的時間,一幀一幀的播放,來模擬一個動畫效果。
#btn:checked + .btn-love:after {
-webkit-animation: heart-burst steps(28) .8s 1 both;
animation: heart-burst steps(28) .8s 1 both;
}
:checked 是css3里用來匹配所有選中的 input 元素,這個應該並沒有什么疑問。
再看大括號里面是個動畫效果用到了css3里面的 animation屬性,這個屬性是一個簡寫屬性,用來設置以下的幾個動畫屬性的。
animation-name:規定需要綁定到選擇器的keyframe名稱。
animation-duration:規定完成動畫所花費的時間,以秒或者毫秒計算。
animation-timing-function:規定動畫的速度曲線。其值可取 ease| linear | ease-in | ease-out | ease-in-out | step-start | step-end | steps([, [ start | end ] ]?) | cubic-bezier(x1, y1, x2, y2)
animation-delay:規定在動畫開始之前的延遲。
animation-iteration-count:規定動畫應該播放的次數。
animation-direction:規定是否應該輪流反向播放動畫。
animation-play-state:屬性規定動畫正在運行還是暫停。
animation-fill-mode:規定動畫在播放前與播放完畢,其動畫效果是否可見。
括號里面一共設置了5個值。
第一個值設置的是animation-name。heart-burst就是該動畫所設置的動畫名。
第二個值設置的是animation-timing-function。steps(28)是什么意思呢?正因為上述動畫並不是線性的,而是類似於一幀一幀的圖片播放,所以就要引入step()這個函數,下面詳細說下這個函數以及這個屬性的具體用法。
animation-timing-function這個屬性可以取以下的幾個值。
ease:動畫緩慢開始,接着加速,最后減慢,默認值;
linear:動畫從頭到尾的速度是相同的;
ease-in:以低速開始;
ease-out:以低速結束;
ease-in-out:動畫以低速開始和結束;
step函數指定了一個階躍函數
第一個參數指定了時間函數中的間隔數量(必須是大於零正整數)。將動畫分成不同的步驟。
第二個參數是可選的,接受 start 和 end 兩個值,指定在每個間隔的起點或是終點發生階躍變化,默認為 end。
step-start等同於steps(1,start),動畫分成一步,動畫執行時為開始左側端點的部分為開始;
step-end等同於steps(1,end):動畫分成一步,動畫執行時以結尾端點為開始,默認值為end。
並且animation-timing-function這個屬性是針對於每一幀和每一幀動畫之間的設定,並不是整個@keyframes,並且並不等同與@keyframes里設置的關鍵幀。
還以當前這個例子舉例。可以看到下面的代碼,是直接從0%變換到100%的,這塊要慎用!一般默認都是從0%~100%。
@keyframes heart-burst { 0% { background-position: left; } 100% { background-position: right; } }
若給0%與100%其中再加上任意一個狀態,我們來看一下效果就變成了如下動圖(為了觀察明顯,依舊延長了動畫時間)

你會發現動畫就出現了問題。animation-timing-function是針對兩個關鍵幀之間的,慎重設置間隔,否則動畫可能會出問題。
第三個值按照簡寫的順序的話應該是animation-delay?其實並不是,這里應該是animation-duration。在animation里只設置一個以秒或者毫秒的值時,將其值默認為animation-duration的值。若設置兩個值時,則會按照先給animation-duration后animation-delay的順序賦給相應值。所以0.8s是設置完成整個動畫一共多少時間。我們可以嘗試將這個0.8s的值設置更大,看到的是動畫變慢,而不是動畫設置延遲變大,從而驗證了我的說法。
第四個值是給animation-iteration-count設置值。所以設置的1是設置動畫循環的次數,若改為2則可以看到動畫在一遍播放結束之后會播放第二遍。
第五個值是給animation-fill-mode設置值。animation-fill-mode屬性一共有4個值,分別如下。
none:不改變默認行為。
forwards:當動畫完成后,保持最后一個屬性值(在最后一個關鍵幀中定義)。
backwards:在 animation-delay 所指定的一段時間內,在動畫顯示之前,應用開始屬性值(在第一個關鍵幀中定義)。
both:向前和向后填充模式都被應用。
可以看到上面設置的是both,如果我們將both取消掉的時候可以看到如下的動畫。 (!!!這里字體大小修改了好多遍還是不知道什么原因總是調整不過來,所以先將就看吧。忙完手中其他事再來好好探討一番!!!)

可以看到其並不保持點贊后的“紅心”狀態,完成動畫后立即恢復到動畫初始幀。所以我們可以得出來both設置的目的是在動畫開始和結束后維持其動畫所在的那一幀。
這個動畫里沒有涉及到的是animation-delay,animation-direction和animation-play-state。animation-delay就是設置動畫延遲的時間,上面已經說過。animation-direction 屬性定義是否應該輪流反向播放動畫,有兩個值可取分別是normal和alternate。normal為默認值即不輪播,alternate設置動畫輪流反向播放。animation-play-state設置動畫是暫停還是播放。這個一般應該與js相結合使用,點擊改變該屬性對應的值,實現動畫的暫停與播放。比如點擊一下后暫停播放,再點擊一下后繼續播放動畫。那么其值paused與running也就很好理解了。
上面差不多就是根據這個twitter點贊動畫簡單介紹了一下css animation屬性的常用方法。
