先加個副標題XD
--如何解決background-size為100%下處理@keyframes
正是在專案中遇到副標題,才引起我更深入的探尋
先略帶一下基本的css3動畫
css3的動畫實現是通過屬性animation 與 @keyframes配合實現的
具體可以參見這篇文章,這位女程式媛有著非常詳盡與精彩的闡述
https://24ways.org/2012/flashless-animation/
最後實現了一張貓跑動在有視訊滾動的畫面上
為什麼不用gif?
gif動畫就是典型的幀動畫,gif在各瀏覽器上也支援的很好。手機上表現也很好。
唯一的缺點就是體積太大,繼而導致低端機上吃記憶體卡頓。
用css3來實現動畫,會明顯降低圖片體積,即用sprite形式
通常,網上文章介紹的動畫都是用px做為大小或距離單位
css3的動畫實現是通過屬性animation 與 @keyframes配合實現的
具體可以參見這篇文章,這位女程式設計師有著非常詳盡與精彩的闡述
https://24ways.org/2012/flashless-animation/
最後實現了一張貓跑動在有視訊滾動的畫面上
通常,網上文章介紹的動畫都是用px做為大小或距離單位
@keyframes walk-cycle { 0% {background-position: 0 0; } 100% {background-position: -880px 0;} }
動畫實現如:
.anim-div{ background-image: “那個蛋的圖地址” animation: walk-cycle 1s steps(11) infinite; }
以上就是最簡單實現幀動畫的程式碼了..
嗯。。在pc上看起來貌似還行。
實際專案中遇到的問題。
如果是在手機上,
為簡單的適應不同螢幕尺寸,我們通常的做法是讓美工大人出一張相對比較大的圖,比如以iphone5為基準,320px寬度。
讓美工提供640寬度的圖給我們。我們通過設定background-size: 100%即可等比縮放來適應大部分的屏了,而不必為每個螢幕都設定不同的背景圖片。
那麼就成了以下的程式碼
.anim-div{ background-image: “那個蛋的圖地址” background-size: 100% animation: walk-cycle 1s steps(11) infinite; }
對,就加了一句background-size: 100%
結果就是,蒙逼了。。動畫完全不像預想的那樣浪了。現在真是浪出新風格了..
搜了半天google才找到有類似的回答,然後解決方法是
@keyframes walk-cycle { 0% {background-position: 0 0; } 100% {background-position: 110% 0;} } .anim-div{ background-image: “那個蛋的圖地址” background-size: 1100% animation: walk-cycle 1s steps(11) infinite; }
第一步:background-size設定為幀數*100%,即1100%
第二步:讓關鍵幀也變換為百分比, 並且為其補上最後一幀
公式為: ((100/(2-1)) + 100) /100
公式為: ((100/(2-1)) + 100) /100
公式為: ((100/(2-1)) + 100) /100
重要的話說三遍,所以公式寫三遍
此例子中即:
(100 / (11-1) +100) / 100 = 1.1
background-position: 110% 0;
為什麼要補上一幀?
帶出了另一個話題
在做biu動圖社群HTML5展示頁時,偶然發現keyframe實現的動圖迴圈過程中會丟失一幀,找了好久終於有一篇國外同行研究此現象的文章,
當使用css3的steps配合以百分比為值的background-position時,迴圈幀的過程中最後一幀是不顯示的
以下是我找到的國外網友分析的資料及例項測試,例項中檢視原始碼即可看到以下的分析邏輯
http://willian12345.github.io/test-demo/step-keyframes/
或
http://sheldonwang.com/test-demo/step-keyframes/
接下來分析一下:
@keyframes countdown { 0% { background-position: 0 0; } 100% {background-position: 0 100%; } }
.flick { animation: countdown 1s steps(2) infinite; background: url(1-2.png) 0 0 no-repeat; }
你以為.flick就可以讓動畫在1和2之間跳動形成動畫
然而並沒有,它只是在1和2中間一半處移來移去
讓我們試試加上”end”或“start”屬性,看看行不行
.flick-end { animation: countdown 1s steps(1, end) infinite; } .flick-start { animation: countdown 1s steps(1, start) infinite; }
它們看起來直接跳過了開始或結束那一幀
綜合查閱了相關資料,end和start控制的是一個幀迴圈結束後連線上繼續迴圈的是哪一幀,現象是
如果設定的是end,那麼最後一幀就被無視掉了,如果設定的是start,那麼第一幀被無視了。W3c有個相應說明的圖,反正我是沒看明白。
讓我們用3幀的圖來驗證一下
.easy-as { animation: countdown 1s steps(2, end) infinite; background: url(1-2-3.png) 0 0 no-repeat; }
果然end效果是1與2之反覆跳轉,直接無視了3
要讓它正常依次顯示1,2,3那麼需要補上一幀
@keyframes countdownTo3 { 0% { background-position: 0 0; } 100% {background-position: 0 150%; } } .easy-working { animation: countdownTo3 1s steps(3) infinite; }
設為150%,即補上了50%一格的高度(一幀)
所以當為兩幀時
@keyframes countdownTo2 { 0% { background-position: 0 0; } 100% {background-position: 0 200%; } } .flick-working { animation: countdownTo2 1s steps(2) infinite; }
再用公式算一遍
background-position-y: (100 / (2-1) +100) / 100 = 200%
嗯,所以是y軸上是200% 即: background-position: 0 200%;
結束語
一開始還真沒注意過這些小細節,直到寫到才會碰到,碰到再解決。。so,只能說能多寫就多寫嘍
直到財務自由!!!,財務自由!!!,財務自由!!!重要的話說三遍
祝看到這篇文章的小夥伴都能實現
=================================================傲嬌分割線===============================================
轉載註明,部落格園
willian12345@126.com
sheldon.wang
github.com/willian12345