這個比較高端了!CSS3動畫幀數科學計算法

編者按:CSS3和HTML5一樣是網頁設計的大勢所趨,本篇文章來自騰訊內部飯卡充值改版項目的CSS3動畫經驗總結。雖然大家訪問不到騰訊內部的飯卡站點,不過可以由此小窺一下有趣的動畫示例喲。

這個比較高端了!CSS3動畫幀數科學計算法

bboy90:總結都濃縮在這個工具里了,想知道工具的地址或想窺探工具誕生的趣事請往下看 。

這個比較高端了!CSS3動畫幀數科學計算法

(請使用chrome、safari或firefox瀏覽器看效果,效果地址

實現上面"嘀卡萌風騷亂舞"的動畫,比較麻煩的是,要憑感覺自己算參數寫代碼,重復試個千百回,才能達到最終滿意的效果。

比如這個動畫:

這個比較高端了!CSS3動畫幀數科學計算法

我曾經,這么干過

這個比較高端了!CSS3動畫幀數科學計算法

還這么干過

這個比較高端了!CSS3動畫幀數科學計算法

step1, 動作1在0%上,動作停留20幀

@keyframes anim-name{ 
    0%, 20%{ /* 動作1 */ }
    ...
}

step2, 動作之間過渡5幀,動作1結束幀在20%,20+5=25, 動作2在25%幀,動作停留20幀

@keyframes anim-name{ 
    0%, 20%{ /* 動作1 */ }
    25%, 45%{ /* 動作2 */ }
    ...
}

……

經過一番計算后

@keyframes anim-name{ 
    0%, 20%{ /* 動作1 */ }
    25%, 45%{ /* 動作2 */ }
    50%, 70%{ /* 動作3 */ }
    75%, 95%{ /* 動作4 */ }
    100%, 120%{ /* 動作5 */ }
}

艾瑪,幀數超出100%了>_<

重新計算了一番,動作數5,動作過渡幀數5%,動作停留幀數16%

@-webkit-keyframes anim-name{
    0%, 16%{  /* 動作1 */  }
    21%, 37%{  /* 動作2 */  }
    42%, 58%{  /* 動作3 */  }
    63%, 79%{  /* 動作4 */  }
    84%, 100%{  /* 動作5 */  }
}

感謝人民感謝黨,最后一幀加起來剛好100%

刷新頁面看效果之后……(動作過渡有點快,動作停留有點長)

效果不對,重算!

效果不對,重算!

……

就這樣被折騰地體無完膚,深刻感悟我們是用生命在做動畫,啊…..多么痛的領悟悟悟~~(有共鳴的,請默默的點個贊,謝謝)

所以,我們今天來探討如何更科學的計算幀數?

這個比較高端了!CSS3動畫幀數科學計算法

文章主要研究循環動畫,各個動作之間的過渡有規律性。

比如嘀卡萌跳舞動畫

這個比較高端了!CSS3動畫幀數科學計算法

走路動畫

這個比較高端了!CSS3動畫幀數科學計算法

還有跑步動畫

這個比較高端了!CSS3動畫幀數科學計算法

(該動畫的實現,可 查看 白樹同學的分享)

動作過渡有規律性,從代碼層面也可理解為各動作之間的過渡幀數是一樣的。

如上面白樹同學實現的跑步動畫,各動作之間的過渡幀約14.3幀,代碼為

@keyframes anim-name{
    0% {background-position: 0 0;}
    14.3% {background-position: -180px 0;}
    28.6% {background-position: -360px 0;}
    42.9% {background-position: -540px 0;}
    57.2% {background-position: -720px 0;}
    71.5% {background-position: -900px 0;}
    85.8% {background-position: -1080px 0;}
    100% {background-position: 0 0;}
}

好,下面讓我們愉快的進入主題吧

循環動畫按循環方式可以分為:

這個比較高端了!CSS3動畫幀數科學計算法

用CSS代碼的方式表示,就是:

單向循環: animation-iteration-count: infinite; animation-direction: normal;

雙向循環: animation-iteration-count: infinite; animation-direction: alternate;

先看看做一個動畫需要哪些條件

這個比較高端了!CSS3動畫幀數科學計算法

總幀數:100 (已知參數)

CSS3幀動畫的幀數設置是從0%~100%,數值可以帶小數位,0%可以用from關鍵詞替代,100%可以用to關鍵詞替代

動作數:n (已知參數)

動畫中的幾個關鍵動作

動作停留幀數:x (未知參數)

在當前動作停留的幀數

動作過渡幀數:y (未知參數)

上一個動作過渡到下一個動作需要用的幀數

我們用示例來說明它們之間的關系。

單向循環動畫

示例要求:實現一個3個動作的單向循環動畫

為了方便理解,以線段圖示法來展示

Step1,滿幀100%

0%                           100%

└─────────────────────────────────────────┘

Step2,添加動作節點(總節點數 = 動作數)

0%             ?%            100%

過渡y幀           過渡y幀

└────────────────────┴────────────────────┘

動作1            動作2            動作3

這個時候,我們很輕易的算出動作2的keyframes幀數是50%

實際上,很多時候我們需要讓每個動作停頓一會,而不會閃動太快。如"嘀卡萌風騷亂舞"的動畫,每個動作都需要定格一會,這個時候我們需要給每個動作分配一些停留幀數。

Step3,添加停留幀 (總節點數 = 動作數 * 2)

0%    ?%     ?%     ?%     ?%    100%

停留x幀  過渡y幀   停留x幀  過渡y幀   停留x幀

└───────┴────────┴────────┴───────┴───────┘

動作1          動作2          動作3

這下就復雜了,不過我們仔細分析,會發現它們之間有一定的規律。

3x + 2y = 100

動作個數 = 3 停留幀個數 = 3 過渡幀個數 = 2

設動作個數為n,則

動作個數 = n 停留幀個數 = n 過渡幀個數 = n-1

然后,我們可以得出一個公式

nx + (n-1)y = 100

接下來我們可以有規則性的嘗試動畫參數了,我們嘗試讓每個動作停留20幀,通過公式求得動作過渡幀數y也等于20,于是得出我們的幀數代碼

.demo{animation:anim-name 1s infinite;}  /* 單向循環 */

@keyframes anim-name{
    0%, 20%{  /* 動作1 */  }
    40%, 60%{  /* 動作2 */  }
    80%, 100%{  /* 動作3 */  }
}

有了公式,我們就不用瞎嘗試啦,可以少死點腦細胞了

雙向循環動畫

示例要求:實現一個3個動作的雙向循環動畫

復制上面的動畫代碼,加個 animation-direction: alternate; 屬性不就好了?

(哦,不對,按照心理學反推論,如果這么簡單,作者有必要另起篇幅嗎?肯定有陰謀!)

不用猜了,我就是有陰謀!

繼續線段圖示,當我們加入 animation-direction: alternate; 屬性之后的效果是

這個比較高端了!CSS3動畫幀數科學計算法

問題:首尾動作從第二遍播放開始會重復停留時間!

這個并不是我們期望看到的效果,不過解決方法也很簡單

這個比較高端了!CSS3動畫幀數科學計算法

通過線段圖分析

2x + 2y = 100

動作個數 = 3 停留幀個數 = 2 過渡幀個數 = 2

設動作個數為n,則

動作個數 = n 停留幀個數 = n-1 過渡幀個數 = n-1

然后,我們可以得出一個公式

(n-1)(x+y) = 100

接下來我們還是嘗試讓每個動作停留20幀,通過公式求得動作過渡幀數y等于30,于是得出我們的幀數代碼

.demo{animation:anim-name 1s infinite alternate;} /* 雙向循環 */

@keyframes anim-name{
    0%, 10%{  /* 動作1 */  }
    40%, 60%{  /* 動作2 */  }
    90%, 100%{  /* 動作3 */  }
}

注意:雙向循環動畫,首尾動作停留幀要各減一半,示例的首尾動作停留幀為10 (20/2=10)

細心的同學會發現,其實這里還有點小瑕疵,那就是

問題:第一次播放的第一個動作只停了一半時間!

有時我們做動作銜接,一定要所有動作時間都保持一致。解決辦法也不是沒有,可以給動畫加個延遲時間 animation-delay 屬性,時長等于動作停留時間的一半,如何計算時長后面會講到。

除了加延時解決這個問題之外,還有一個偽方法,請繼續往下看

模擬雙向循環動畫

示例要求:實現一個3個動作的雙向循環動畫

模擬雙向循環動畫就是不使用 animation-direction: alternate; 屬性實現雙向循環的效果。

有點繞,上線段圖

這個比較高端了!CSS3動畫幀數科學計算法

通過線段圖分析

4x + 4y = 100

動作個數 = 5 停留幀個數 = 4 過渡幀個數 = 4

設動作個數為n,則

動作個數 = n 停留幀個數 = n-1 過渡幀個數 = n-1

然后,我們可以得出一個公式

(n-1)(x+y) = 100

但動作個數5包含了重復動作,不符合我們的計算習慣,不包含重復動作個數3才符合我們的計算習慣。那么設

(不含重復)動作個數為 m

(含重復)動作個數為 n,則 n = 2m-1,將 2m-1 帶入上面的公式得出公式

(2m-1-1)(x+y) = 100

將m統一換成n表示,再簡化公式后得到最終公式

(2n-2)(x+y) = 100

接下來我們再次嘗試讓每個動作停留20幀,通過公式求得動作過渡幀數y等于5,于是得出我們的幀數代碼

.demo{animation:anim-name 1s infinite;} /* 模擬雙向循環 */

@-webkit-keyframes anim-name{
    0%{  /* 動作1 */  }
    20%{  /* 動作1 */  }
    25%{  /* 動作2 */  }
    45%{  /* 動作2 */  }
    50%{  /* 動作3 */  }
    70%{  /* 動作3 */  }
    75%{  /* 動作2 */  }
    95%{  /* 動作2 */  }
    100%{  /* 動作1 */  }
}

縮寫版代碼

.demo{animation:anim-name 1s infinite;} /* 模擬雙向循環 */

@keyframes anim-name{
    0%, 20%, 100%{  /* 動作1 */  }
    25%, 45%, 75%, 95%{  /* 動作2 */  }
    50%, 70%{  /* 動作3 */  }
}

模擬雙向循環的方法可以讓所有動作的停留時間都保持一致,缺點就是代碼比較多,幀數也算得麻煩,不過也不失為一種解決方法。一般情況下,還是建議大家使用雙向循環+延遲播放的方案。

提到延遲播放,跟時間有關系,這個延遲時長該怎么定?如果以上方案,每個動作我們要固定它的過渡時間,比如動作之間過渡0.4秒,那過渡幀數又該怎么定?接下來我們再挖掘一下,幀數如何跟時間結合。

時間模式計算幀數

我們在做動畫的時候需要設置一個 animation-duration 動畫持續時間的屬性,知道持續播放時間我們就可以很輕易的計算出播放速度,還記得我們小學學的速度公式嗎?

設,總幀數為s(100幀),播放時間為t,播放速度為v,得出公式

v = s / t

繼續用示例來加深理解。

示例要求:實現一個3個動作的單向循環動畫,播放時間2秒,每個動作的過渡時間為0.4秒

通過播放速度公式,我們可以計算出過渡幀數。

播放速度: 100幀 / 2秒 = 50幀/秒
過渡幀數: 50幀/秒 * 0.4秒 = 20幀

得出過渡幀數,接下來套用單向循環動畫的幀數公式,計算出停留幀數,參考上面總結的公式 nx + (n-1)y = 100 ,推導公式得出停留幀數 x = (100-(n-1)y) / n

動作個數(n): 3

過渡幀數(y): 20
停留幀數: (100-(3-1)*20)/3 = 20幀

于是得出我們的幀數代碼

.demo{animation:anim-name 2s infinite;}  /* 單向循環 */

@keyframes anim-name{
    0%, 20%{  /* 動作1 */  }
    40%, 60%{  /* 動作2 */  }
    80%, 100%{  /* 動作3 */  }
}

這么多公式,眼都花了更別說記了。別著急,公式是給機器記的,這種破事就交給我們的機器去算。下面是一個簡易的CSS3動畫幀數計算器,可以幫我們省去一些計算的煩惱。

CSS3動畫幀數計算器:http://tid.tenpay.com/labs/css3_keyframes_calculator.html

這個比較高端了!CSS3動畫幀數科學計算法

以白樹同學的跑步動畫為示例

這個比較高端了!CSS3動畫幀數科學計算法

這個比較高端了!CSS3動畫幀數科學計算法

動畫是單向循環,有7個關鍵動作,動作需要使用逐幀過渡效果 animation-timing-function:step-start 實現,所以動作個數需要額外加1,即有8個動作。使用 step-start 后會自動平分動作停留時間,所以keyframes我們就不用加動作停留幀數了。

打開工具頁面,選擇 [單向循環動畫] -> [不停頓] -> [動作個數8] -> [生成代碼]

這個比較高端了!CSS3動畫幀數科學計算法

最后……就沒有最后了,歡迎大家一起交流探討。

原文地址:http://tid.tenpay.com/?p=5983
作者:bboy90

【優設網 原創文章 投稿郵箱:2650232288@qq.com】

================關于優設網================
"優設網uisdc.com"是一個分享網頁設計、無線端設計以及PS教程的干貨網站。
【特色推薦】
設計師需要讀的100本書:史上最全的設計師圖書導航:http://hao.uisdc.com/book/。
設計微博:擁有粉絲量70萬的人氣微博@優秀網頁設計 ,歡迎關注獲取網頁設計資源、下載頂尖設計素材。
設計導航:全球頂尖設計網站推薦,設計師必備導航:http://hao.uisdc.com
———————————————————–
想在手機上、被窩里獲取設計教程、經驗分享和各種意想不到的"福利"嗎?
添加 優秀網頁設計 微信號:【youshege】優設哥的全拼
您也可以通過掃描下方二維碼快速添加:

這個比較高端了!CSS3動畫幀數科學計算法

收藏 7
點贊 2

復制本文鏈接 文章為作者獨立觀點不代表優設網立場,未經允許不得轉載。