引用错误:patternSourceCanvas未定义fabric js loadFromJSON

时间:2017-12-04 05:54:28

标签: design-patterns fabricjs

我将模式应用于SVG,并使用toJSON将数据保存在数据库中。当我尝试使用loadFromJSON在画布上加载它时,它的抛出错误模式源是未定义的。

这是我用来设置模式的代码。

fabric.Image.fromURL(url,function(img){
            img.scaleToWidth(width);
            if (angle > 0) img.set('angle', angle);
            var patternSourceCanvas = new fabric.StaticCanvas();
            patternSourceCanvas.add(img);
            patternSourceCanvas.renderAll();
            var pattern = new fabric.Pattern({
                source: function() {
                    patternSourceCanvas.setDimensions({
                        width:img.getWidth() + padding,
                        height:img.getHeight() + padding
                    });
                    patternSourceCanvas.renderAll();
                    return patternSourceCanvas.getElement();
                },
                repeat: isrepeat,
                src: url,
            });

            if(left_offset > 0) { pattern.offsetX = (left_offset); } else{ pattern.offsetX = 0;}
            if(top_offset > 0) { pattern.offsetY = (top_offset); } else { pattern.offsetY = 0;}
            var applyPatternto = 0;
            if(activeView != 1){ applyPatternto = $("#sel_applyPatternto").val(); }
            currentElement.paths[applyPatternto].setFill(pattern);
            canvas.renderAll();
        });

加载保存JSON并从JSON加载我正在使用以下内容,

var frontJson  = JSON.stringify(canvas.toJSON());

从JSON加载时我还添加延迟来检查同一问题,

canvas.loadFromJSON(frontJson);
    setTimeout(function(){
        canvas.renderAll.bind(canvas);  
 },3000);

2 个答案:

答案 0 :(得分:0)

是范围问题。

您无法从JSON中重新加载具有自身引用的函数。

当函数被重建时,没有定义patternSourceCanvas来运行它。

source: function() {
  patternSourceCanvas.setDimensions({
    width:img.getWidth() + padding,
    height:img.getHeight() + padding
  });
  patternSourceCanvas.renderAll();
  return patternSourceCanvas.getElement();
},

在此上下文中,PatternSourceCanvas未定义。

即使你在内部提供了patternSourceCanvas也会无助,因为img不会在它上面绘制。

如果需要使用函数构建模式,则必须确保这些变量在渲染时在全局命名空间中可用。

还不清楚填充来自哪里,它可能会受到同样问题的影响。

答案 1 :(得分:0)

使用以下代码将Image源转换为base 64格式并存储在数据库中,然后重新打开。

JavaScript:

xdebug.default_enable=1
xdebug.remote_enable=1
xdebug.remote_handler=dbgp

xdebug.remote_port=9001
xdebug.remote_autostart=0

xdebug.remote_connect_back=1
xdebug.idekey="PHPSTORM"

xdebug.max_nesting_level = 250

css:

//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)
})

HTML:

canvas{
  border:2px solid #000;
}