在實踐過bodymovin以後,發現若是須要在動畫裏面加邏輯比較麻煩,效果也很差。所以後面找到了另一個開源的工具,就是YY開源出來的svga,有android,ios,web版本,還有對應的AE插件,用法請看官方文檔html
之因此選擇svga:前端
問題:由於須要本地播放,因此Parse.load傳的是svga文件轉成base64以後的字符串,load會多了一步readBlobAsArrayBuffer的過程,這個很耗瀏覽器性能。android
設計經過AE+svga插件,導出一個動畫的svga格式的一個二進制文件,雖然看不到裏面的內容,可是把他扔到svga預覽,是能夠看到svga文件的一些信息的(轉換以後)ios
svga基本信息
{
"version": "2.0",
"FPS": 30,
"frames": 110,
"videoSize": {
"width": 750,
"height": 750
}
}
//素材信息
A --- {"width":600,"height":493}
Aleft --- {"width":82,"height":67}
Aright --- {"width":82,"height":67}
Avatar --- {"width":72,"height":72}
BG --- {"width":750,"height":750}
Bleft --- {"width":120,"height":97}
Bright --- {"width":120,"height":97}
Planet --- {"width":80,"height":60}
flower --- {"width":63,"height":26}
hole --- {"width":113,"height":109}
img_491 --- {"width":38,"height":38}
medal --- {"width":376,"height":415}
medal-bling-l --- {"width":66,"height":66}
複製代碼
固然,文件裏面的信息確定不僅包含上面的信息,看svga-web的源碼,裏面的reader那一部分的邏輯,應該是有包含具體到哪一幀用canvas繪製上面樣的內容的一些信息(這個好像是廢話)。git
設計大佬會給一個寶箱的svga,這邊須要作的就是經過設計大佬給一個imagekey+svga的setImage去設置寶箱開處理的禮物圖片。github
var parser = new svgaplayerweb.Parser('#canvas')
var player = new svgaplayerweb.Player('#canvas')
//之因此用這個方法去作適配是由於官方的庫設置fillMode屬性有在ios7p/8p 上面有bug,那時候沒去提issuse,不知道如今修復了沒
function setFill(){
var $_canvas = document.getElementById('canvas'),
w = window.innerWidth,
h = window.innerHeight,
screen_proportion = h/w,
svga_proportion = 16/9;
if(screen_proportion > svga_proportion){//長屏幕
$_canvas.style.width = h/svga_proportion+'px';
$_canvas.style.left = (w-h/svga_proportion)/2+'px';
}else{
$_canvas.style.height = w*svga_proportion+'px';
$_canvas.style.top = (h-w*svga_proportion)/2+'px';
}
}
//初始化
function svgaInitial(giftSrc){
// svga ready
parser.load(svgabase64,function(videoItem){
//設置寶箱開出的禮物圖片
player.setImage(giftSrc, 'gift')
player.loops = 1;
player.setVideoItem(videoItem);
player.onFinished(function(){
//播放結束後觸發離開邏輯
leave();
})
enter();
},function(err){
// alert(err.message);
//報錯直接觸發離開邏輯
leave();
})
}
複製代碼
寶箱部分禮物須要開出圖片,一部分須要開出特效,這個時候就比較爲難,最後決定的解決方案是在寶箱裏面放置了好幾段特效,分別是:寶箱打開+普通禮物(1.0)+寶箱打開+大禮物特效*N(這樣致使了一個特效包最大的差很少2M)web
//相對於1.0的版本,1.1的版本多了好幾個svga文件,多瞭如下判斷邏輯,經過參數去以爲播放哪個svga
if(giftId == 7){
svgabase64 = box_JL;
}
else if(giftId == 8){
svgabase64 = box_HD;
}
else if(giftId == 9){
svgabase64 = box_CS;
}
問題:雖然只load一份base64,不過幾個base64文件打包到一個js裏面去,會致使js的體積很大
複製代碼
寶箱須要開出的禮物有不一樣的類別(最大五種)+不一樣的數量,若是這個效果按照1.1的形式去作的話,得須要有五段不同的svga,那麼整個特效包的大小確定會超過2M。在去看文檔的時候,發現了startAnimationWithRange這個方法,播放svga動畫的某一個區間的動畫,但仍是知足不了,無奈之下fork一下倉庫,本身實現一些功能json
player.setText({
text:form,
size:form > 99 ? "160px" :"200px",
color:"linear-gradient(to right, #e1d7b4, #bfae7d)",
family:"Impact",
offset:{
x:0,
y:-10
},
textShadow:{
color:'rgba(0, 0, 0, 0.01)',
offsetX:0,
offsetY:3,
blur:3
}
},"numberone");
複製代碼
function svgaInitial(){
var len = gift.length;
var releaseGift = function(data,len){
data.forEach((item,index) => {
player.setImage(item.src,`gift-${len == 1 ? "" : len+"-"}${index+1}`);
player.setText({
text:`X${item.count}`,
size:item.count>999 ? "40px":"54px",
family:"BaiZhouRenZhe",
color: "#FFF2C8",
offset: {x: 0, y: 0}
},`gift-count-${len == 1 ? "" : len+"-"}${index+1}`)
})
}
// svga ready
parser.load(svgabase64,function(videoItem){
player.loops = 1;
releaseGift(gift,giftLen);
player.setVideoItem(videoItem);
player.onFinished(function(){
leave();
})
if(len > 0){
enter();
}
},function(err){
leave();
})
}
function enter() {
var releaseSvga = function(gift,len){
switch(len){
case 1:
player.startAnimationWithRange({location:0,length:200});
break;
case 2:
player.startAnimationWithRangeDouble([{location:0,length:150},{location:200,length:50}]);
break;
case 3:
player.startAnimationWithRangeDouble([{location:0,length:150},{location:250,length:50}]);
break;
case 4:
player.startAnimationWithRangeDouble([{location:0,length:150},{location:300,length:50}]);
break;
case 5:
player.startAnimationWithRangeDouble([{location:0,length:150},{location:350,length:50}]);
break;
}
}
releaseSvga(gift,giftLen)
}
//相對於1.1的版本,此次1.2的版本減小了打包以後總體的體積,可是由於是所有動畫都在一個svga文件,單個的svga的文件比較大,所以load起來的速度也會慢一些。
複製代碼
bodymovin,svga幫助咱們解脫了看着mov寫特效,而後設計師坐在旁邊花費不少時間去調試到滿意的結果的日子。讓前端能夠更注重寫邏輯這塊的代碼。canvas
原本是想在每一個版本上面都加上動畫的gif的,奈何md的寫法添加圖片比較煩,或者須要一個圖片服務器上傳圖片纔好,又不想用富文本編輯器去寫,因此就沒放了。api