FabricJs:从JSON(patternSourceCanvas)保存和加载动态模式

时间:2018-04-05 05:07:33

标签: javascript json serialization fabricjs fabricjs2

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

我已经在网上搜索了解决方案但无济于事。我理解why it is happening,但不明白如何解决它。

这基本上就是我在做什么......

  1. 将动态模式应用于对象。
  2. 使用...'JSON.stringify(canvas.toJSON([...]))'
  3. 将画布保存到MongoDB
  4. 使用'loadFromJSON'
  5. 加载画布
  6. 获取错误'未捕获的ReferenceError:未定义patternSourceCanvas'
  7. 我在这个问题上找到的所有内容都可以追溯到至少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' });
      }
    

2 个答案:

答案 0 :(得分:1)

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

这就是我在做什么......

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

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

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

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

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

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

答案 1 :(得分:0)

使用下面的代码将Image源转换为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>