2014-03-31 40 views
0

我使用FabricJS將SVG對象放在HTML中的Canvas元素上。 但由於FabricJS使用new關鍵字來實例化類,我認爲該類的屬性綁定到global命名空間。在使用fabricjs時遇到Javascript新關鍵字的問題

下面是我的參考代碼

,我解析

var defaultSceneObj = [ 
     { 
      "eyes": "res/img/animals/cat/cat_part_eye.svg", 
      "skin": "res/img/animals/cat/cat_skin.svg", 
      "mouth": "res/img/animals/cat/cat_part_mouth_happy.svg", 
      "pos": { 
       "ground" : "right_back", 
       "sky" : "none", //other values ["none"] 
       "relative" : "none" //other values ["none", "top", "bottom"] 
      } 
     }, 
     { 
      "eyes": "res/img/animals/cat/cat_part_eye.svg", 
      "skin": "res/img/animals/cat/cat_skin.svg", 
      "mouth": "res/img/animals/cat/cat_part_mouth_happy.svg", 
      "pos": { 
       "ground" : "left_back", 
       "sky" : "none", //other values ["none"] 
       "relative" : "none" //other values ["none", "top", "bottom"] 
      } 
     } 
    ]; 

我的JSON對象這意味着我的對象,其中每個animaleyeskinmouth有2 animals svg文件。

我通過他們在我的javascript代碼循環,從而使它們

var renderObjOnCanvas = function(cObj, cDim){ 
     // console.log("Object, Dimension:", cObj, cDim); 
     // var canvas = new fabric.Canvas('elem-frame-svg'); 
     var canvas = this.__canvas = new fabric.Canvas('elem-frame-svg'); 

     imgwidth = 200; //default image width 
     imgheight = 255; //default image height 
     imgScale = 0.6; 
     imgOffsetX = Math.floor(imgwidth*imgScale/2); 
     imgOffsetY = Math.floor(imgheight*imgScale/2); 

     canvaswidth = canvas.width; 
     canvasheight = canvas.height; 

     // console.log("render canvas dimensions:", canvaswidth, canvasheight); 
     if (cObj.length > 0){ 

      for (var c =0; c < cObj.length; c++){ 
       var noun = cObj[c]; //assign the noun object 

       if (noun.skin !== 'Undefined'){ 
        var animalParts = ['skin', 'eyes', 'mouth']; 
        var pos = cDim.ground[noun.pos.ground]; 

        for (var g = 0; g < animalParts.length; g++){ 

         var part_top = canvasheight - (pos[1] + imgOffsetY); 
         var part_left = pos[0] - imgOffsetX; 
         console.log("part:", noun[animalParts[g]], "part_position: ", part_top, part_left); 

         var img = new fabric.Image.fromURL(noun[animalParts[g]], function(s){ 
          this.top = part_top; 
          this.left = part_left; 
          // this.scale(imgScale); 

          s = this; 

          console.log("part:", part_top, part_left); 

          canvas.add(); 

         }); 
        } 
       } 
      } 
     } 
    }; 

第一console.log輸出正確的topleft座標,但第二個僅輸出分配最後的值,因此我所有的對象都放在畫布上的相同位置。

輸出的第一console.log

part: res/img/animals/cat/cat_skin.svg part_position: 282 574 main.js:126 
part: res/img/animals/cat/cat_part_eye.svg part_position: 282 574 main.js:126 
part: res/img/animals/cat/cat_part_mouth_happy.svg part_position: 282 574 main.js:126 
part: res/img/animals/cat/cat_skin.svg part_position: 282 135 main.js:126 
part: res/img/animals/cat/cat_part_eye.svg part_position: 282 135 main.js:126 
part: res/img/animals/cat/cat_part_mouth_happy.svg part_position: 282 135 

輸出第二console.log:使用forEach()方法而不是for

(6) part: 282 135 
+0

該錯誤可能是因爲[在Javascript這個錯誤]的(http://youtu.be/hQVTIJBZook?t=24m46s) – Shreyas

回答

1

這是因爲forEach爲您管理變量的範圍,而不是。例如,

var arr = [1,2,3]; 
for (var i=0;i<arr.length;i++){ 
    var r = 100; 
} 
console.log(r); //prints 100 

arr.forEach(function(){ 
    var w = 100; 
}); 
console.log(w); //prints "w is not defined" 

所以在你的情況下,part_top,part_left變量存在外面的變量按引用傳遞的循環,只有最後分配的值將採取由回調函數。看看這個答案

scope of variables in JavaScript callback functions

0

爲我工作。雖然我不確定,但爲什麼

我們最接近的解釋是,由於forEach()接受一個匿名函數,因此當調用new運算符時,它會將變量範圍綁定到閉包中。

... 
if (noun.skin !== 'Undefined'){ 
        var animalParts = ['skin', 'eyes', 'mouth']; 
        var pos = cDim.ground[noun.pos.ground]; 

        animalParts.forEach(function(item, g){ // <-works 
        // for (var g = 0; g < animalParts.length; g++){ 

         var part_top = canvasheight - (pos[1] + imgOffsetY); 
         var part_left = pos[0] - imgOffsetX; 
         console.log("part:", noun[animalParts[g]], "part_position: ", part_top, part_left); 

         var img = new fabric.Image.fromURL(noun[animalParts[g]], function(s){ 
          s.top = part_top; 
          s.left = part_left; 
          s.scale(imgScale); 
          // console.log(s, s.top,s.left, part_top, part_left); 
          canvas.add(s); 
         }); 
        }); 
       } 
...