在更改其属性后重新呈现子类织物对象

时间:2018-06-16 05:03:10

标签: javascript html fabricjs

我对织物进行了分类.Rect" class"。它有一些属性,如类型,名称和区域。



var RoomRect = fabric.util.createClass(fabric.Rect, {

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

      // type is either one of HALL, BEDROOM, TOILET, etc.
      this.set('type', options.type || '');

      // name is user defined and also a default name is generated if the name has not been specified
      // the name acts as a unique identifier
      this.set('name', options.name || '');

      // area is in sq. meters
      this.set('area', options.area || 0);
    },
  
    toObject: function() {
      return fabric.util.object.extend(this.callSuper('toObject'), {
        type: this.get('type'),
        name: this.get('name'),
        area: this.get('area')
      });
    },
    
    _render: function(ctx) {
      this.callSuper('_render', ctx);

      ctx.font = '1.3em Lato';
      ctx.fillStyle = '#383838';
      ctx.fillText("Type: "+this.type, -this.width/2+15, -this.height/2 + 20);
      ctx.fillText("Name: "+this.name, -this.width/2+15, -this.height/2 + 40);
      ctx.fillText("Area: "+this.area+" sq. m.", -this.width/2+15, -this.height/2 + 60);
    }
  });




双击此矩形时会显示一个提示,其中用户可以更改名称和区域属性。如果用户单击“保存”,则会触发以下代码。它会更改属性并再次呈现所有内容。



function saveRoomInfo(){
        if(SELECTED_ITEM == null){return;}
        // get the data from the form and put it into the object
        
        var roomInfoForm_name = document.getElementById('roomName');
        var newName = roomInfoForm_name.value;

        var roomInfoForm_area = document.getElementById('roomArea');
        var newArea = roomInfoForm_area.value;

        SELECTED_ITEM.set('name',newName);
        SELECTED_ITEM.set('area',newArea);
        
        fabricCanvas.renderAll();
        
    }




这里的问题是,更改是在对象中进行的(通过调试器确认),但更改不是在用户界面(矩形对象)中完成的。

另一个问题是,再次渲染所有内容是一种很好的做法。我可以有选择地重新渲染一个对象。我可以删除旧对象并渲染一个具有不同属性的新对象,但这也需要更改其他数据结构。

1 个答案:

答案 0 :(得分:1)

在较新版本的fabricjs中,它不会呈现所有对象,您需要设置dirty : true或将属性放在cacheProperties中,这会影响缓存画布以呈现缓存。并且不要使用type属性,因为它在从JSON加载时用于搜索相应的类。

<强> 样本

fabric.RoomRect = fabric.util.createClass(fabric.Rect, {
  type: 'roomRect',

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

    this.callSuper('initialize', options);
    // type is either one of HALL, BEDROOM, TOILET, etc.
    this.roomRectType = options.roomRectType || '';
    // name is user defined and also a default name is generated if the name has not been specified
    // the name acts as a unique identifier
    this.name = options.name || '';
    // area is in sq. meters
    this.area = options.area || '';
  },

  toObject: function() {
    return fabric.util.object.extend(this.callSuper('toObject'), {
      roomRectType: this.get('roomRectType'),
      name: this.get('name'),
      area: this.get('area')
    });
  },

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

    ctx.font = '1.3em Lato';
    ctx.fillStyle = '#383838';
    ctx.fillText("Type: " + this.roomRectType, -this.width / 2 + 15, -this.height / 2 + 20);
    ctx.fillText("Name: " + this.name, -this.width / 2 + 15, -this.height / 2 + 40);
    ctx.fillText("Area: " + this.area + " sq. m.", -this.width / 2 + 15, -this.height / 2 + 60);
  }
});

var canvas = new fabric.Canvas('c');
var roomrect = new fabric.RoomRect({
  left: 10,
  top: 10,
  width: 100,
  height: 100,
  fill: '',
  stroke: 'red'
});
canvas.add(roomrect);
setTimeout(function() {
  roomrect.set({
    roomRectType: 'room',
    name: 'test',
    area: 100,
    dirty: true
  });
  canvas.requestRenderAll();
}, 2000)
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.2/fabric.js"></script>
<canvas width=300 height=300 id='c'></canvas>