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

ImageDecoder 只能在 localhost 或者 https 的 tab 頁(yè)中獲取到
代碼
1.canvas 設(shè)置 width 和 height,和 GIF 圖片尺寸一致
<canvas width="1310" height="954"></canvas>
或許你也可以通過(guò)一下方法動(dòng)態(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.通過(guò) fetch 獲取 GIF 圖片資源,傳入 url
fetch(url).then((response) => decodeImage(response.body));
3.decodeImage 方法對(duì)圖片解碼
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;
// 如果序號(hào)超出了幀數(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前端實(shí)現(xiàn)GIF圖片循環(huán)播放的文章就介紹到這了,更多相關(guān)JavaScript GIF圖片循環(huán)播放內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript實(shí)現(xiàn)時(shí)間范圍效果
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)時(shí)間范圍效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05
JS 60秒后重新發(fā)送驗(yàn)證碼的實(shí)例講解
下面小編就為大家?guī)?lái)一篇JS 60秒后重新發(fā)送驗(yàn)證碼的實(shí)例講解。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07
javascript實(shí)現(xiàn)起伏的水波背景效果
這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)起伏的水波背景效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-05-05
微信小程序新聞網(wǎng)站詳情頁(yè)實(shí)例代碼
這篇文章主要介紹了微信小程序新聞網(wǎng)站詳情頁(yè)的實(shí)例代碼,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01

