canvas is throw error of tainted after LoadFromJson

457 views Asked by At

I am using fabric js version 1.7.22

when image set in a repetitive manner in a rectangle of fabric js, at the first time it will be loaded and saved into JSON using toJSON() and save an image using todataUrl() method, but when cal canvas a loadFromJson method at that time, this canvas not savable, because it throws tainted canvas error.

Please help me,

I already set crossOrigin in a pattern but it not working. and not added in canvas JSON.

I have made one Fiddle For Generate Issue :

[http://jsfiddle.net/Mark_1998/kt387vLc/1/][1]

Steps to generate issue :

click on 'set pattern'

then click on 'save canvas'

then click on 'reload canvas' // load canvas from JSON

then click on 'save canvas' // cause issue of tainted canvas

1

There are 1 answers

1
Durga On BEST ANSWER

This issue is fixed in new version of fabricjs already. If you are still using 1.7.20 the override fabric.Pattern.prototype.toObject and fabric.Pattern.prototype.initialize, find code in snippet.

var canvas = new fabric.Canvas('canvas', {
  height: 500,
  width: 500,
});
canvas.backgroundColor = '#ff0000';
canvas.renderAll();
var canvasJSON = {};

document.getElementById('setPat').addEventListener('click', function() {
  fabric.util.loadImage('https://cdn.dribbble.com/assets/icon-backtotop-1b04df73090f6b0f3192a3b71874ca3b3cc19dff16adc6cf365cd0c75897f6c0.png', function(image) {
    var pattern = new fabric.Pattern({
      source: image,
      repeat: 'repeat',
      crossOrigin: 'Anonymous'
    });
    var patternObject = new fabric.Rect({
      left: 0,
      top: 0,
      height: canvas.height,
      width: canvas.width,
      angle: 0,
      fill: pattern,
      objectCaching: false
    })
    canvas.add(patternObject);
  }, null, {
    crossOrigin: 'Anonymous'
  });
})
document.getElementById('saveCanvas').addEventListener('click', function() {
  console.log('save canvas');
  canvasJSON = canvas.toJSON();
  var image = canvas.toDataURL("image/png", {
    crossOrigin: 'Anonymous'
  }); // don't remove this, i need it as thumbnail.
  //console.log('canvas.Json', canvasJSON);
  //console.log('image', image);
  canvas.clear();
  canvas.backgroundColor = '#ff0000';
  canvas.renderAll();
});
document.getElementById('reloadCanvas').addEventListener('click', function() {
  console.log('save canvas');
  canvas.loadFromJSON(canvasJSON, function() {
    canvas.set({
      crossOrigin: 'Anonymous'
    })
  });
  console.log('canvas.Json', canvasJSON);
});

//cross origin was not added in toObject JSON
fabric.Pattern.prototype.toObject = (function(toObject) {
  return function() {
    return fabric.util.object.extend(toObject.call(this), {
      crossOrigin: this.crossOrigin,
      patternTransform: this.patternTransform ? this.patternTransform.concat() : null
    });
  };
})(fabric.Pattern.prototype.toObject);
//cross origin was not added while creating image
fabric.Pattern.prototype.initialize = function(options, callback) {
  options || (options = {});

  this.id = fabric.Object.__uid++;
  this.setOptions(options);
  if (!options.source || (options.source && typeof options.source !== 'string')) {
    callback && callback(this);
    return;
  }
  // function string
  if (typeof fabric.util.getFunctionBody(options.source) !== 'undefined') {
    this.source = new Function(fabric.util.getFunctionBody(options.source));
    callback && callback(this);
  } else {
    // img src string
    var _this = this;
    this.source = fabric.util.createImage();
    fabric.util.loadImage(options.source, function(img) {
      _this.source = img;
      callback && callback(_this);
    }, null, this.crossOrigin);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.20/fabric.js"></script>
<button id="setPat">
  Set pattern
</button>
<button id="saveCanvas">
  Save canvas
</button>
<button id="reloadCanvas">
  Reload CAnvas
</button>
<canvas id="canvas"></canvas>