首页 > 解决方案 > 复制和粘贴自定义 FabricJS 对象

问题描述

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

这是 FabricJS 版本2.3.3

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

但是在我创建了我的自定义 Class 之后(例如这里http://fabricjs.com/cross,我无法根据我的自定义 Class 粘贴对象。复制没问题,只是粘贴功能会抛出错误。

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

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

这是我的自定义类:

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
},

标签: javascriptfabricjsfabricjs2

解决方案


您需要fromObject为您的自定义类添加。并且需要定义type与查找特定类时需要读取的类名相同。

演示

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>


推荐阅读