You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.4 KiB
JavaScript

class GifPlayer {
/**
*
* @param {*} template 图片模板路径:变量,{i}
* @param {*} num 图片的总数{i}=0~(num-1), 默认34
* @param {*} canvas 画布
* @param {*} radioRate 播放速率比,0=不播放 默认1
*/
constructor(template, num, canvas, radioRate) {
this.load = false;
this.canvas = canvas;
this.radioRate = radioRate;
this.ctx = this.canvas.getContext('2d');
// this.ctx.save();
this.#init(template, num);
}
async #init(template, num) {
this.imgs = await this.loadImgs(template, num);
this.canvas.dispatchEvent(new CustomEvent('loadend', { bubbles: false }))
this.load = true;
this.canvas.width = this.imgs[0].naturalWidth * window.devicePixelRatio;
this.canvas.height = this.imgs[0].naturalHeight * window.devicePixelRatio;
this.i = 0;
this.time = Date.now();
this.playing = true;
this.ctx.drawImage(this.imgs[0], 0, 0, this.canvas.width, this.canvas.height);
this.#backgroudPlay();
}
/**
* 加载图片
* @param {*} template 图片模板路径:变量,{i}
* @param {*} num 图片的总数{i}=0~(num-1), 默认34
*/
loadImgs(template, num = 34) {
return new Promise((resolve, reject) => {
const imgs = [];
const ps = [];
for (let i = 0; i < num; i++) {
const img = new Image();
img.src = template.replace('{i}', i);
imgs[i] = img;
ps.push(new Promise((resolve1, reject1) => {
img.onload = resolve1;
img.onerror = reject1;
}));
}
Promise.all(ps).then(() => {
resolve(imgs);
}).catch(err => {
reject(err);
})
})
}
#backgroudPlay() {
if (this.radioRate === 0 || !this.playing) {
requestAnimationFrame(() => { this.#backgroudPlay() });
return;
}
let now = Date.now();
if (now - this.time >= 50 / this.radioRate) {
this.time = now;
this.i++;
if (this.i >= this.imgs.length) {
this.i = 0;
this.canvas.dispatchEvent(new CustomEvent('loopend', { bubbles: false }))
}
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
// this.ctx.restore();
this.ctx.drawImage(this.imgs[this.i], 0, 0, this.canvas.width, this.canvas.height);
}
requestAnimationFrame(() => { this.#backgroudPlay() });
}
start() {
this.playing = true;
}
stop() {
this.playing = false;
}
}
export { GifPlayer };