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-05JS 60秒后重新發(fā)送驗(yàn)證碼的實(shí)例講解
下面小編就為大家?guī)?lái)一篇JS 60秒后重新發(fā)送驗(yàn)證碼的實(shí)例講解。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07javascript實(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