我试图只显示一次GIF图片,所以我使用了以下代码来实现。
var ui_img = document.getElementById("ui_image");
ui_img.hidden = false;
setTimeout(function () {
ui_img.hidden = true;
}, 8000);
但我知道所有的gif并不具有相同的持续时间。 我该如何解决这个问题?
我试图只显示一次GIF图片,所以我使用了以下代码来实现。
var ui_img = document.getElementById("ui_image");
ui_img.hidden = false;
setTimeout(function () {
ui_img.hidden = true;
}, 8000);
但我知道所有的gif并不具有相同的持续时间。 我该如何解决这个问题?
parseGIF()
函数,然后使用decompressFrames()
函数获取一个frame数组,每个frame有一个delay
属性,表示该frame显示的时间。所以,你可以将所有frame的delay相加,得到GIF图像的总持续时间。import { parseGIF, decompressFrames } from 'gifuct-js'
var oReq = new XMLHttpRequest();
oReq.open("GET", gifURL, true);
oReq.responseType = "arraybuffer";
oReq.onload = function (oEvent) {
var arrayBuffer = oReq.response; // Note: not oReq.responseText
if (arrayBuffer) {
var gif = parseGIF(arrayBuffer);
var frames = decompressFrames(gif, true);
// do something with the frame data
// get total time in ms
var totalTime = frames
.map(frame => frame.delay)
.reduce((a, b) => a + b);
}
};
oReq.send(null);
这将返回持续时间值
isGifAnimated(file) {
return new Promise((resolve, reject) => {
try {
let fileReader = new FileReader();
fileReader.readAsArrayBuffer(file);
fileReader.onload = (event) => {
let arr = new Uint8Array(fileReader.result);
let duration = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i] == 0x21
&& arr[i + 1] == 0xF9
&& arr[i + 2] == 0x04
&& arr[i + 7] == 0x00) {
const delay = (arr[i + 5] << 8) | (arr[i + 4] & 0xFF)
duration += delay < 2 ? 10 : delay;
}
}
resolve(duration / 100);
}
} catch (e) {
reject(e);
}
});
}
fetch('https://media0.giphy.com/media/FIHThOlkZK3r8HTj9t/giphy.gif')
.then(res => res.arrayBuffer())
.then(ab => isGifAnimated(new Uint8Array(ab)))
.then(console.log)
/** @param {Uint8Array} uint8 */
function isGifAnimated (uint8) {
let duration = 0
for (let i = 0, len = uint8.length; i < len; i++) {
if (uint8[i] == 0x21
&& uint8[i + 1] == 0xF9
&& uint8[i + 2] == 0x04
&& uint8[i + 7] == 0x00)
{
const delay = (uint8[i + 5] << 8) | (uint8[i + 4] & 0xFF)
duration += delay < 2 ? 10 : delay
}
}
return duration / 100
}