0

我在保存和加载应用于对象的动态模式时遇到问题。

我在网上搜索了解决此问题的方法,但无济于事。我明白它为什么会发生,但不明白如何解决它。

这基本上就是我正在做的......

  1. 将动态模式应用于对象。
  2. 使用...'JSON.stringify(canvas.toJSON([...]))' 将画布保存到 MongoDB
  3. 使用“loadFromJSON”加载画布
  4. 收到错误“未捕获的 ReferenceError:patternSourceCanvas 未定义”

我在这个问题上发现的一切都可以追溯到至少 2 年前(有些甚至是 2013 年),没有可靠的代码示例。

更新

这是我用来在路径上应用模式的功能......

function applyPatternOnPath(p, image, width, patternRepeat, patternPadding) {

    if (patternRepeat) {
      var r = 'repeat'
    } else {
      var r = 'no-repeat'
    }

    fabric.Image.fromURL(image, function(img) {

      var padding = 0 + patternPadding;

      img.scaleToWidth(width);

      var patternSourceCanvas = new fabric.StaticCanvas();

      patternSourceCanvas.add(img);
      patternSourceCanvas.renderAll();

      var pattern = new fabric.Pattern({
        source: function() {
          patternSourceCanvas.setDimensions({
            width: img.getScaledWidth() + padding,
            height: img.getScaledHeight() + padding
          });
          patternSourceCanvas.renderAll();
          return patternSourceCanvas.getElement();
        },
        repeat: r
      });

      p.set('fill', pattern);
      canvas.renderAll();

    }, { crossOrigin: 'Anonymous' });
  }
4

2 回答 2

1

我已经通过一些解决方法解决了我的问题。我不确定这是否是处理使用 JSON 保存的动态模式的“正确”方法,但它对我有用。

这就是我正在做的...

  1. 将动态模式应用于对象。
  2. 在将画布(JSON 字符串)保存到 MongoDB 之前,我正在做两件事......

    a) 将对象信息(包括模式 src、宽度、填充等)保存在 mongoDB 文档的一个名为“canvasLayers”的字段中。

    b) 通过将“填充”属性设置为“”来清除应用了动态模式的路径的所有“填充”属性。

    因此 JSON 在保存到数据库时不包含任何模式信息。

  3. 加载以前保存的画布时,我正在根据每个对象的“canvasLayers”字段中保存的模式信息重新应用模式。

基本上,我不是用 JSON 字符串保存模式信息,而是将模式数据存储在单独的对象(mongodb 字段)上,然后在画布加载时重新应用模式。

于 2018-04-08T05:33:31.667 回答
0

使用下面的代码将图像源转换为 base 64 格式并存储并重新打开它。

//override toObject of fabric.Pattern
var toFixed = fabric.util.toFixed;
fabric.Pattern.prototype.toObject = function(propertiesToInclude) {
  var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,
    source, object;
  if (typeof this.source === "function") {
    source = String(this.source);
  } else if (typeof this.source.src === "string") {
    source = this.source.src;
  } else if (typeof this.source === "object" && this.source.toDataURL) {
    source = this.source.toDataURL();
  }
  object = {
    type: "pattern",
    source: source,
    repeat: this.repeat,
    crossOrigin: this.crossOrigin,
    offsetX: toFixed(this.offsetX, NUM_FRACTION_DIGITS),
    offsetY: toFixed(this.offsetY, NUM_FRACTION_DIGITS),
    patternTransform: this.patternTransform ? this.patternTransform.concat() : null
  };
  fabric.util.populateWithProperties(this, object, propertiesToInclude);
  return object;
};



var imageUrl = 'https://upload.wikimedia.org/wikipedia/commons/2/22/Wikimapia_logotype.svg';
var canvas = new fabric.Canvas('canvas');
var rect = new fabric.Rect({
  width: 200,
  height: 200,
  strokeWidth: 2,
  stroke: '#000'
})
canvas.add(rect);

fabric.Image.fromURL(imageUrl, function(img) {
  //alert('t' + img);
  console.log('img', img);
  img.scaleToHeight(200);
  var patternSourceCanvas = new fabric.StaticCanvas();
  patternSourceCanvas.add(img);
  patternSourceCanvas.setDimensions({
    width: img.getWidth(),
    height: img.getHeight()
  });
  patternSourceCanvas.renderAll();
  var pattern = new fabric.Pattern({
    source: patternSourceCanvas.getElement()
  });
  rect.fill = pattern;
  canvas.renderAll();
}, {
  crossOrigin: 'annonymous'
});

$('#loadjson').on('click', function() {
  var json = canvas.toJSON();
  console.log('json', json['objects']);
  canvas.clear();
  setTimeout(function() {
    canvas.loadFromJSON(json, canvas.renderAll.bind(canvas));
  }, 3000)
})

CSS

canvas{
  border:2px solid #000;
}

网页:

<canvas id="canvas" width="300" height="300"></canvas><br>
<button  id="loadjson">loadfromjson </button>


<script src='https://www.multicastr.com/imageeditor/assets/js/fabric.unmin.js'></script>

<script src="https://www.multicastr.com/user/js/jquery.min.js"></script>
于 2018-07-19T10:18:47.520 回答