在选中之前,Fabric.js图像在画布上不可见

时间:2015-11-04 18:43:40

标签: javascript html5 canvas fabricjs

我正在创建一个画布,可以根据用户点击事件添加图像。但是,当单击元素并添加图像时,图像就在那里(鼠标悬停暗示它是)但在画布上不可见,直到第二次单击该元素。

  var canvas = new fabric.Canvas( "designer" );

  $( ".shape-option" ).click( function() {
     event.stopPropagation();
     var shapeSelected = $( this );
     var shapeId = shapeSelected.attr( "id" );
     var assetObject = new Image();

     assetObject.src = "/images/" + shapeId + ".png";
     shape = new fabric.Image( assetObject );
     shape.set( { top: 0, height: 300, width: 300 } );
     canvas.add( shape );
  } );

是否有人遇到此问题或类似问题?

2 个答案:

答案 0 :(得分:2)

这个问题显然与时间有关。在测试了几个变体后,以下工作得很好。

首先,我需要添加对canvas.renderAll()的调用以在更改后呈现画布。但是,我发现调用canvas.renderAll()函数需要包装在setTimeout中,允许canvas和DOM在渲染之前注册更改。这修复了可见性。

其次,我发现对象的可选区域与对象本身的位置不匹配。随后,我不得不调用canvas.calcOffset()来确保操作后对象路径的坐标是正确的。我的解决方案如下:

$( document ).ready( function() {
    Designer.initialize();
} ); 

var Designer = Designer || {

    canvas: null, 

    initialize: function() {
        Designer.canvas = new fabric.Canvas( "designer" );
        Designer.bindShapeOptionClickEvent();
    },

    bindShapeOptionClickEvent: function() {
        $( ".shape-option" ).click( function() {
            event.stopPropagation();
            var shapeSelected = $( this );
            var shapeId = shapeSelected.attr( "id" );
            var assetObject = new Image();

            assetObject.src = "/images/" + shapeId + ".png";
            shape = new fabric.Image( assetObject );
            shape.set( { top: 0, height: 300, width: 300 } );
            Designer.canvas.add( shape );
            Designer.updateCanvas();
        } );
    },

    updateCanvas: function() {
        setTimeout( function() { Designer.canvas.renderAll(); }, 50 );
        Designer.canvas.calcOffset();
    }
};

答案 1 :(得分:1)

你在src更改后立即执行图片加载,触发重新加载,所以当你做新的fabric.Image时,元素还没有准备好。

所以请用以下方法之一改变逻辑:

$( ".shape-option" ).click( function() {
     event.stopPropagation();
     var shapeSelected = $( this );
     var shapeId = shapeSelected.attr( "id" );
     var assetObject = new Image();
     assetObject.onLoad = function() {
          shape = new fabric.Image( assetObject );
          shape.set( { top: 0, height: 300, width: 300 } );
          canvas.add( shape );
     }
     assetObject.src = "/images/" + shapeId + ".png";
  } );

或让Fabric处理异步加载:

$( ".shape-option" ).click( function() {
     event.stopPropagation();
     var shapeSelected = $( this );
     var shapeId = shapeSelected.attr( "id" );
     fabric.Image.fromURL('/images/' + shapeId + '.png', function(oImg) {
         img.set( { top: 0, height: 300, width: 300 } );
         canvas.add(img);
     });
} );