jnordberg / gif.js

JavaScript GIF encoding library

Home Page:http://jnordberg.github.io/gif.js/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Rendered GIF has black frames

kulverstukas1 opened this issue · comments

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>

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();
    });