工作案例分享:SVGA動效落地的使用與避坑
編輯導(dǎo)讀:網(wǎng)絡(luò)上關(guān)于SVGA的討論大多數(shù)都只是在軟件上的問題,具體實踐案例很少。本文作者依據(jù)工作中項目實踐的所思所想,結(jié)合案例等分享了SVGA動效落地使用過程中非常有價值的設(shè)計知識,并對過程存在的問題進(jìn)行了盤點,供大家一同參考和學(xué)習(xí)。
接近年底,工作繁多,缺失精力,所以停更了一段時間。但正是因為投入到工作當(dāng)中,去解決棘手的問題,反而可以學(xué)習(xí)到很多新東西。今天我就來分享一下我的項目碰壁經(jīng)歷與總結(jié)。熱騰騰、新鮮出爐的一線干貨~
一、案例背景:為什么棄Lottie投SVGA
耍家任職于一家電商產(chǎn)品公司。雙十一大促近在眼前,我們想通過大量的動效來營造平臺的活動氛圍。
因為近些年Lottie的風(fēng)行,前端動效落地的成本比以前低了許多,不論是動畫視覺效果、前端事件綁定、動效文件大小控制等等方面,Lottie讓UI設(shè)計師在動效上的發(fā)揮空間得到了進(jìn)一步的擴展。我們團(tuán)隊之前實施動效落地,也是一直采用的Lottie方案。(我之前也總結(jié)過Lottie的一些入門事項,可移步《了解圖標(biāo)規(guī)范,用Lottie動畫讓圖標(biāo)落地》)
但這次想達(dá)到的動效效果和之前的不太相同。這一次因為關(guān)系到雙十一大促活動,我們想讓動效風(fēng)格更加夸張、驚喜。導(dǎo)致我們在運用Lottie的過程中,遇到了諸多問題。
后來經(jīng)過各方面的請教與調(diào)研,這次我們準(zhǔn)備轉(zhuǎn)戰(zhàn)SVGA方案。
網(wǎng)絡(luò)上關(guān)于SVGA的資料不少,但大多數(shù)不涉及到真實項目場景的細(xì)節(jié)還原。所以我準(zhǔn)備分享實例,好好講一講我為什么最終選擇SVGA,以及如何執(zhí)行、如何解決在這個過程中遇到的問題的。
這都是我本人一步一個坑踩出來的經(jīng)驗!希望能夠幫助到你。
二、辛路歷程
這次我們在Lottie上遭遇碰壁,原因是因為Lottie矢量動畫不支持部分AE直出的樣式效果,導(dǎo)致我們必須考慮以序列幀的方式去實現(xiàn)動畫。
我們在AE中制作好的成果,導(dǎo)出json后在本地解析預(yù)覽,效果不盡人意。到各端真機上演示還會再損失掉更多的樣式效果。(原因是因為Lottie在不同環(huán)境中所支持的AE參數(shù)有所差異)
以津貼紅包動效為例。為了給用戶帶來紅包的驚喜、喜慶氛圍,前期我構(gòu)思的動效是希望盡量帶有沖擊感。擬3D的效果可以讓紅包的出現(xiàn)看上去更加真實,并且在紅包飛出過程中使用了發(fā)光效果。
前期我們?yōu)榱吮苊庾哌M(jìn)「序列幀動畫」的胡同,基于我們團(tuán)隊在Lottie方面所具備的經(jīng)驗,我們希望盡量通過Lottie所支持的AE屬性來實現(xiàn)矢量動畫,這樣在文件大小、性能上都能夠得到把控。
例如,我們知道Lottie是不支持AE效果器所直接填加的效果的。于是對于發(fā)光效果,我們并沒有直接采用「效果-發(fā)光」去實現(xiàn),而是通過「高斯模糊+內(nèi)發(fā)光+投影」的方式,從視覺上去模擬發(fā)光。也期許這樣簡單的圖層樣式,能夠被Lottie解析。
但通過Bodymovin導(dǎo)出json后進(jìn)行本地預(yù)覽,出現(xiàn)了這樣的狀況:內(nèi)發(fā)光、投影效果和高斯模糊都丟失了。效果非常生硬?
甚至到了真機演示上,3D效果竟然也丟失了。完全沒法投入落地使用。
為了兼容所有的樣式效果,我們最終只好將動效輸出為序列幀,通過Lottie去一幀一幀播放(還是踏上了這條路…)。最終這樣的方式導(dǎo)致Lottie輸出后,包內(nèi)所包含的img位圖文件總量達(dá)到了數(shù)兆之多…
為了找到一個不管從視覺效果還是文件大小上都能主動把控的技術(shù)方案。于是我盯上了SVGA。
三、SVGA初體驗
在此我就不再做過多的SVGA背景說明了,網(wǎng)上一查一大堆。我盯上SVGA的原因是因為,許多直播禮物的浮夸動效都是用序列幀+svga方案落地的,應(yīng)該符合我們這次的項目要求。
通過最初的探索發(fā)現(xiàn),SVGA和Lottie其實很類似。你可以直接制作矢量動畫輸出svga文件,當(dāng)然,SVGA也有它所不支持的AE屬性。你也可以通過序列幀去輸出svga文件,這一點和Lottie就有所差異了。
熟悉Lottie的朋友應(yīng)該知道,當(dāng)動效中包含位圖元素時,Lottie會生成兩個文件:一個json代碼文件+一個img文件夾,這也是為什么我之前用Lottie去做序列幀時,整個文件包的大小達(dá)到了幾兆之多的原因,大部分都是因為一張一張的圖片堆積起來的。
而通過SVGA,只會生成一個svga后綴文件,代碼和位圖元素都被集成在了一起。
第一次接觸SVGA的我,掉進(jìn)了慣性思維的陷阱。無腦地以為SVGA就是專門為做序列幀動畫而誕生的。所以直接上手把整個動畫合成都導(dǎo)出成了序列幀動畫。最后輸出的文件依然超超超級大…
一定是我哪里出了什么問題…于是我開始了漫漫探索優(yōu)化的道路。
四、走起來了!走起來了!
雖然無可避免地走上了「序列幀動畫」這條路,但為了優(yōu)化動畫文件大小,我們開始思考,如何盡可能地減少序列幀的幀數(shù)。讓序列幀動畫盡量少,讓矢量動畫盡量多。
最終我們決定將紅包動畫拆分為兩個部分:「紅包飛出部分」+「等待開啟部分」。
因為「等待開啟部分」所涉及到的動效參數(shù),都比較基礎(chǔ),縮放、旋轉(zhuǎn)、透明度這類基礎(chǔ)屬性,是SVGA矢量動畫肯定能夠解析的。所以對于這一部分我們把元素全部進(jìn)行了拆解,最后輸出的矢量動畫文件,只有幾十k。
而「紅包飛出部分」,我將作為本次講解的案例,分享給大家。講一講我的操作與實現(xiàn)過程需要注意的事項。
步驟一:制作動效并導(dǎo)出序列幀
制作動效的部分,是屬于AE使用范疇的內(nèi)容了,我在此不做過多贅述。做好動效后,把合成添加至渲染序列,然后選擇導(dǎo)出為序列幀。
步驟二:壓縮序列幀文件并導(dǎo)入
從這一步開始,你就要做好思考如何優(yōu)化svga文件大小的準(zhǔn)備了。導(dǎo)入序列幀之前,務(wù)必先對所有的序列幀文件進(jìn)行壓縮(或者你的動效文件中有位圖元素,也務(wù)必先對位圖進(jìn)行壓縮)。元素文件大小將關(guān)乎你最終svga文件的大小。
SVGA和Lottie不一樣的地方就在于,SVGA是將位圖集成在svga文件當(dāng)中的,而Lottie則是把json和位圖分離開。Lottie可以在導(dǎo)出后,再對位圖進(jìn)行文件大小優(yōu)化;而SVGA最好是在事先就對位圖進(jìn)行大小優(yōu)化。我一般使用tinypng來壓縮位圖。
在項目面板中「右鍵-導(dǎo)入-文件」,選擇序列幀文件夾。
步驟三:制作序列幀動畫并導(dǎo)出
五、該如何優(yōu)化svga大小
我?guī)缀醢丫W(wǎng)上流傳的各種優(yōu)化svga文件大小的方式都試了個遍。
最終我發(fā)現(xiàn),對SVGA序列幀幀動畫大小影響最關(guān)鍵要素始終都是位圖文件的大小。任何方式的最終落腳點,都是在直接或間接地優(yōu)化位圖文件。
方法一:控制文件尺寸
尺寸越大文件越大,即使是alpha通道中的透明像素,也會影響位圖文件的最終大小。所以控制動畫素材文件的尺寸,是優(yōu)化svga文件大小的方式之一。
如果動畫的展示不需要全屏,盡量縮小動畫區(qū)域。如果動畫展示是全屏,建議尺寸可設(shè)置為680*1209,基本可以滿足所有分辨率的移動設(shè)備。
這里提出一個避坑點:「控制尺寸」是指在制作動畫時,就需要對畫板尺寸進(jìn)行控制。而不是二次導(dǎo)入序列幀后,再去改變合成的尺寸。在這個時候改變合成尺寸,約等于只是在改變動畫的可視區(qū)域,對最后導(dǎo)出的svga文件并沒有影響。
舉個例子:序列幀的原尺寸為400px*400px,原本輸出的svga動畫大小為90k。在保持序列幀尺寸不變的情況下,經(jīng)過我的實驗,就算我在二次序列幀合成中改變合成的尺寸為1px*1px,輸出的svga動畫大小依舊會是90k!只是動畫的可視區(qū)域變成了1px*1px。原因是因為,實際上svga文件中包含的源位圖文件是一樣的。只有在制作動畫時,導(dǎo)出300px*300px的序列幀,才能夠真正優(yōu)化到svga文件哦!
方法二:降低幀率
相信大多數(shù)人喜歡用24fps或30fps制作動畫,也就是每1秒鐘的動畫,將會產(chǎn)生24張或30張序列幀文件。
經(jīng)過其他同行的驗證,說14fps其實也基本可以滿足動畫的視覺要求。也就是說,同樣為1秒的動畫,只會產(chǎn)生14張序列幀文件。從源頭上減少位圖文件數(shù)量。
但我自己有做嘗試,14fps對于我們項目所需要的動畫來說會稍顯卡頓,所以最終選擇了放棄。
具體的動畫要具體分析,其實也不妨可以嘗試15-20fps之間的幀率,來尋找動畫效果與文件大小的平衡。
方法三:手動抽幀
和降低幀率的原理一樣,「手動抽幀」也是從源頭上減少位圖數(shù)量。
我查資料的時候發(fā)現(xiàn)有同行使用過「每隔一幀抽一幀」、「每隔兩幀抽一幀」、「每隔三幀抽兩幀」的方式,我為了保證動畫的連貫性,最終還是選用的「每隔一幀抽一幀」的方式。
?這里有一個躲坑點:因為一般我們做一個動畫,時長是提前明確的,抽幀之后會導(dǎo)致動畫時長縮短(例如「每隔一幀抽一幀」會導(dǎo)致動畫時長縮為之前的1/2)。所以為了保證動畫時長不變,我們抽幀之后要手動降低幀率。
舉個例子:因為「總幀數(shù)=幀率*時長」,在一個幀率為24fps的合成中,1s的動畫,就會有24張序列幀文件。我們選擇「每隔一幀抽一幀」的方式,保留了12張序列幀文件。在時長1s不變的前提下,我們需要用12fps幀率來重新新建一個合成導(dǎo)出svga文件。
方法四:降低分辨率
其實說到這里,大家也該悟到了,想控制svga的大小,其實就是在想方設(shè)法控制位圖文件的總大小。
通常我做動畫,都是在@2x下制作位圖元素。但如果前面的方式都嘗試了之后,發(fā)現(xiàn)你的svga文件還是過大,你還可以選擇在@1x下制作素材。缺點是在高分辨率設(shè)備上的畫質(zhì)會有所降低。
以上所有方法都要視具體動畫,具體分析,篩選最為合理的優(yōu)化方式。當(dāng)然你還可以探索其他各種方式來進(jìn)行svga大小的優(yōu)化,只要記住宗旨是:減小位圖文件總大小,一定還有其他更多的方式。也歡迎交流!
#專欄作家#
UCD耍家,公眾號:UCD耍家(ID:ucdplayer),人人都是產(chǎn)品經(jīng)理專欄作家。
本文由 @UCD耍家 原創(chuàng)發(fā)布于人人都是產(chǎn)品經(jīng)理。未經(jīng)許可,禁止轉(zhuǎn)載
題圖來自Unsplash,基于CC0協(xié)議
大哥,下次順便吧導(dǎo)出SVGA的方法也寫上吧,哈哈哈哈哈哈