【问题标题】:FabricJs: Saving and loading dynamic patterns from JSON (patternSourceCanvas)FabricJs:从 JSON (patternSourceCanvas) 保存和加载动态模式
【发布时间】:2018-09-14 19:30:29
【问题描述】:

我在保存和加载应用于对象的dynamic patterns 时遇到问题。

我在网上搜索了解决此问题的方法,但无济于事。我了解why it is happening,但不明白如何解决。

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

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

我在这个问题上发现的一切都可以追溯到至少 2 年前 (some even 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' });
  }

【问题讨论】:

  • 我不确定,但是,**new fabric.StaticCanvas()** 在这一行,我认为您需要传递元素 ID ( canvas element id ) 参考:fabricjs.com/static_canvas。另外,如果您将画布保存到数据库,我认为您应该使用**canvas.toDatalessJSON** 并使用**canvas.loadFromDatalessJSON** 加载。这样可以最大限度地减少数据。
  • 我的主画布的元素 id 为 'c',所以如果我尝试使用新的 fabric.StaticCanvas('c'),当应用图案时,整个画布会变得混乱(调整大小) .感谢 toDatalessJson 提示。

标签: javascript json serialization fabricjs fabricjs2


【解决方案1】:

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

这就是我正在做的......

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

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

    b) 通过将 'fill' 属性设置为 "" 来清除应用了动态模式的路径的所有 'fill' 属性。

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

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

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

【讨论】:

  • 我遇到了与上述相同的问题。是的,完美。您能否更详细地解释一下。如果您能上传相同的代码,那就太好了。
【解决方案2】:

使用以下代码将图像源转换为 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;
}

HTML:

<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-12-23
    • 2017-03-13
    • 2013-08-24
    • 2012-07-02
    • 2021-01-06
    • 2018-09-16
    • 1970-01-01
    • 1970-01-01
    • 2019-12-01
    相关资源
    最近更新 更多