今天在微博上看到@過氣網紅一絲 的一篇微博,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屬性的常用方法。