Css3幀動畫深刻探尋,講點項目中實際會碰到的問題

先加個副標題XDcss

--如何解決background-size爲100%下處理@keyframes

正是在項目中遇到副標題,才引發我更深刻的探尋css3

 

先略帶一下基本的css3動畫


 

css3的動畫實現是經過屬性animation 與 @keyframes配合實現的git

具體能夠參見這篇文章,這位女程序媛有着很是詳盡與精彩的闡述程序員

https://24ways.org/2012/flashless-animation/github

最後實現了一張貓跑動在有視頻滾動的畫面上 瀏覽器

 

爲何不用gif?css3動畫

gif動畫就是典型的幀動畫,gif在各瀏覽器上也支持的很好。手機上表現也很好。app

惟一的缺點就是體積太大,繼而致使低端機上吃內存卡頓。less

 

用css3來實現動畫,會明顯下降圖片體積,即用sprite形式iphone

 

一般,網上文章介紹的動畫都是用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

相關文章
相關標籤/搜索