AE-to-web系列:bodymovin實踐(開發禮物特效)

牙膏發表於2019-02-28

需求:實現禮物特效,實現特效播放,連擊邏輯,以及最終打包成本地檔案,給到後臺上傳,使用者會自動下載特效包到本地,在有特效的時候進行相關的特效播放

特效實現

特效頁面實現(部分程式碼) bodymovin的具體用法可以參考

   import lottie from "lottie-web";
   var $_lottie = document.getElementById(`vw_lottie`),
       isReady = false,
       animationData = require(`./lottie.json`);
   var frameCount = 125,    //一共多少幀,設計的動畫一般1秒25幀
       maxFirstFrame = 25,       //連擊快的時候,最大起始幀
       timeCount = 5*1000,    //動畫時間,毫秒
       onFrameTime = timeCount/frameCount,     //一幀的時間
       lastTime = 0;
   var animation = lottie.loadAnimation({
       container:$_lottie,
       renderer:`canvas`,
       loop:false,
       autoplay:false,
       animationData:animationData
   });
   export function lottieIsReady(callback){
       animation.addEventListener(`DOMLoaded`,function(){
           isReady = true;
           console.log(`lottie is ready,準備好了`);
           callback && callback.call && callback();
       })
   }
   export function lottieStart(firstFrame){
       console.log(`lottieStart`);
       if(isReady){
           firstFrame = firstFrame || 0
           lastTime = Date.now();
           animation.playSegments([firstFrame,frameCount],true);
       }
   }
   var timer = null
   export function lottieRepeatHit(){
       if(isReady){
           let now = Date.now(),
               timeDiff = now-lastTime,
               firstFrame = 0;
           firstFrame = maxFirstFrame - parseInt(timeDiff/onFrameTime);
           firstFrame = firstFrame >= 0 ? firstFrame : 0;
           lottieStart(firstFrame);
       }
   }
   
複製程式碼

主要遇到的問題:

  1. 連擊的時候,特效是怎麼展示
  2. 特效的渲染方式,(bodymovin有三種渲染方式svg,html,canvas),主要考慮的是在anroid的低端機子上的效能問題。
  3. 因為是使用者下載特效包到本地的,就是出現特效涉及的圖片會在使用者手機的相簿裡面出現,使用者有可能誤刪的情況(直接影響特效展示),或者特效圖片在相簿這個也不是很美觀
  4. bodymovin是有load的,在載入動畫json的時候,ajax load 檔案只能是http or https協議頭。

解決方案

  1. 連擊的處理;剛開始的處理是每次連擊的時候,動畫重新播放,那麼點選得快的話,就會出現動畫消失的情況(動畫有入場),解決方案是通過計算連擊的頻率,頻率越低,開始播放的地方就越趨向於0,頻率越高,開始播放的地方就越趨向於動畫完全呈現的位置。(入場 -> 完全顯示 -> 離場)
  2. 這裡,目前的做法是用canvas感覺會好一點,有遇到問題就是用canvas渲染會模糊,改成svg渲染,結果在android的機子上很卡,最後改回來canvs,優化圖片。
  3. 動畫特效相關圖片會顯示在相簿的問題,用了webpack-replace-loader,webpack-file-loader,替換data.json裡面的“png ”->”_ png _”,以及將圖片的輸出路徑也改成一樣的字尾
  4. 在例項化Lottie的時候,不傳path,用webpzck-json-Loader,把json轉成物件傳到animationData引數裡面去。

小坑

  • 在做其他特效的時候,遇到了一個需求是需要動態變化動畫裡面的一些元素,所以監聽了complete 這個事件,這個事件有兩個坑
    • 不是一幀才回撥一次
    • 安卓或者效能差點的手機會出現掉幀的情況,也就是說如果針對某一幀去做一些操作的話,是有可能會執行不到的。

相關文章