需求:實現禮物特效,實現特效播放,連擊邏輯,以及最終打包成本地檔案,給到後臺上傳,使用者會自動下載特效包到本地,在有特效的時候進行相關的特效播放
特效實現
特效頁面實現(部分程式碼) 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);
}
}
複製程式碼
主要遇到的問題:
- 連擊的時候,特效是怎麼展示
- 特效的渲染方式,(bodymovin有三種渲染方式svg,html,canvas),主要考慮的是在anroid的低端機子上的效能問題。
- 因為是使用者下載特效包到本地的,就是出現特效涉及的圖片會在使用者手機的相簿裡面出現,使用者有可能誤刪的情況(直接影響特效展示),或者特效圖片在相簿這個也不是很美觀
- bodymovin是有load的,在載入動畫json的時候,ajax load 檔案只能是http or https協議頭。
解決方案
- 連擊的處理;剛開始的處理是每次連擊的時候,動畫重新播放,那麼點選得快的話,就會出現動畫消失的情況(動畫有入場),解決方案是通過計算連擊的頻率,頻率越低,開始播放的地方就越趨向於0,頻率越高,開始播放的地方就越趨向於動畫完全呈現的位置。(入場 -> 完全顯示 -> 離場)
- 這裡,目前的做法是用canvas感覺會好一點,有遇到問題就是用canvas渲染會模糊,改成svg渲染,結果在android的機子上很卡,最後改回來canvs,優化圖片。
- 動畫特效相關圖片會顯示在相簿的問題,用了webpack-replace-loader,webpack-file-loader,替換data.json裡面的“png ”->”_ png _”,以及將圖片的輸出路徑也改成一樣的字尾
- 在例項化Lottie的時候,不傳path,用webpzck-json-Loader,把json轉成物件傳到animationData引數裡面去。
小坑
- 在做其他特效的時候,遇到了一個需求是需要動態變化動畫裡面的一些元素,所以監聽了complete 這個事件,這個事件有兩個坑
- 不是一幀才回撥一次
- 安卓或者效能差點的手機會出現掉幀的情況,也就是說如果針對某一幀去做一些操作的話,是有可能會執行不到的。