Rendered GIF has black frames
kulverstukas1 opened this issue · comments
Kulverstukas commented
Hello,
I was trying out this library and noticed a strange thing happening:
I load the page, press a button to render, the GIF is rendered and displayed on the same page. But the GIF that I get has first two images replaced with a black canvas.
The interesting part is that if I press the button again, the GIF is rendered properly. If I refresh the page and do it again first time - same thing with black frames.
Here's my test code:
<html>
<head>
<script src='js/gifjs/gif.js'></script>
</head>
<body>
<input value="PRESS ME" type="button" id="hello_btn" onclick="createGif()">
<br/>
<span id="prog">Progress: 0</span>
<br/>
<br/>
<br/>
</body>
<script>
function createImgArr() {
images = [];
for (i = 1; i < 73; i++) {
url = "/img/p"+(i.toString().padStart(3, "0"))+".jpg";
img = new Image();
img.src = url;
images.push(img);
}
return images;
}
function createGif() {
var gif = new GIF({
workers: 2,
quality: 20,
workerScript: "js/gifjs/gif.worker.js",
<!-- debug: true -->
});
images = createImgArr();
for (i = 0; i < 10; i++) {
gif.addFrame(images[i], {delay: 40});
}
gif.on('finished', function(blob) {
animatedImage = document.createElement('img');
animatedImage.src = URL.createObjectURL(blob);
document.body.appendChild(animatedImage);
});
gif.on('progress', function(progress) {
document.querySelector("#prog").innerHTML = "Progress: "+progress;
});
gif.render();
}
</script>
</html>
Kulverstukas commented
Welp, I found an open issue about the same problem here: #76
And the complete solution that works for me would be this:
function waitForImagesLoaded(imageURLs, callback){
var imageElements = [];
var remaining = imageURLs.length;
var onEachImageLoad = function(){
if (--remaining === 0 && callback) {
callback(imageElements);
}
};
for (var i = 0, len = imageURLs.length; i < len; i++){
var img = new Image();
img.onload = onEachImageLoad;
img.src = imageURLs[i];
imageElements.push(img);
}
}
function createImgArr() {
images = [];
for (i = 1; i < 73; i++) {
url = "/sukeklio-interfeisas/img/Export_small/p"+(i.toString().padStart(3, "0"))+".jpg";
images.push(url);
}
return images;
}
and then in createGif()
:
waitForImagesLoaded(createImgArr(), function(images) {
for (var i = 0; i < 10; i++) {
gif.addFrame(images[i], {delay: 40});
}
gif.render();
});