如何创建自定义 fabricjs 对象?

How to create custom fabricjs object?

我必须创建一个 自定义 fabricjs 对象(比如,fabric.Demo),它 扩展了 fabric.Group 对象. fabric.Demo 个对象将 用于组合其他两个 fabric.Group 个对象。我在 Internet 上搜索过,发现只有这些链接有用。

  1. Link 1
  2. Link 2

但我收到此错误 'this._objects is undefined'。我知道我没有写 _render()。但我不明白在 _render() 中编写什么代码。如果有人知道答案,将不胜感激。

这是我的代码。

(function (global) {

    var fabric = global.fabric || (global.fabric = {}),
            extend = fabric.util.object.extend,
            clone = fabric.util.object.clone;

    var stateProperties = fabric.Text.prototype.stateProperties.concat();
    stateProperties.push(
            'top',
            'left'
            );

    fabric.Demo = fabric.util.createClass(fabric.Group, {
        type: 'demo',
        initialize: function () {

            this.grp = new fabric.Group([], {
                selectable: false,
                padding: 0
            });

            this.grp.add([
                new fabric.Group([
                    new fabric.Text('A', {top: 200, left: 200}),
                    new fabric.Text('B', {top: 200, left: 200})
                ]),
                new fabric.Group([
                    new fabric.Text('C', {top: 200, left: 200}),
                    new fabric.Text('D', {top: 200, left: 200})
                ])
            ]);
        },
        _render: function (ctx) {

        }
    });
})(typeof exports !== 'undefined' ? exports : this);

$(document).ready(function() {
    var canvas = new fabric.Canvas('c');
    var abc = new fabric.Demo();
    canvas.add(abc);
});

如果你想扩展 Group,你必须尊重它的基本功能,渲染存储在 _objects 数组中的一些对象。

因此,当您初始化 class 时,请不要创建 this.grp

而是将您的 2 个组推入一个 _objects 数组。

fabric.Demo = fabric.util.createClass(fabric.Group, {
        type: 'demo',
        initialize: function () {

            this.grp = new fabric.Group([], {
                selectable: false,
                padding: 0
            });

            this._objects.push(
                new fabric.Group([
                    new fabric.Text('A', {top: 200, left: 200}),
                    new fabric.Text('B', {top: 200, left: 200})
                ]));
            this._objects.push(
                new fabric.Group([
                    new fabric.Text('C', {top: 200, left: 200}),
                    new fabric.Text('D', {top: 200, left: 200})
                ]));
        }
    });
})(typeof exports !== 'undefined' ? exports : this);

扩展渲染函数,思考你需要的不同于标准组的东西,如果你想加载和恢复你的 canvas.

,不要忘记放置 fromObject 函数

这是内部使用组的 fabric JS 自定义对象。

(function (fabric) {
 "use strict";

fabric.CustomObject = fabric.util.createClass(fabric.Group, {
type: "customObject",
top: 0,
left: 0,
width: 0,
height: 0,
Fill: "#000000",
textObj: null,
rectObj: null,
originX: "left",
originY: "top",
noScaleCache: true,
objectCaching: false,
lockScalingFlip: true,
cacheProperties: fabric.Text.prototype.cacheProperties
  .concat
  //comma saperated string Properties that you want to cache
  (),
initialize: function (options) {
  this.set(options);
  this.rectObj = new fabric.Rect({
    top: 0,
    left: 0,
    width: this.width,
    height: this.height,
    fill: this.Fill,
  });

  this.textObj = new fabric.Textbox("text", {
    // text properties from this custom objects
  });

  this._objects = [this.rectObj, this.textObj];
  //   this custom _set function will set custom properties value to object when it will load from json.
  // at that time loadFromJson function will call this initialize function.
  this._setCustomProperties(this.options);
  this.canvas.renderAll();

  this.on("scaled", (e) => {
    //evenet will file if this custom object scalled
  });
  this.on("scaling", (e) => {
    //evenet will file if this custom object scalling
  });
},
_setCustomProperties(options) {
  let text = this.textObj;
  text.set({
    Fill: options.Fill,
  });
},
toObject: function (propertiesToInclude) {
  // This function is used for serialize this object. (used for create json)
  // not inlclude this.textObj and this.rectObj into json because when object will load from json, init fucntion of this class is called and it will assign this two object textObj and rectObj again.
  var obj = this.callSuper(
    "toObject",
    [
      "objectCaching",
      // ... property list that you want to add into json when this object is convert into json using toJSON() function. (serialize)
    ].concat(propertiesToInclude)
  );
  // delete objects array from json because then object load from json, Init function will call. which will automatically re-assign object and assign _object array.
  delete obj.objects;
  return obj;
},
 });

fabric.CustomObject.fromObject = function (object, callback) {
// This function is used for deserialize json and convert object json into button object again. (called when we call loadFromJson() fucntion on canvas)
return fabric.Object._fromObject("CustomObject", object, callback);
};

fabric.CustomObject.async = true;
})(fabric);