2014-04-17 87 views
1

我有一系列的4個圖像,我試圖放置在指定的座標在fabricjs中,並且我在頁面加載時將它們放置得不一致。刷新一次或兩次通常會給出正確的佈局。試圖防止這種情況發生。fabricjs在畫布上的圖像放置不一致

有人知道如何解決這個問題嗎?這裏是我的代碼:

var objects = [ 
    { type: "image", filename : "tv.png" , x: 688, y: 184, angle: 0, zIndex: 10 }, 
    { type: "image", filename : "polaroid.jpg" , x: 347, y: 515 }, 
    { type: "image", filename : "polaroid.jpg" , x: 138, y: 643 }, 
    { type: "image", filename : "polaroid.jpg" , x: 429, y: 803 }, 
    { type: "text", text: "Your favorite band", x: 1168, y: 1163, angle: -17, canvasRef: null,zIndex: 50 } 
]; 

for (var i=0; i<objects.length;i++){ 

    var objRef = objects[i]; 

    switch(objRef.type){ 
     case 'image': 
      var url = "img/" + objRef.filename; 

      fabric.Image.fromURL(url, function(img) { 
       var objRef = objects[curObject]; 
       img.set({ 
        left: objRef.x, 
        top: objRef.y, 
        angle: objRef.angle, 
        hasBorders: false, 
        hasControls: false, 
        hasRotatingPoint: false, 
        lockMovementX: true, 
        lockMovementY: true 
       }); 
       canvas.add(img).renderAll(); 
       img.moveTo(objRef.zIndex); 
       curObject++; 
       //canvas.setActiveObject(img); 
      }); 

      break; 

     case 'text': 
      var text = objRef.text; 
      var fabricText = new fabric.Text(text, { 
       left: objRef.x, 
       top: objRef.y, 
       angle: objRef.angle, 
       hasBorders: false, 
       hasControls: false, 
       hasRotatingPoint: false, 
       lockMovementX: true, 
       lockMovementY: true 
      }); 
      objRef.canvasRef = fabricText; 
      addTextListeners(fabricText); 
      canvas.add(fabricText); 
      break; 
    } 

} 

我應該還提到,沒有這個代碼的反應,直到後window.ready,畢竟是織物試圖加載到畫布上的圖像已被使用imagesloaded插件預裝。

我還應該提到,我試着在每次加載(而不是循環)之間使用setTimeout延遲加載每個連續圖像,並保存canvas.renderAll()直到循環之後,沒有成功。甚至嘗試運行一個循環來重新放置物品後放置在屏幕上。以下是問題的圖片 - 分別是正確的和不正確的。

Proper Layout

Improper Layout

回答

5

它看起來像你必須從不同的順序加載圖像中的競爭條件。

fabric.Image.fromURL()方法正在使用回調函數,該函數會在圖像加載後觸發,因此您不能保證以與您調用它相同的順序觸發該內部函數。但是,每次調用函數時都使用curObject向上遞增,該函數假定它們按順序調用。在圖像加載時,objRef可以重新分配給一個新對象,這就是x/y/rotate值關閉的原因(使用來自數組中其他對象的值)。

所以,而是採用img.set()圖像就裝好後,使用Image.fromURL()方法的第三個參數中的屬性來傳遞:

for (var i=0; i<objects.length;i++){ 
    var objRef = objects[i]; 
    switch(objRef.type){ 
    case 'image': 
     var url = "img/" + objRef.filename; 
     fabric.Image.fromURL(url, function(img) { 
     canvas.add(img).renderAll(); 
     }, { 
     left: objRef.x, 
     top: objRef.y, 
     angle: objRef.angle, 
     hasBorders: false, 
     hasControls: false, 
     hasRotatingPoint: false, 
     lockMovementX: true, 
     lockMovementY: true 
     }); 
     break; 

    case 'text': 
     // ... 
     break; 
    } 
} 
0

所以關鍵的答案是異步回調。只需檢查警報消息何時發出。

fabric.Image.fromURL('hulk.png', function (img) { 
    alert('came1'); 
    canvas.add(img).renderAll(); 
    }, { 
     id: 'hulkid', 
     num: 1, 
     left: 10, 
     top: 10, 
     angle: 0 
    }); 

fabric.Image.fromURL('hulk.png', function (img) { 
    alert('came2'); 
    canvas.add(img).renderAll(); 
}, { 
    id: 'hulkid', 
    num: 2, 
    left: 25, 
    top: 25, 
    angle: 0 
}); 
alert('came Last');