我尝试在画布中绘制几个图像。我有一个问题,因为有时候所有的图像都被绘制出来,有时会丢失几个。我尝试使用chrome和firefox。
有代码:
for (i=0; i<tileList.length; i++)
{
// var img_src = new Image();
var img_src = document.createElement("img");
var c = tileList[i].y ;
var r = tileList[i].x;
img_src.onload = function (){
ctx.drawImage(img_src, r * tileSize, c * tileSize, tileSize * tileList[i].qw, tileSize * tileList[i].qh);
}
img_src.src = './viewer/images/'+path+'/LOD'+glod+'/tiles_'+ c + '_' + r +'.jpeg';
我同时尝试new Image()
和document.createElement("img")
,结果是一样的。
答案 0 :(得分:0)
这是一个关闭问题。由于图像加载是异步的,仍然从处理程序内部引用父作用域的值不再包含您希望它们保留的值。
为此,您需要一种方法来保持这些值,直到图像正确加载。你可以使用闭包,或者像这里绑定一样 -
function handler() {
var i = this.i;
ctx.drawImage(this.img_src,
this.r * tileSize,
this.c * tileSize,
tileSize * tileList[i].qw, tileSize * tileList[i].qh);
}
注意它需要一个对象引用。在循环内部,我们现在可以做到:
for (var i = 0; i < tileList.length; i++) {
var o = {
img_src: new Image,
c: tileList[i].y,
r: tileList[i].x,
i: i
};
o.img_src.onload = handler.bind(o); // bind this object (o)
o.img_src.src = './viewer/images/'+path+'/LOD'+glod+'/tiles_'+ c + '_' + r +'.jpeg';
}
所以我们在循环中创建一个新的对象实例。我们存储了以后需要的数据。然后我们设置处理程序,但绑定到对象,它将保留在内存中,直到我们不再引用它。绑定它还允许我们使用this
来引用我们为处理程序创建的原始对象。
这是一种干净的方法,不需要匿名函数,也不会妨碍图像对象本身。
// conceptual example
var ctx = c.getContext("2d"),
list = [ // pseudo list serving this example
{x:2, y:5, src: "//i.imgur.com/kPX1264b.jpg"},
{x: 160, y:7, src: "//i.imgur.com/IgPTywZb.jpg"}
];
function handler() {
console.log(this.i, this.r, this.c, this.img_src.src);
ctx.drawImage(this.img_src, this.r, this.c);
}
for (i=0; i < list.length; i++) {
var o = {
img_src: new Image,
c: list[i].y,
r: list[i].x,
i: i
};
o.img_src.onload = handler.bind(o); // bind this object (o)
o.img_src.src = list[i].src;
}
&#13;
<canvas id=c></canvas>
&#13;
另请参阅this thread了解其他方法。