我正在使用FabricJS将SVG对象放在HTML中的Canvas元素上。
但是由于FabricJS使用new
关键字来实例化类,我认为该类的属性与global
命名空间相关联。
下面是我的参考代码
我正在解析的JSON对象
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"]
}
}
];
这意味着我的对象中有2个animals
,其中每个animal
由eye
,skin
和mouth
个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
输出正确的top
和left
坐标,但第二个只输出分配的最后一个值,因此我的所有对象都放在画布上的相同位置
第一个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
的输出:
(6) part: 282 135
答案 0 :(得分: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变量存在于for循环之外,只有最后指定的值将被回调函数占用,因为变量是通过引用传递的。看看这个答案
答案 1 :(得分:0)
使用forEach()
方法代替for
循环为我工作。虽然我不确定,为什么
我们最接近的解释是,由于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);
});
});
}
...