教你用科學(xué)計(jì)算法計(jì)算CSS3動(dòng)畫幀數(shù)
發(fā)表日期:2015/9/22 10:12:15 文章編輯: 瀏覽次數(shù):3285
—————————————————————– 華麗麗的開篇 —————————————————————- 本篇文章來自騰訊內(nèi)部飯卡充值改版項(xiàng)目的CSS3動(dòng)畫經(jīng)驗(yàn)總結(jié)。雖然你們?cè)L問不到我們的飯卡站點(diǎn),不過可以小窺一下我們的動(dòng)畫示例喲。 (請(qǐng)使用chrome、safari或firefox瀏覽器看效果,效果地址) 實(shí)現(xiàn)上面“嘀卡萌風(fēng)騷亂舞”的動(dòng)畫,比較麻煩的是,要憑感覺自己算參數(shù)寫代碼,重復(fù)試個(gè)千百回,才能達(dá)到最終滿意的效果。 比如這個(gè)動(dòng)畫: 還這么干過
復(fù)制代碼 step2, 動(dòng)作之間過渡5幀,動(dòng)作1結(jié)束幀在20%,20+5=25, 動(dòng)作2在25%幀,動(dòng)作停留20幀
復(fù)制代碼 ……經(jīng)過一番計(jì)算后
復(fù)制代碼 艾瑪,幀數(shù)超出100%了>_<重新計(jì)算了一番,動(dòng)作數(shù)5,動(dòng)作過渡幀數(shù)5%,動(dòng)作停留幀數(shù)16%
復(fù)制代碼 感謝人民感謝黨,最后一幀加起來剛好100%刷新頁面看效果之后……(動(dòng)作過渡有點(diǎn)快,動(dòng)作停留有點(diǎn)長) 效果不對(duì),重算! 效果不對(duì),重算! …… 就這樣被折騰地體無完膚,深刻感悟我們是用生命在做動(dòng)畫,啊…..多么痛的領(lǐng)悟悟悟~~(有共鳴的,請(qǐng)默默的點(diǎn)個(gè)贊,謝謝) 所以,我們今天來探討如何更科學(xué)的計(jì)算幀數(shù)? 文章主要研究循環(huán)動(dòng)畫,各個(gè)動(dòng)作之間的過渡有規(guī)律性。 比如嘀卡萌跳舞動(dòng)畫 (該動(dòng)畫的實(shí)現(xiàn),可 查看 白樹同學(xué)的分享) 動(dòng)作過渡有規(guī)律性,從代碼層面也可理解為各動(dòng)作之間的過渡幀數(shù)是一樣的。如上面白樹同學(xué)實(shí)現(xiàn)的跑步動(dòng)畫,各動(dòng)作之間的過渡幀約14.3幀,代碼為
復(fù)制代碼 好,下面讓我們愉快的進(jìn)入主題吧循環(huán)動(dòng)畫按循環(huán)方式可以分為: 用CSS代碼的方式表示,就是: 單向循環(huán): animation-iteration-count: infinite; animation-direction: normal; 雙向循環(huán): animation-iteration-count: infinite; animation-direction: alternate; 先看看做一個(gè)動(dòng)畫需要哪些條件 CSS3幀動(dòng)畫的幀數(shù)設(shè)置是從0%~100%,數(shù)值可以帶小數(shù)位,0%可以用from關(guān)鍵詞替代,100%可以用to關(guān)鍵詞替代 動(dòng)作數(shù):n (已知參數(shù)) 動(dòng)畫中的幾個(gè)關(guān)鍵動(dòng)作 動(dòng)作停留幀數(shù):x (未知參數(shù)) 在當(dāng)前動(dòng)作停留的幀數(shù) 動(dòng)作過渡幀數(shù):y (未知參數(shù)) 上一個(gè)動(dòng)作過渡到下一個(gè)動(dòng)作需要用的幀數(shù) 我們用示例來說明它們之間的關(guān)系。 單向循環(huán)動(dòng)畫 示例要求:實(shí)現(xiàn)一個(gè)3個(gè)動(dòng)作的單向循環(huán)動(dòng)畫 為了方便理解,以線段圖示法來展示 Step1,滿幀100% 0% 100% └─────────────────────────────────────────┘ Step2,添加動(dòng)作節(jié)點(diǎn)(總節(jié)點(diǎn)數(shù) = 動(dòng)作數(shù)) 0% ?。? 100% 過渡y幀 過渡y幀 └────────────────────┴────────────────────┘動(dòng)作1 動(dòng)作2 動(dòng)作3 這個(gè)時(shí)候,我們很輕易的算出動(dòng)作2的keyframes幀數(shù)是50% |
實(shí)際上,很多時(shí)候我們需要讓每個(gè)動(dòng)作停頓一會(huì),而不會(huì)閃動(dòng)太快。如“嘀卡萌風(fēng)騷亂舞”的動(dòng)畫,每個(gè)動(dòng)作都需要定格一會(huì),這個(gè)時(shí)候我們需要給每個(gè)動(dòng)作分配一些停留幀數(shù)。
Step3,添加停留幀 (總節(jié)點(diǎn)數(shù) = 動(dòng)作數(shù) * 2)
0% ?% ?% ?% ?% 100%
停留x幀 過渡y幀 停留x幀 過渡y幀 停留x幀
└───────┴────────┴────────┴───────┴───────┘
動(dòng)作1 動(dòng)作2 動(dòng)作3
這下就復(fù)雜了,不過我們仔細(xì)分析,會(huì)發(fā)現(xiàn)它們之間有一定的規(guī)律。
3x + 2y = 100
動(dòng)作個(gè)數(shù) = 3 停留幀個(gè)數(shù) = 3 過渡幀個(gè)數(shù) = 2
設(shè)動(dòng)作個(gè)數(shù)為n,則
動(dòng)作個(gè)數(shù) = n 停留幀個(gè)數(shù) = n 過渡幀個(gè)數(shù) = n-1
然后,我們可以得出一個(gè)公式
nx + (n-1)y = 100
接下來我們可以有規(guī)則性的嘗試動(dòng)畫參數(shù)了,我們嘗試讓每個(gè)動(dòng)作停留20幀,通過公式求得動(dòng)作過渡幀數(shù)y也等于20,于是得出我們的幀數(shù)代碼
.demo{animation:anim-name 1s infinite;} /* 單向循環(huán) */
@keyframes anim-name{
0%, 20%{ /* 動(dòng)作1 */ }
40%, 60%{ /* 動(dòng)作2 */ }
80%, 100%{ /* 動(dòng)作3 */ }
}
復(fù)制代碼
有了公式,我們就不用瞎嘗試?yán)玻梢陨偎傈c(diǎn)腦細(xì)胞了
雙向循環(huán)動(dòng)畫
示例要求:實(shí)現(xiàn)一個(gè)3個(gè)動(dòng)作的雙向循環(huán)動(dòng)畫
復(fù)制上面的動(dòng)畫代碼,加個(gè) animation-direction: alternate; 屬性不就好了?
(哦,不對(duì),按照心理學(xué)反推論,如果這么簡(jiǎn)單,作者有必要另起篇幅嗎?肯定有陰謀!)
不用猜了,我就是有陰謀!
繼續(xù)線段圖示,當(dāng)我們加入 animation-direction: alternate; 屬性之后的效果是
問題:首尾動(dòng)作從第二遍播放開始會(huì)重復(fù)停留時(shí)間!
這個(gè)并不是我們期望看到的效果,不過解決方法也很簡(jiǎn)單
通過線段圖分析
2x + 2y = 100
動(dòng)作個(gè)數(shù) = 3 停留幀個(gè)數(shù) = 2 過渡幀個(gè)數(shù) = 2
設(shè)動(dòng)作個(gè)數(shù)為n,則
動(dòng)作個(gè)數(shù) = n 停留幀個(gè)數(shù) = n-1 過渡幀個(gè)數(shù) = n-1
然后,我們可以得出一個(gè)公式
(n-1)(x+y) = 100
接下來我們還是嘗試讓每個(gè)動(dòng)作停留20幀,通過公式求得動(dòng)作過渡幀數(shù)y等于30,于是得出我們的幀數(shù)代碼
.demo{animation:anim-name 1s infinite alternate;} /* 雙向循環(huán) */
@keyframes anim-name{
0%, 10%{ /* 動(dòng)作1 */ }
40%, 60%{ /* 動(dòng)作2 */ }
90%, 100%{ /* 動(dòng)作3 */ }
}
復(fù)制代碼
注意:雙向循環(huán)動(dòng)畫,首尾動(dòng)作停留幀要各減一半,示例的首尾動(dòng)作停留幀為10 (20/2=10)
細(xì)心的同學(xué)會(huì)發(fā)現(xiàn),其實(shí)這里還有點(diǎn)小瑕疵,那就是
問題:第一次播放的第一個(gè)動(dòng)作只停了一半時(shí)間!
有時(shí)我們做動(dòng)作銜接,一定要所有動(dòng)作時(shí)間都保持一致。解決辦法也不是沒有,可以給動(dòng)畫加個(gè)延遲時(shí)間 animation-delay 屬性,時(shí)長等于動(dòng)作停留時(shí)間的一半,如何計(jì)算時(shí)長后面會(huì)講到。
除了加延時(shí)解決這個(gè)問題之外,還有一個(gè)偽方法,請(qǐng)繼續(xù)往下看
模擬雙向循環(huán)動(dòng)畫
示例要求:實(shí)現(xiàn)一個(gè)3個(gè)動(dòng)作的雙向循環(huán)動(dòng)畫
模擬雙向循環(huán)動(dòng)畫就是不使用 animation-direction: alternate; 屬性實(shí)現(xiàn)雙向循環(huán)的效果。
有點(diǎn)繞,上線段圖
通過線段圖分析
4x + 4y = 100
動(dòng)作個(gè)數(shù) = 5 停留幀個(gè)數(shù) = 4 過渡幀個(gè)數(shù) = 4
設(shè)動(dòng)作個(gè)數(shù)為n,則
動(dòng)作個(gè)數(shù) = n 停留幀個(gè)數(shù) = n-1 過渡幀個(gè)數(shù) = n-1
然后,我們可以得出一個(gè)公式
(n-1)(x+y) = 100
但動(dòng)作個(gè)數(shù)5包含了重復(fù)動(dòng)作,不符合我們的計(jì)算習(xí)慣,不包含重復(fù)動(dòng)作個(gè)數(shù)3才符合我們的計(jì)算習(xí)慣。那么設(shè)
(不含重復(fù))動(dòng)作個(gè)數(shù)為 m
(含重復(fù))動(dòng)作個(gè)數(shù)為 n,則 n = 2m-1,將 2m-1 帶入上面的公式得出公式
(2m-1-1)(x+y) = 100
將m統(tǒng)一換成n表示,再簡(jiǎn)化公式后得到最終公式
(2n-2)(x+y) = 100
接下來我們?cè)俅螄L試讓每個(gè)動(dòng)作停留20幀,通過公式求得動(dòng)作過渡幀數(shù)y等于5,于是得出我們的幀數(shù)代碼
.demo{animation:anim-name 1s infinite;} /* 模擬雙向循環(huán) */
@-webkit-keyframes anim-name{
0%{ /* 動(dòng)作1 */ }
20%{ /* 動(dòng)作1 */ }
25%{ /* 動(dòng)作2 */ }
45%{ /* 動(dòng)作2 */ }
50%{ /* 動(dòng)作3 */ }
70%{ /* 動(dòng)作3 */ }
75%{ /* 動(dòng)作2 */ }
95%{ /* 動(dòng)作2 */ }
100%{ /* 動(dòng)作1 */ }
}
復(fù)制代碼
縮寫版代碼
.demo{animation:anim-name 1s infinite;} /* 模擬雙向循環(huán) */
@keyframes anim-name{
0%, 20%, 100%{ /* 動(dòng)作1 */ }
25%, 45%, 75%, 95%{ /* 動(dòng)作2 */ }
50%, 70%{ /* 動(dòng)作3 */ }
}
復(fù)制代碼
模擬雙向循環(huán)的方法可以讓所有動(dòng)作的停留時(shí)間都保持一致,缺點(diǎn)就是代碼比較多,幀數(shù)也算得麻煩,不過也不失為一種解決方法。一般情況下,還是建議大家使用雙向循環(huán)+延遲播放的方案。
提到延遲播放,跟時(shí)間有關(guān)系,這個(gè)延遲時(shí)長該怎么定?如果以上方案,每個(gè)動(dòng)作我們要固定它的過渡時(shí)間,比如動(dòng)作之間過渡0.4秒,那過渡幀數(shù)又該怎么定?接下來我們?cè)偻诰蛞幌拢瑤瑪?shù)如何跟時(shí)間結(jié)合。
時(shí)間模式計(jì)算幀數(shù)
我們?cè)谧鰟?dòng)畫的時(shí)候需要設(shè)置一個(gè) animation-duration 動(dòng)畫持續(xù)時(shí)間的屬性,知道持續(xù)播放時(shí)間我們就可以很輕易的計(jì)算出播放速度,還記得我們小學(xué)學(xué)的速度公式嗎?
設(shè),總幀數(shù)為s(100幀),播放時(shí)間為t,播放速度為v,得出公式
v = s / t
繼續(xù)用示例來加深理解。
示例要求:實(shí)現(xiàn)一個(gè)3個(gè)動(dòng)作的單向循環(huán)動(dòng)畫,播放時(shí)間2秒,每個(gè)動(dòng)作的過渡時(shí)間為0.4秒
通過播放速度公式,我們可以計(jì)算出過渡幀數(shù)。
播放速度: 100幀 / 2秒 = 50幀/秒
過渡幀數(shù): 50幀/秒 * 0.4秒 = 20幀
得出過渡幀數(shù),接下來套用單向循環(huán)動(dòng)畫的幀數(shù)公式,計(jì)算出停留幀數(shù),參考上面總結(jié)的公式 nx + (n-1)y = 100 ,推導(dǎo)公式得出停留幀數(shù) x = (100-(n-1)y) / n
動(dòng)作個(gè)數(shù)(n): 3
過渡幀數(shù)(y): 20
停留幀數(shù): (100-(3-1)*20)/3 = 20幀
于是得出我們的幀數(shù)代碼
.demo{animation:anim-name 2s infinite;} /* 單向循環(huán) */
@keyframes anim-name{
0%, 20%{ /* 動(dòng)作1 */ }
40%, 60%{ /* 動(dòng)作2 */ }
80%, 100%{ /* 動(dòng)作3 */ }
}
復(fù)制代碼
這么多公式,眼都花了更別說記了。別著急,公式是給機(jī)器記的,這種破事就交給我們的機(jī)器去算。下面是一個(gè)簡(jiǎn)易的CSS3動(dòng)畫幀數(shù)計(jì)算器,可以幫我們省去一些計(jì)算的煩惱。
CSS3動(dòng)畫幀數(shù)計(jì)算器:http://tid.tenpay.com/labs/css3_keyframes_calculator.html
以白樹同學(xué)的跑步動(dòng)畫為示例
動(dòng)畫是單向循環(huán),有7個(gè)關(guān)鍵動(dòng)作,動(dòng)作需要使用逐幀過渡效果 animation-timing-function:step-start 實(shí)現(xiàn),所以動(dòng)作個(gè)數(shù)需要額外加1,即有8個(gè)動(dòng)作。使用 step-start 后會(huì)自動(dòng)平分動(dòng)作停留時(shí)間,所以keyframes我們就不用加動(dòng)作停留幀數(shù)了。
打開工具頁面,選擇 [單向循環(huán)動(dòng)畫] -> [不停頓] -> [動(dòng)作個(gè)數(shù)8] -> [生成代碼]
最后……就沒有最后了,歡迎大家一起交流探討。
轉(zhuǎn)載本文章請(qǐng)關(guān)注!網(wǎng)站建設(shè)選擇北京瑩晨設(shè)計(jì)www.ww520ww.com
-
省時(shí)的瀏覽器同步測(cè)試神器
日期:2016-03-27 瀏覽次數(shù):2969
-
專注收集CSS 動(dòng)畫的網(wǎng)站
日期:2015-08-25 瀏覽次數(shù):3110
-
精選網(wǎng)站建設(shè)CSS選擇器
日期:2015-07-31 瀏覽次數(shù):2472
-
JS插件:miniGrid
日期:2015-08-07 瀏覽次數(shù):2736
-
HTML5的設(shè)計(jì)原理。
日期:2015-07-31 瀏覽次數(shù):2862
-
免費(fèi)SSL證書申請(qǐng)網(wǎng)站topssl.cn上線
日期:2024-09-23 瀏覽次數(shù):1089
-
如何在北京順義尋找一個(gè)踏實(shí)的網(wǎng)站建設(shè)公司
日期:2023-08-10 瀏覽次數(shù):4141
-
順義網(wǎng)站建設(shè):北京順義網(wǎng)站建設(shè)的優(yōu)點(diǎn)
日期:2023-05-25 瀏覽次數(shù):4565
-
選擇網(wǎng)站公司需要考慮哪些因素
日期:2023-05-25 瀏覽次數(shù):3425
-
北京模板建站
日期:2023-03-28 瀏覽次數(shù):3606
-
30個(gè)使用CSS實(shí)現(xiàn)的loading等待加載效果
日期:2015-11-05 瀏覽次數(shù):2719
-
保證網(wǎng)站設(shè)計(jì)成功的關(guān)鍵秘訣
日期:2019-01-02 瀏覽次數(shù):2266
-
發(fā)布網(wǎng)站時(shí)遇到哪些問題
日期:2019-03-05 瀏覽次數(shù):2358
-
白色空間在網(wǎng)站設(shè)計(jì)中的重要性
日期:2019-04-11 瀏覽次數(shù):2213
-
網(wǎng)站導(dǎo)航5個(gè)錯(cuò)誤以及如何避免它們
日期:2019-01-15 瀏覽次數(shù):2300