h5进行svga动画礼物特效播放的代码实现队列按顺序播放
需求描述:
在直播场景中,有很多的礼物特效动画,如采用Svga动画的播放方案,则会遇到以下问题;
1.svga文件的预加载,
2.动画的顺序播放队列。即前一个动画播放完了,才会播放下一个动画。
1.svga文件的预加载,又分两种情况,
a)全部文件预先加载,到时候播放直接调用就行,但这样刚开始的时候会占用大量带宽。
b)按需加载,即在播放某个动画的时候,第一次进行加载,以后就不需要进行加载了,但第一次会有一些卡顿,可以增加一个loading的动画来改善用户体验。
2.动画的顺序播放
每当有用户赠送礼物的时候,我们会将这个动画放入动画播放队列尾部,等待其前一个动画播放完成后,再播放这个动画。防止动画交叉播放。等待上一个动画播放完成的一个重点事件是onPercentage和onFinished函数。我们用的是onPercentage函数,即播放进度。
因为我们是按顺序播放的,即是从播放队列中的第一个开始播放,所以,动画播放队列第一个播放完成后,即可删除第一个元素。然后第二个就变成了第一个,这样播放阶列越来越少。节省资源。
另外,文件缓存单独放一个队列,即svga文件缓存队列。
完整的代码如下
/**
* Created with 快兔科技 老李.
* User: 手机模板网
* Date: 2023/12/3
* Time: 15:20
* sjmoban.com
* QQ: 79089679
*/
//播放队列有几个方法
var dl = {
stData: {//状态参数
isLoading: 0,
playing: 0,
dhIndex: -1
},
filelist: [],//文件列表,因为有一些文件是重复的,所以这个存放文件即可,
//{filepath:"",loaded:0}//文件路径,是否加载了。
clearData: function () {
var that = this;
that.dhlist = [];
that.stData.isLoading = 0;
that.stData.playing = 0;
},
fn_fileIndex: function (filepath) {
var that = this;
for (var i in that.filelist) {
if (that.filelist[i].filepath == filepath) {
return i;
}
}
return -1;
},
addFile: function (svgaPath) {
var that = this;
//先看看文件在不在。
var file_init = 0;
var file_loaded = 0;
var file_index = -1;
for (var i in that.filelist) {
if (that.filelist[i].filepath == svgaPath) {//即在里面,将其加载状态也带上
file_init = 1;
file_index = i;//得到当前的
file_loaded = parseInt(that.filelist[i].loaded);
}
}
//如果文件不在里面
if (!file_init) {//即文件不在里面,加到里面,
that.filelist.push({filepath: svgaPath, loaded: 0, videoItem: {}});//不在里面
file_index = that.filelist.length - 1;//得到文件的索引值
}
//预加载加进来的这个文件
if (!that.filelist[file_init].loaded) {//即没加载,则需要加载这个文件
that.parser.load(svgaPath, function (videoItem) {//先检查这个文件是否loaded过,这样的话,就可以直接loaded了
var fi = that.fn_fileIndex(svgaPath);
if (fi >= 0) {
that.filelist[fi].videoItem = videoItem;
that.filelist[fi].loaded = 1;
}
});
}
var index = -1;
var ta = {
fileIndex: file_index,
filepath: svgaPath,
played: 0,
loaded: 0,
index: -1
};
//预加载这个文件,然后将loaded设置为1,才能正常播放,否则会播放不流畅
that.dhlist.push(ta);//增加过后,也要把这个,返回索引值
return {fileIndex: file_index, dhIndex: that.dhlist.length - 1};
},
init: function (options) {//初始化数据
var that = this;
that.player = options.player || 0;
that.parser = options.parser || 0;
that.player.onFinished = function () {//这个不是播放完成执行的函数
console.info("finished!");
};
that.clearData();
that.player.loops = 1;
that.player.clearsAfterStop = true;
that.player.onFrame(function (res) {//帧数
// console.info(res);
});
that.player.onPercentage(function (res) {//播放进度
// console.info(res);
if(res==1){//播放完了,则删除这个动画
console.info(that.stData.dhIndex);
that.dhlist.splice(that.stData.dhIndex,1);
that.play();//继续播放
}
});
},
getFirstLoaded: function () {
var that = this;
for (var i in that.dhlist) {
if (that.filelist[that.dhlist[i].fileIndex].loaded == 1) {//即文件已经加载了
return {fileIndex: that.dhlist[i].fileIndex, dhIndex: i, file: that.filelist[that.dhlist[i].fileIndex]};
}
}
return {fileIndex: -1, dhIndex: -1, file: {}, dh: {}};
},
preload: function () {//预加载
},
dhlist: [],
push: function () {//向尾部追加
},
pop: function () {//从头部
},
play_01: function () {//不是按顺序播放
var that = this;
if(that.dhlist.length==0){
return false;
}
var fo = that.getFirstLoaded();//得到第一个加载的。不一定是按顺序播放的,如果要是按顺序放的,则只播放第0个就可以了,然后删除第0个
// console.info(fo);
if (fo.fileIndex < 0) {//即没有,则调用自身//但需要延时调用自身
setTimeout(function () {
console.info(fo);
that.play();///则调用自身
}, 1000);
} else {//播放,
//
console.info(fo);
that.player.clearsAfterStop = true;
that.stData.dhIndex = parseInt(fo.dhIndex);
that.player.setVideoItem(fo.file.videoItem);
that.player.startAnimation();
}
},
play: function () {//按顺序播放,则一定要等到第一个加载完成,播放完就删除
var that = this;
if(that.dhlist.length==0){
return false;
}
// console.info(fo);
if (that.filelist[that.dhlist[0].fileIndex].loaded !=1) {//即没加载,则一直尝试着
setTimeout(function () {
that.play();///则调用自身
}, 1000);
} else {//播放,
//
that.player.clearsAfterStop = true;
that.stData.dhIndex=0;//始终播放第一个
that.player.setVideoItem(that.filelist[that.dhlist[0].fileIndex].videoItem);
that.player.startAnimation();
}
},
del: function () {
}
};
调用代码如下图