Search code examples
javascripthtmlanimated-gifkonvajs

How to fix glitch with gif animation when loading through Konva.js and Gifler?


I did the gif-animation loading, following the example in the documentation. However, frames are skipped and frames are displayed incorrectly.

This happens to many gif files. Please, how to fix it, does anyone know?

Here is an example error:

 var width = window.innerWidth;
      var height = window.innerHeight;

      var stage = new Konva.Stage({
        container: 'container',
        width: width,
        height: height
      });

      var layer = new Konva.Layer();
      stage.add(layer);

      var canvas = document.createElement('canvas');
      // use external library to parse and draw gif animation
      function onDrawFrame(ctx, frame) {
        // update canvas size
        canvas.width = frame.width;
        canvas.height = frame.height;
        // update canvas that we are using for Konva.Image
        ctx.drawImage(frame.buffer, 0, 0);
        // redraw the layer
        layer.draw();
      }

      gifler('https://i.gifer.com/8RDg.gif').frames(canvas, onDrawFrame);

      // draw resulted canvas into the stage as Konva.Image
      var image = new Konva.Image({
        image: canvas
      });
      layer.add(image);
<script src="https://unpkg.com/konva@4.0.4/konva.min.js"></script>
    <script src="https://unpkg.com/gifler@0.1.0/gifler.min.js"></script>
<div id="container"></div>


Solution

  • You have to try to use another library. I used libgif.js to solve this issue that is an example

      var width = window.innerWidth;
      var height = window.innerHeight;
    
      var templateImage = new Image();
    
      templateImage.onload = function(){
        // image  has been loaded
        drawKonva(templateImage);
      };
    
      templateImage.src = "https://i.gifer.com/8RDg.gif";
    

    function drawKonva(templateImage) {

      var stage = new Konva.Stage({
        container: 'container',
        width: width,
        height: height,
      });
    
      var layer = new Konva.Layer();
      stage.add(layer);
    
      var gif = new SuperGif({
        gif: templateImage,
        progressbar_height: 0,
        auto_play: true,
        loop_mode: true,
        draw_while_loading: true
      });
    
      gif.load();
    
      var gif_canvas = gif.get_canvas(); // the lib canvas
      // a copy of this canvas which will be appended to the doc
      var canvas = gif_canvas.cloneNode();
      var context = canvas.getContext('2d');
    
      function anim(t) { // our animation loop
          context.clearRect(0,0,canvas.width,canvas.height); // in case of transparency ?
          context.drawImage(gif_canvas, 0, 0); // draw the gif frame
          layer.draw();
          requestAnimationFrame(anim);
    
      };
    
      anim();
    
      // draw resulted canvas into the stage as Konva.Image
      var image = new Konva.Image({
        image: canvas,
        draggable: true
      });
      layer.add(image);
    

    }