摘要:通過剖析一個跑男動畫實例,來把中動畫相關(guān)的知識點抽絲剝繭,一網(wǎng)打盡。跑男的動畫其實可以拆分為兩個一個是交替擺腿另一個是位置移動。在使用改變雪碧圖時,得到效果這樣的平滑過度顯然不是我們想要的。所以,在切換雪碧圖背景的方案下,就要派上用場了。
作為一名真正的前端開發(fā)者,我們不能只關(guān)注前端邏輯部分。畢竟“水銀泄地”般的頁面設(shè)計和“炫酷逼真”的動畫效果,是我們區(qū)別于其他程序員所特有的優(yōu)勢之一。
盡量百分之百的還原視覺稿,為UE設(shè)計靈感和用戶視覺享受架起一座橋梁:正所謂“晉帝時祭北郊,更祝版,工人削之,筆入木三分?!?br>借古書法形容我們的代碼,當(dāng)真是恰當(dāng)準確又自戀無比。
之前的一些文章大多都是分享JS相關(guān)內(nèi)容。今天輕松一下,我來談?wù)勄岸隧撁娴膭赢嫴糠?。通過剖析一個“跑男”動畫實例,來把CSS3中動畫相關(guān)的知識點抽絲剝繭,一網(wǎng)打盡。如果讀者有自己的感想或者不一樣的見解,歡迎一起討論。
整個項目的Github地址可以參考這里。對比線上效果,這個倉庫進行了90%的刪減,但是更加適合練手和理解。感興趣的讀者歡迎拉下來自己玩一玩。里面只有一關(guān)動畫,您可以比葫蘆畫瓢進行調(diào)試練習(xí)。
項目簡介這是一個運營活動頁面——"春季馬拉松大比拼":用戶以闖關(guān)形式參加,并進行角色扮演。在滿足一定條件下,自己扮演的馬拉松選手會繞著跑道(非正規(guī)跑道形狀)前進,向終點發(fā)起沖擊。
部分頁面動畫效果如下:
當(dāng)然,這個動畫并不完美??紤]到時間性價比,我只用了兩幀重復(fù)循環(huán)模擬擺腿動作。但也達到了運營和產(chǎn)品小妹的需求。如果在沒有上線壓力的情況下,我們完全可以拆分更多幀,把他打磨的更流暢順滑。
首先,我們來看一下它的具體實現(xiàn)方式吧。
動畫方案這一系列的動畫設(shè)計,出于性能和簡單的考慮,我采用了純CSS3來實現(xiàn)。CSS3實現(xiàn)動畫,主要有兩種方式:transition屬性和animation屬性。
前者是用來“平滑的改變CSS的值”。一般對于需要特定幀處理的動畫,顯然是蒼白無力的,這里就不過多介紹了。重點介紹一下animation屬性。
animation屬性其實是一個簡寫屬性,就像我們更加熟悉的“background”一樣。它用于設(shè)置六個動畫屬性:
1)animation-name
2)animation-duration
3)animation-timing-function
4)animation-delay
5)animation-iteration-count
6)animation-direction
最重要的就是animation-name,它規(guī)定了需要綁定的keyframes名稱。keyframes,我們用來定義幾個關(guān)鍵節(jié)點幀。
具體我不會進行科普。如果初學(xué)者不了解,社區(qū)上關(guān)于這些的資料可是一大把。
跑男開跑回到具體的業(yè)務(wù)場景,我們進行分析。跑男的動畫其實可以拆分為兩個:
1)一個是交替擺腿;
2)另一個是位置移動。
這兩個動作要嚴絲合縫的結(jié)合。能把這個想清楚,那就基本思路理解了。
接著,如何讓這兩種動畫一起施加在“靜止的”跑男身上呢?
我采用了增加一個div標(biāo)簽,作為父節(jié)點包裹的方式:
"man-wrapper"這個div與"man"這個div尺寸大小完全一致,視覺上絕對重合。父節(jié)點處理位移,子節(jié)點負責(zé)交替擺腿:
.man-wrapper { display: inline-block; width: 46px; height: 75px; position: absolute; } .man { display: inline-block; width: 46px; height: 75px; background: url(img/sprite.png); position: absolute; top: 0; left: 0; }
當(dāng)需要觸發(fā)位移,開啟跑步狀態(tài)時,父節(jié)點添"start-run"類:
$(".man-wrapper").addClass("start-run");
同時,子節(jié)點添加"running"類:
$("#man").addClass("running");動畫實現(xiàn)
關(guān)于“start-run”位移的動畫設(shè)計,在跑道上直道部分相對簡單,我們思路是使用transform:translate3d。
但是視覺稿上存在不少于5處不規(guī)則彎道,在不改變原圖的基礎(chǔ)上,以及在不增加多余圖片的原則下,我們可以使用transform:rotate3d,使跑男進行側(cè)身。具體設(shè)計看下圖:
1)1-2和4-5,只需要改變transform:translate3d;
2)2-4部分,即2,3,4這三個階段是為了彎道準備的。當(dāng)然,如果時間充足,我們完全可以拆分的更加細致,更加細分。
3)其中3是彎道中心的45度轉(zhuǎn)身:rotate3d(0,0,1,45deg);
4)其中4是已經(jīng)完全轉(zhuǎn)身:rotate3d(0,0,1,90deg);
具體代碼:
.start-run { animation: start-run 5000ms; animation-fill-mode: forwards; animation-timing-function: linear; } @keyframes start-run { 0% { transform: translate3d(0, 0, 0); } 35% { transform: translate3d(0, 155px, 0) rotate3d(0, 0, 1, 0deg); } 50% { transform: translate3d(20px, 224px, 0) rotate3d(0, 0, 1, -45deg); } 70% { transform: translate3d(80px, 242px, 0) rotate3d(0, 0, 1, -90deg); } 100% { transform: translate3d(200px, 243px, 0) rotate3d(0, 0, 1, -90deg); } }
為什么是35%,50%,70%呢?這個是我調(diào)試出來,相對能達到順暢效果。如果追求更嚴謹?shù)脑挘耆梢粤幸粋€極坐標(biāo)計算一下位移和時間。當(dāng)然這樣子成本會比較大。
還有一點值得一提的是animation-timing-function: linear; 一般馬拉松中段,都近似于勻速跑吧~
解決完了位移的問題,我們來看擺腿動作。這個其實就是兩張圖片在交替播放。就是gif圖原理。我使用了改變background-position,來切換精靈圖片的方式處理:
.running { animation: running-man 1200ms steps(2) infinite; } @keyframes running-man { 0% { background-position: 0 0; } 50% { background-position: 92px 0; } }
千萬不要掃一眼代碼完事兒,這里還有一些最重要的細節(jié)要注意。首先是“infinite”的使用,這個應(yīng)該沒什么意外吧。另外,你可曾注意了steps這個函數(shù)?
steps()函數(shù)實現(xiàn)階躍動畫我們知道animation定義的關(guān)鍵幀之間是“平滑過渡”的。這個平滑過渡怎么理解呢?我做了一個“反例”示圖來說明。
在使用keyframes改變雪碧圖background-position時,得到效果:
這樣的"平滑過度"顯然不是我們想要的。
所以,在切換雪碧圖背景的方案下,steps()就要派上用場了。順便說一句,最近面試一些人,提到熟悉CSS3動畫,但是大部分都還不知道這個steps階躍函數(shù)。如果你還不清楚,可以參考這里。
借助steps()函數(shù),我們實現(xiàn)了交替跑動的分解動畫:
還不完美做到這里,其實還沒有完全結(jié)束。有一些值得我們思考的問題。
1)真的有必要多一個標(biāo)簽,來相互結(jié)合生成動畫嗎?
其實不是的,animation很神奇很強大的一點在于:它可以接受多個動畫屬性序列。比如上邊那種情況我們完全可以這樣實現(xiàn):
.running { animation: start-run 5000ms forwards linear, running-man 1200ms steps(2) infinite }
2) 如果刻意追求更佳完美的動畫,我們還需要哪些儲備?
不得不要說數(shù)學(xué)和物理知識了。比如,二次方曲線、三次方曲線、一直到五次方曲線,正弦余弦、圓弧、拋物線、反彈曲線、彈簧曲線等等。如果你對研究這些有興趣,這里安利一些:高性能動畫實現(xiàn)以及可視化1,可視化2。
除了數(shù)學(xué)公式以外,也需要我們掌握樣式預(yù)處理器函數(shù)使用。畢竟,那么多幀我們不可能自己手動實現(xiàn)。
總結(jié)流暢高效的動畫,絕非一朝一夕就能完成,需要各方面甚至跨領(lǐng)域的積累。如果你對此很感興趣,歡迎討論。
最后,這篇文章中截圖部分采用了我廠UE:許冬設(shè)計師的視覺稿,和PM:田小甜大小姐的交互設(shè)計。
PS:百度知識搜索部大前端繼續(xù)招兵買馬,有意向者火速聯(lián)系。。。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/50558.html
摘要:通過剖析一個跑男動畫實例,來把中動畫相關(guān)的知識點抽絲剝繭,一網(wǎng)打盡。跑男的動畫其實可以拆分為兩個一個是交替擺腿另一個是位置移動。在使用改變雪碧圖時,得到效果這樣的平滑過度顯然不是我們想要的。所以,在切換雪碧圖背景的方案下,就要派上用場了。 作為一名真正的前端開發(fā)者,我們不能只關(guān)注前端邏輯部分。畢竟水銀泄地般的頁面設(shè)計和炫酷逼真的動畫效果,是我們區(qū)別于其他程序員所特有的優(yōu)勢之一。 盡量百...
摘要:通過剖析一個跑男動畫實例,來把中動畫相關(guān)的知識點抽絲剝繭,一網(wǎng)打盡。跑男的動畫其實可以拆分為兩個一個是交替擺腿另一個是位置移動。在使用改變雪碧圖時,得到效果這樣的平滑過度顯然不是我們想要的。所以,在切換雪碧圖背景的方案下,就要派上用場了。 作為一名真正的前端開發(fā)者,我們不能只關(guān)注前端邏輯部分。畢竟水銀泄地般的頁面設(shè)計和炫酷逼真的動畫效果,是我們區(qū)別于其他程序員所特有的優(yōu)勢之一。 盡量百...
摘要:并且用驗證了中一系列的實質(zhì)就是魔法糖的本質(zhì)。抽絲剝繭我們首先看的編譯結(jié)果這是一個自執(zhí)行函數(shù),它接受一個參數(shù)就是他要繼承的父類,返回一個構(gòu)造函數(shù)。 如果你已經(jīng)看過第一篇揭秘babel的魔法之class魔法處理,這篇將會是一個延伸;如果你還沒看過,并且也不想現(xiàn)在就去讀一下,單獨看這篇也沒有關(guān)系,并不存在理解上的障礙。 上一篇針對Babel對ES6里面基礎(chǔ)class的編譯進行了分析。這一篇將...
閱讀 1561·2021-11-25 09:43
閱讀 2348·2019-08-30 15:55
閱讀 1472·2019-08-30 13:08
閱讀 2684·2019-08-29 10:59
閱讀 823·2019-08-29 10:54
閱讀 1595·2019-08-26 18:26
閱讀 2555·2019-08-26 13:44
閱讀 2659·2019-08-23 18:36