【问题标题】:Fabric.js: src attribute missing on grouping subclassed objectFabric.js:分组子类对象时缺少 src 属性
【发布时间】:2017-10-01 17:15:41
【问题描述】:

我尝试使用子类化,如 http://fabricjs.com/polaroid 的示例所示。

PolaroidPhoto 子类只是在图像上添加了一个边框,如下面的小提琴所示:https://jsfiddle.net/gusy54rr/6/

   canvas = this.__canvas = new fabric.Canvas('c', {
    backgroundColor: '#333',
    HOVER_CURSOR: 'pointer'
  });

  var PolaroidPhoto = fabric.util.createClass(fabric.Image, {
    H_PADDING: 20,
    V_PADDING: 20,
    originX: 'center',
    originY: 'center',
    initialize: function(src, options) {
      this.callSuper('initialize', options);
      this.image = new Image();
      this.image.src = src;
    console.log("In initialize, src is:" + src);
      this.image.onload = (function() {
        this.width = this.image.width;
        this.height = this.image.height;
        this.loaded = true;
        this.setCoords();
        this.fire('image:loaded');
      }).bind(this);
    },
    _render: function(ctx) {
      if (this.loaded) {
        ctx.fillStyle = '#fff';
        ctx.fillRect(
          -(this.width / 2) - this.H_PADDING,
          -(this.height / 2) - this.H_PADDING,
          this.width + this.H_PADDING * 2,
          this.height + this.V_PADDING * 2);
        ctx.drawImage(this.image, -this.width / 2, -this.height / 2);
      }
    }
  });
  var photo = new PolaroidPhoto('https://i.stack.imgur.com/cqmQ9.png', { });

 photo.on('image:loaded', canvas.renderAll.bind(canvas));

 photo.set('scaleX', 1);
 photo.set('scaleY', 1);
 photo.set('top', 180);
 photo.set('left', 150);
    console.log("photo,src is :" + photo.get('src'));

  // forcing src value (but ineffective)
 photo.set('src', 'https://i.stack.imgur.com/cqmQ9.png');

   canvas.add(photo);


canvas.add(
   rect= new fabric.Rect({ top: 50, left: 100, width: 50, height: 50, fill: '#f55' }),
 circle =   new fabric.Circle({ top: 140, left: 230, radius: 75, fill: 'green' }),
   triangle = new fabric.Triangle({ top: 300, left: 210, width: 100, height: 100, fill: 'blue' })
);

$("#group").on('click', function() {
    var activegroup = canvas.getActiveGroup();
    var objectsInGroup = activegroup.getObjects();

    activegroup.clone(function(newgroup) {
            canvas.discardActiveGroup();
            objectsInGroup.forEach(function(object) {
            canvas.remove(object);  
            });
            canvas.add(newgroup);

    });
});

$("#ungroup").click(function(){
   var activeObject = canvas.getActiveObject();
    if(activeObject.type=="group"){
            var items = activeObject._objects;
            alert(items);
            activeObject._restoreObjectsState();
            canvas.remove(activeObject);
            for(var i = 0; i < items.length; i++) {
                canvas.add(items[i]);
            items[i].dirty = true;
                canvas.item(canvas.size()-1).hasControls = true;
            }
        canvas.renderAll();
    }
});

在我想对子类对象进行字符串化或分组之前,它可以正常工作。

在小提琴中,我通过添加一些基础对象(矩形、圆形和三角形)完成了 Fabric 演示的示例。 如果我选择子类图像和任何其他对象,然后单击组按钮: 图像消失。

照片的 scr 属性未设置(如前一组的“取消组合”警报所示)。

画布的字符串化也显示“src”缺失。

即使我使用 "photo.set('src',...)" 强制(见小提琴)一个 src 值: - 分组仍然使图片消失。 - 字符串化仍然缺少“src”属性。 (我尝试扩展 toObjects 无济于事)

如何进行分组和字符串化以处理子类对象? 感谢您的帮助。

【问题讨论】:

  • 检查this,这个在版本2.0.0-beta7
  • 非常感谢杜尔加。确实,分组很好,您可以很好地转换到 2.0.0-beta7 版本。但是, loadFromJSON 仍然没有成功。无论如何,我仍然必须找到一种方法让分组和 loadFromJSON 与 Fabric 1.7 一起工作

标签: fabricjs


【解决方案1】:

