Animated GIF on Fabric.js Canvas

前端 未结 3 930
青春惊慌失措
青春惊慌失措 2020-12-16 07:00

I\'m working on a project where I\'ve been asked to support animated GIF on a fabric.js canvas.

As per https://github.com/kangax/fabric.js/issues/560, I\'ve followed

3条回答
  •  有刺的猬
    2020-12-16 07:04

    var canvas = new fabric.Canvas(document.getElementById('stage'));
    var url = 'https://themadcreator.github.io/gifler/assets/gif/run.gif';
    fabric.Image.fromURL(url, function(img) {
      img.scaleToWidth(80);
      img.scaleToHeight(80);
      img.left = 105;
      img.top = 30;
      gif(url, function(frames, delay) {
        var framesIndex = 0,
          animInterval;
        img.dirty = true;
        img._render = function(ctx) {
          ctx.drawImage(frames[framesIndex], -this.width / 2, -this.height / 2, this.width, this.height);
        }
        img.play = function() {
          if (typeof(animInterval) === 'undefined') {
            animInterval = setInterval(function() {
              framesIndex++;
              if (framesIndex === frames.length) {
                framesIndex = 0;
              }
            }, delay);
          }
        }
        img.stop = function() {
          clearInterval(animInterval);
          animInterval = undefined;
        }
        img.play();
        canvas.add(img);
      })
    
    })
    
    
    function gif(url, callback) {
    
      var tempCanvas = document.createElement('canvas');
      var tempCtx = tempCanvas.getContext('2d');
    
      var gifCanvas = document.createElement('canvas');
      var gifCtx = gifCanvas.getContext('2d');
    
      var imgs = [];
    
    
      var xhr = new XMLHttpRequest();
      xhr.open('get', url, true);
      xhr.responseType = 'arraybuffer';
      xhr.onload = function() {
        var tempBitmap = {};
        tempBitmap.url = url;
        var arrayBuffer = xhr.response;
        if (arrayBuffer) {
          var gif = new GIF(arrayBuffer);
          var frames = gif.decompressFrames(true);
          gifCanvas.width = frames[0].dims.width;
          gifCanvas.height = frames[0].dims.height;
    
          for (var i = 0; i < frames.length; i++) {
            createFrame(frames[i]);
          }
          callback(imgs, frames[0].delay);
        }
    
      }
      xhr.send(null);
    
      var disposalType;
    
      function createFrame(frame) {
        if (!disposalType) {
          disposalType = frame.disposalType;
        }
    
        var dims = frame.dims;
    
        tempCanvas.width = dims.width;
        tempCanvas.height = dims.height;
        var frameImageData = tempCtx.createImageData(dims.width, dims.height);
    
        frameImageData.data.set(frame.patch);
    
        if (disposalType !== 1) {
          gifCtx.clearRect(0, 0, gifCanvas.width, gifCanvas.height);
        }
    
        tempCtx.putImageData(frameImageData, 0, 0);
        gifCtx.drawImage(tempCanvas, dims.left, dims.top);
        var dataURL = gifCanvas.toDataURL('image/png');
        var tempImg = fabric.util.createImage();
        tempImg.src = dataURL;
        imgs.push(tempImg);
      }
    }
    render()
    
    function render() {
      if (canvas) {
        canvas.renderAll();
      }
    
      fabric.util.requestAnimFrame(render);
    }
    #stage {
      border: solid 1px #CCCCCC;
    }
    
    
    

提交回复
热议问题