复制并粘贴自定义 FabricJS 对象

Copy & paste custom FabricJS object

我正在尝试在我的 FabricJS 项目中复制和粘贴对象。

是FabricJS版本2.3.3

对于本机 FabricJS 对象,它工作正常。与演示中的完全一样 (http://fabricjs.com/copypaste).

但是在我创建自定义 Class 之后(例如这里 http://fabricjs.com/cross我无法根据我的自定义粘贴对象 Class。复制没问题,就是粘贴函数报错

我得到的只是控制台日志中的错误:this._render 不是指向 FabricJS 库中某些行号的函数

谁能告诉我为什么?谢谢!

这是我的习惯 Class:

const C_Cross = fabric.util.createClass(fabric.Object, {

    initialize: function(options) {
        this.callSuper('initialize', options);

        this.width = 100;
        this.height = 100;

        this.w1 = this.h2 = 100;
        this.h1 = this.w2 = 30;
    },

    _render: function (ctx) {
        ctx.fillRect(-this.w1 / 2, -this.h1 / 2, this.w1, this.h1);
        ctx.fillRect(-this.w2 / 2, -this.h2 / 2, this.w2, this.h2);
    }

});

这是 HTML 文件:(仅限 BODY 标签)

<body>

<canvas id="c" width="1000" height="800" style="border:1px solid #ccc"></canvas>

<br>

<button onclick="testCopy()">COPY</button>
<button onclick="testPaste()">PASTE</button>


<script type="text/javascript">
    var TheCanvas = new fabric.Canvas('c');

    var myCross = new C_Cross({ top: 100, left: 100 });
    TheCanvas.add(myCross);
</script>

</body>

复制和粘贴功能如下:

function testCopy(){
    TheCanvas.getActiveObject().clone(function(cloned) {
        TheClipboard = cloned;
    });
}

function testPaste(){
    TheClipboard.clone(function(clonedObj) {
        TheCanvas.discardActiveObject();
        clonedObj.set({
            left: clonedObj.left + 10,
            top: clonedObj.top + 10,
            evented: true,
        });
        if (clonedObj.type === 'activeSelection') {
            // active selection needs a reference to the canvas
            clonedObj.canvas = canvas;
            clonedObj.forEachObject(function(obj) {
                TheCanvas.add(obj);
            });
            // this should solve the unselectability
            clonedObj.setCoords();
        } else {
            TheCanvas.add(clonedObj);
        }
        TheClipboard.top += 10;
        TheClipboard.left += 10;
        TheCanvas.setActiveObject(clonedObj);
        TheCanvas.requestRenderAll();
    });
}

这是 FabricJS 库中崩溃的一段代码: 在这个函数的最后一行。

drawObject: function(ctx) {
      this._renderBackground(ctx);
      this._setStrokeStyles(ctx, this);
      this._setFillStyles(ctx, this);
      this._render(ctx); // <--- crashes here
},

您需要为您的自定义 class 添加 fromObject。并且需要定义 type 与 class 名称相同,需要在查找特定 class.

时阅读

演示版

fabric.Cross = fabric.util.createClass(fabric.Object, {
  type: 'cross',
  initialize: function(options) {
    this.callSuper('initialize', options);

    this.width = 100;
    this.height = 100;

    this.w1 = this.h2 = 100;
    this.h1 = this.w2 = 30;
  },

  _render: function(ctx) {
    ctx.fillRect(-this.w1 / 2, -this.h1 / 2, this.w1, this.h1);
    ctx.fillRect(-this.w2 / 2, -this.h2 / 2, this.w2, this.h2);
  }

});

fabric.Cross.fromObject = function(object, callback) {
  var cross = new fabric.Cross(object);
  callback && callback(cross);
  return cross;
};

var TheCanvas = new fabric.Canvas('c');

var myCross = new fabric.Cross({
  top: 100,
  left: 100
});
TheCanvas.add(myCross);

function testCopy() {
  TheCanvas.getActiveObject().clone(function(cloned) {
    TheClipboard = cloned;
    console.log(TheClipboard)
  });
}

function testPaste() {
  TheClipboard.clone(function(clonedObj) {
    TheCanvas.discardActiveObject();
    clonedObj.set({
      left: clonedObj.left + 10,
      top: clonedObj.top + 10,
      evented: true,
    });
    if (clonedObj.type === 'activeSelection') {
      // active selection needs a reference to the canvas
      clonedObj.canvas = TheCanvas;
      clonedObj.forEachObject(function(obj) {
        TheCanvas.add(obj);
      });
      // this should solve the unselectability
      clonedObj.setCoords();
    } else {
      TheCanvas.add(clonedObj);
    }
    TheClipboard.top += 10;
    TheClipboard.left += 10;
    TheCanvas.setActiveObject(clonedObj);
    TheCanvas.requestRenderAll();
  });
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="400" height="400" style="border:1px solid #ccc"></canvas>
<br>
<button onclick="testCopy()">COPY</button>
<button onclick="testPaste()">PASTE</button>