Fabric.js/Angular - 当我更改 canvas 对象的图像时,它消失然后重新出现

Fabric.js/Angular - When I change the image of a canvas object, it disappears and then reappears

我想做的事情:

  1. Select canvas 上的对象
  2. 单击更改图像以更改 canvas
  3. 上的所选图像

发生了什么:

  1. 图像消失了,但当您尝试移动空白区域时又重新出现为新图像。

我不知道为什么要这样做。我假设它对必须从控制器实例化的 DOM 进行了某种重新编译,但我不确定。

提前致谢。 jsfiddle 演示了这个问题,但我也展示了下面的代码。

angular.module('canvasApp', [])

.controller('MainCtrl', function($scope){

 $scope.up = function(){
  $scope.$broadcast('change');
 }

})



.directive('ngCanvas', function(){
 return {
  restrict: 'EA',
  scope: true,
  template: '<canvas id="canvas" width="1000" height="500" data-drop="true" jqyoui-droppable="{onDrop:\'drop(event, data, obj)\'}" ></canvas>',
  controller: function($scope){
   
   $scope.$on('change', function(event){
    var tmp = $scope.canvas.getActiveObject();
    
    var el = tmp.getElement();
    
    el.setAttribute('src', "https://www.filepicker.io/api/file/7b3SLVgR65Fx4Q8JZyxQ");

    $scope.canvas.renderAll();
    $scope.canvas.calcOffset();
   });  

  },
  link:  function(scope, element, attrs){

   scope.canvas = new fabric.Canvas('canvas');
   
   fabric.Image.fromURL("https://www.filepicker.io/api/file/jGVMrkPuQ8eNGn5BpsiB", function(oImg) {
    scope.canvas.add(oImg);
   });
  }

 }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.4.13/fabric.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body ng-app="canvasApp">
 <div ng-controller="MainCtrl">

 <button id="click" ng-click="up()">Change Image</button>

 <div ng-canvas></div>
 
</div>
</body>

http://jsfiddle.net/eg4y6d3k/4/

编辑

如果没有 angular,同样的代码直接用 JS 完成,它仍然有同样的问题。下面的代码。

  var canvas = new fabric.Canvas('canvas');

  fabric.Image.fromURL("https://www.filepicker.io/api/file/jGVMrkPuQ8eNGn5BpsiB", function(oImg) {
    canvas.add(oImg);
  });

  var up = function() {
    var tmp = canvas.getActiveObject();
    var el = tmp.getElement();

    el.setAttribute('src', "https://www.filepicker.io/api/file/7b3SLVgR65Fx4Q8JZyxQ");

    canvas.renderAll();
    canvas.calcOffset();
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.4.13/fabric.js"></script>

<body>
  <button id="click" onclick="up()">Change Image</button>

  <canvas id="canvas" width="1000" height="500"></canvas>

</body>

我不得不 fiddle 使用 fabric.js 和 canvas - 以前从未使用过。

以下是我完成这项工作的方法:

$scope.$on('change', function(event, data) {

  fabric.Image.fromURL("https://www.filepicker.io/api/file/7b3SLVgR65Fx4Q8JZyxQ", 
    function(oImg) {
      var canvas = $scope.canvas;
      canvas.clear().renderAll();
      canvas.add(oImg);
      $scope.$digest();
    });

});

Your updated fiddle

编辑:

另一种方法是在织物的图像对象上使用setElement

link: function(scope, element, attrs) {
  var fabricImage;

  scope.canvas = new fabric.Canvas('canvas');

  fabric.Image.fromURL("image1.png", function(oImg) {
    fabricImage = oImg;
    scope.canvas.add(oImg);
  });

  scope.$on('change', function(event, data) {
    if (!fabricImage) return;

    var image = new Image();
    image.onload = function() {
      fabricImage.setElement(image);
      scope.canvas.renderAll();
    }
    image.src = "image2.png";
  });

}

updated fiddle

编辑 2:

第三种方法(可能是最直接的)是使用 setSrc:

  scope.$on('change', function(event, data) {
    if (!fabricImage) return;

    fabricImage.setSrc("image2.png",
          function(){
             scope.canvas.renderAll();
          });
  });

updated fiddle 2

使用 object.setSrc,您可以选择指定回调。

http://jsfiddle.net/eg4y6d3k/9/

最初没有选择任何对象,所以我取出了 canvas.getActiveObject() - 没有任何活动。

var tmp = $scope.canvas.getObjects(); tmp[0].setSrc( "https://www.filepicker.io/api/file/7b3SLVgR65Fx4Q8JZyxQ", function(){$scope.canvas.renderAll()});

单击按钮时图像发生变化。