具有子类对象的fabricjs loadFromJSON问题

时间:2015-10-14 17:24:02

标签: canvas subclass fabricjs

我想要渲染一些我先前保存在数据库中的画布对象。

我的问题非常类似于https://groups.google.com/forum/#!topic/fabricjs/1hykgQ0aVhE。 不幸的是,纠正后的jsFiddle无效。

我正在使用自定义子类LabeledRect,如fabricjs.com/fabric-intro-part-3/所述 我按照Google论坛论坛中的建议修改了LabelRectLabelrect的名称。

我尝试使用enlivenObjects方法,但没有解决我的问题。

我在jsFiddle和下面的代码段中发布了我的代码:

fabric.Labeledrect = fabric.util.createClass(fabric.Rect, {

  type: 'labeledRect',

  initialize: function(options) {
    options || (options = {});

    this.callSuper('initialize', options);
    this.set('id', options.id || '');
    this.set('label', options.label || '');
    this.set('htmlContent', options.htmlContent || '');
  },

  toObject: function() {
    return fabric.util.object.extend(this.callSuper('toObject'), {
      label: this.get('label'),
      htmlContent: this.get('htmlContent'),
      id: this.get('id')
    });
  },

  _render: function(ctx) {
    this.callSuper('_render', ctx);

    ctx.font = '20px skf_chevin_medium';
    ctx.fillStyle = '#333';
    ctx.fillText(this.label, -this.width / 2, -this.height / 2 + 20, this.width);

    ctx.font = "20px skf_chevin_medium";
    // Create gradient
    var gradient = ctx.createLinearGradient(0, 0, c.width, 0);
    gradient.addColorStop("0", "magenta");
    gradient.addColorStop("0.5", "blue");
    gradient.addColorStop("1.0", "red");
    // Fill with gradient
    ctx.fillStyle = gradient;
    ctx.fillText(this.htmlContent, -this.width / 2, -this.height / 2 + 40, this.width);
  },
});



//fabric.Labeledrect.fromObject = function (object, callback) {
//    var _enlivenedObjects;
//    fabric.util.enlivenObjects(object.objects, function (enlivenedObjects) {
//        delete object.objects;
//        _enlivenedObjects = enlivenedObjects;
//    });
//    return new fabric.Labeledrect(_enlivenedObjects, object);
//};

fabric.Labeledrect.fromObject = function(object, callback) {
  fabric.util.enlivenObjects(object.objects, function(enlivenedObjects) {
    delete object.objects;
    callback && callback(new fabric.Labeledrect(enlivenedObjects, object));
  });
};
fabric.Labeledrect.async = true;

var canvas = new fabric.Canvas('c', {
  backgroundColor: 'rgb(100,100,200)',
  selectionColor: 'blue',
  selectionLineWidth: 2
});
canvas.on({
  'object:selected': selectedObject
});




function selectedObject() {
  var id = canvas.getActiveObject().get('id');
  alert("id: " + id);
}

function addArea(areaCode, areaID) {
  var labeledRectObj = new fabric.Labeledrect({
    width: 100,
    height: 50,
    left: 100,
    top: 100,
    label: areaCode,
    fill: '#ccc',
    htmlContent: 'test html',
    id: areaID
  });
  canvas.add(labeledRectObj);
  canvas.setActiveObject(labeledRectObj);
}

$("#addArea1").click(function() {

  addArea("A01", 1);
});

$("#addArea2").click(function() {
  addArea("A02", 2);
});


$("#reload").click(function() {
  var canvasJson = canvas.toJSON();
  alert(JSON.stringify(canvasJson));
  canvas.loadFromJSON(canvasJson, canvas.renderAll.bind(canvas));
  //the canvas is not getting rendered
});
<input type="button" id="addArea1" value="Area 1">
<input type="button" id="addArea2" value="Area 2">
<div id="canvas-container" style="overflow-x:scroll;overflow-y:scroll;">
  <canvas id="c" height="400" width="300" style="border:1px solid #ccc;"></canvas>
</div>
<input type="button" id="reload" value="Reload Objects">

我得到的错误是“无法读取未定义的属性'async'

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

自定义类的type属性未命名为propertyly。查看更新的fiddler

答案 1 :(得分:0)

这是一个老问题,但我最近在调用loadFromJson时反序列化自定义子类的类似错误,例如"Cannot read property 'fromObject' of undefined",我所学到的可能会帮助其他人。通过检查1.7.19源代码,我发现我必须改变关于子类的两件事:

  1. 我的子类需要在fabric命名空间中声明。以前我在宣布他们是另一个班级的成员。

  2. 我的子类必须有一个fromObject函数,它必须与子类本身分开声明。以前我在传递给fromObject的参数对象中声明createClass

  3. 这是一份工作宣言:

        fabric.MyText = fabric.util.createClass(fabric.Text, {
            type: 'MyText',
    
            // The following code results in "klass.fromObject is not a function"
            //fromObject: function(object, callback, forceAsync) {
            //    return fabric.Object._fromObject('MyText', object, callback, forceAsync, 'text');
            //},
    
            ... my specializations ...
        });
    
        fabric.MyText.fromObject = function (object, callback, forceAsync) {
            return fabric.Object._fromObject('MyText', object, callback, forceAsync, 'text');
        };