canvas 在 LoadFromJson 之后抛出 tainted 错误

canvas is throw error of tainted after LoadFromJson

我正在使用 fabric js 版本 1.7.22

当图片在fabric js的矩形中重复设置时,在 第一次使用 toJSON() 加载并保存到 JSON 并使用 todataUrl() 方法保存图像,但是当调用 canvas 一个 loadFromJson 方法时,这个 canvas 不可保存,因为它会抛出受污染的 canvas 错误。

请帮帮我,

我已经在模式中设置了 crossOrigin,但它不起作用。并不是 添加于 canvas JSON.

我已经制作了一个 Fiddle 用于生成问题:

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

生成问题的步骤:

点击'set pattern'

然后点击 'save canvas'

然后点击 'reload canvas' // 从 JSON

加载 canvas

然后点击 'save canvas' // 导致问题 canvas

此问题已在新版本的 fabricjs 中修复。如果您仍在使用 1.7.20 覆盖 fabric.Pattern.prototype.toObjectfabric.Pattern.prototype.initialize,请在片段中查找代码。

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>