这是一个新的 jsfiddle,显示了正确的分组和 JSON 加载以及子类 (PolaroidPhoto) 图像。 Fabric 版本是 1.7.19 https://jsfiddle.net/rpzk7wL6/2/

我在代码中放了一些 cmets 来显示我的修改。 前一个脚本的主要问题是缺少 fromObjects() 方法。 我还向创建的子类实例添加了一个监听“image:loaded”的处理程序 通过fromObjects,以便在加载后渲染它。

      fabric.Object.prototype.transparentCorners = false;

   canvas = this.__canvas = new fabric.Canvas('c', {
    backgroundColor: '#333',
    HOVER_CURSOR: 'pointer'
  });

 fabric.Polaroidphoto = fabric.util.createClass(fabric.Image, {
type: 'polaroidphoto',
    H_PADDING: 20,
    V_PADDING: 20,
    originX: 'center',
    originY: 'center',
    initialize: function(src, options) {
    this.image = new Image();
    this.image.src = src;
        this.callSuper('initialize',src, options);
        console.log("initialize, src:" + src);
        this.image.onload = (function() {
            this.width = this.image.width;
        console.log("initialize, scaleX:" + this.image.scaleX);
            this.height = this.image.height;
        this.src= this.image.src;
        console.log("initialize image.onload, src:" + src);
            this.loaded = true;
            this.setCoords(); 
            this.fire('image:loaded');
            }).bind(this);
        },
    _render: function(ctx) {
    if (this.loaded) {
        console.log("_render:is_loaded");
            ctx.fillStyle = '#fff';
            ctx.fillRect(
                -(this.width / 2) - this.H_PADDING,
                 -(this.height / 2) - this.H_PADDING,
                this.width + this.H_PADDING * 2,
                this.height + this.V_PADDING * 2);
                ctx.drawImage(this.image, -this.width / 2, -this.height / 2);
        } else {
        console.log("_render:is_NOT__loaded");
        }
    }
  });

// Added fromObject function for sub-class 
fabric.Polaroidphoto.async = true;
fabric.Polaroidphoto.fromObject = function (object, callback) {
console.log("fabric.Polaroidphoto.fromObject object.src) :" + object.src);
            var instance = new fabric.Polaroidphoto(object.src, object);
            callback && callback(instance);
    // added handler to render instance 
        instance.on('image:loaded', when_loaded );
          };

 var photo = new fabric.Polaroidphoto('https://i.stack.imgur.com/cqmQ9.png', { });
 photo.on('image:loaded', when_loaded );
 photo.set('scaleX', 1);
 photo.set('scaleY', 1);
 photo.set('top', 180);
 photo.set('left', 150);
 canvas.add(photo);


canvas.add(
   rect= new fabric.Rect({ top: 50, left: 100, width: 50, height: 50, fill: '#f55' }),
 circle =   new fabric.Circle({ top: 140, left: 230, radius: 75, fill: 'green' }),
   triangle = new fabric.Triangle({ top: 300, left: 210, width: 100, height: 100, fill: 'blue' })
);

// required at load to render sub-classed image in group
function when_loaded() {
    console.log("when_loaded");
    dirty(); // to set dirty : true 
    canvas.renderAll();
}

// required at load to display sub-classed image in group, 
// set dirty:true for groups 

function dirty() {
    $.each(canvas._objects, function( index, obj ) {
        if( typeof obj.type !== 'undefined' && obj.type == 'group') {
            obj.dirty= true;
        }
    });
}

$("#group").on('click', function() {
    var activegroup = canvas.getActiveGroup();
    var objectsInGroup = activegroup.getObjects();

    activegroup.clone(function(newgroup) {
            canvas.discardActiveGroup();
            objectsInGroup.forEach(function(object) {
            canvas.remove(object);  
            });
             canvas.add(newgroup);
        newgroup.dirty = true; 
    });
});

$("#ungroup").click(function(){
   var activeObject = canvas.getActiveObject();
    if(activeObject.type=="group"){
            var items = activeObject._objects;
            alert(items);
            activeObject._restoreObjectsState();
            canvas.remove(activeObject);
            for(var i = 0; i < items.length; i++) {
                canvas.add(items[i]);
            items[i].dirty = true;
            canvas.item(canvas.size()-1).hasControls = true;
            }
        canvas.renderAll();
    }
});

谢谢

【讨论】:

    猜你喜欢
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多