【问题标题】:How to create custom fabricjs object?如何创建自定义fabricjs对象?
【发布时间】:2020-11-05 00:27:46
【问题描述】:

我必须创建一个自定义 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);
});

【问题讨论】:

    标签: javascript fabricjs


    【解决方案1】:

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

    所以当你初始化你的类时不要创建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);
    

    扩展渲染函数,思考你需要不同于标准组的东西,如果你想加载和恢复你的画布,不要忘记放置 fromObject 函数。

    【讨论】:

    • 你能写出fromObject函数来从json中恢复吗?
    • 4 年后,我要么问你用这样的对象做什么。如果您需要通用恢复功能,我可以编写它。但是这个自定义对象对原始问题的范围非常狭窄。
    • 非常感谢您的回复,但实际上,作为客户要求,我们需要它来解决自定义对象中的一些问题,所以我不得不返回此代码。
    • 你在使用什么版本的fabricJS?恢复功能从 1 更改为 2。
    • 我使用的是fabric js 3.6.3版。
    【解决方案2】:

    这是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);
    

    【讨论】:

      猜你喜欢
      • 2018-05-14
      • 1970-01-01
      • 2015-07-31
      • 2018-12-03
      • 2018-09-18
      • 2018-04-19
      • 2015-12-02
      • 2020-12-17
      • 1970-01-01
      相关资源
      最近更新 更多