JavaScript前端實現(xiàn)GIF圖片循環(huán)播放
前言
使用 img 加載 GIF 圖片,內(nèi)容只會播放一次,之后就會自動暫停;
通過定時器在一段時間后重新加載圖片的方式,會導(dǎo)致瀏覽器內(nèi)存不斷增大,并且可能會有閃爍、卡頓的問題;
ImageDecoder
WebCodecs API 的 ImageDecoder 接口提供了一種對編碼圖像數(shù)據(jù)進行解包和解碼的方法。

ImageDecoder 只能在 localhost 或者 https 的 tab 頁中獲取到
代碼
1.canvas 設(shè)置 width 和 height,和 GIF 圖片尺寸一致
<canvas width="1310" height="954"></canvas>
或許你也可以通過一下方法動態(tài)設(shè)置尺寸;
const img = new Image();
img.src = '圖片路徑';
img.onload = function() {
var width = this.width; // 圖片寬度
var height = this.height; // 圖片高度
console.log(`圖片尺寸為:${width} x ${height}`);
// some code...
// 為canvas 設(shè)置 width、height
};
2.通過 fetch 獲取 GIF 圖片資源,傳入 url
fetch(url).then((response) => decodeImage(response.body));
3.decodeImage 方法對圖片解碼
imageDecoder = new ImageDecoder({ data: imageByteStream, type: "image/gif" });
imageDecoder.decode({ frameIndex: imageIndex }).then(renderImage);
4.renderImage 渲染每一幀的圖片
function renderImage (result) {
const canvas = document.querySelector("canvas");
const canvasContext = canvas.getContext("2d");
// 繪制圖片
canvasContext.drawImage(result.image, 0, 0);
const track = imageDecoder.tracks.selectedTrack;
if (imageDecoder.complete) {
if (track.frameCount === 1) return;
// 如果序號超出了幀數(shù),重置為 0
if (imageIndex + 1 >= track.frameCount) imageIndex = 0;
}
// 解碼下一幀圖片并渲染
imageDecoder
.decode({ frameIndex: ++imageIndex })
.then((nextResult) =>
setTimeout(() => {
renderImage(nextResult);
}, result.image.duration / 1000) // 可以調(diào)整播放速度
)
.catch((e) => {
if (e instanceof RangeError) {
imageIndex = 0;
imageDecoder.decode({ frameIndex: imageIndex }).then(renderImage);
} else {
throw e;
}
});
}
完整代碼
<template>
<div>
<canvas width="1310" height="954"></canvas>
</div>
</template>
<script>
export default {
mounted() {
this.play(require("@/assets/images/animate.gif"));
},
play(url) {
let imageDecoder = null;
let imageIndex = 0;
function renderImage (result) {
const canvas = document.querySelector("canvas");
const canvasContext = canvas.getContext("2d");
canvasContext.drawImage(result.image, 0, 0);
const track = imageDecoder.tracks.selectedTrack;
if (imageDecoder.complete) {
if (track.frameCount === 1) return;
if (imageIndex + 1 >= track.frameCount) imageIndex = 0;
}
imageDecoder
.decode({ frameIndex: ++imageIndex })
.then((nextResult) =>
setTimeout(() => {
renderImage(nextResult);
}, result.image.duration / 1000)
)
.catch((e) => {
if (e instanceof RangeError) {
imageIndex = 0;
imageDecoder.decode({ frameIndex: imageIndex }).then(renderImage);
} else {
throw e;
}
});
}
function decodeImage (imageByteStream) {
imageDecoder = new ImageDecoder({ data: imageByteStream, type: "image/gif" });
imageDecoder.decode({ frameIndex: imageIndex }).then(renderImage);
}
fetch(url).then((response) => decodeImage(response.body));
}
}
</script>
到此這篇關(guān)于JavaScript前端實現(xiàn)GIF圖片循環(huán)播放的文章就介紹到這了,更多相關(guān)JavaScript GIF圖片循環(huán)播放內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

