我在尝试将大型2D图像数组绘制到画布上时遇到了问题。使用一个单独的程序,我正在拍摄一个大的图像文件并将其分解成更小,更均匀的部分。我正在使用2D数组来表示图像的这个“网格”,理想情况下,当我在网格中分配每个元素的src时,该图像一旦准备就会被绘制到画布上的正确点。但是,我的代码无效。
var grid = new Array()
/*grid is set to be a 2D array of 'totalRows' rows and 'totalCols' columns*/
/*In the following code, pieceWidth and pieceHeight are the respective height/widths
of each of the smaller 'pieces' of the main image. X and Y are the coordinates on
the canvas that each image will be drawn at. All of the images are located in the
same directory (The src's are set to http://localhost/etc), and each individual
filename is in the form of name(row*totalRows + col).png, ex, traversing the 2D
array left to right top to bottom would give image1.png, image2.png, etc*/
for (var row = 0; row < totalRows; row++)
{
for (var col = 0; col < totalCols; col++)
{
grid[row][col] = new Image();
var x = col * pieceWidth;
var y = row * pieceHeight;
grid[row][col].onload = function () {ctx.drawImage(grid[row][col], x, y);};
grid[row][col].src = "oldimagename" + ((row * totalRows) + col) + ".png";
}
}
我尝试在Opera,Firefox,Chrome和Safari中运行此代码。在Opera,Chrome和Safari中,onload事件根本不会触发(我在onload函数中放置了一个警报,它从未出现过)。在Firefox中,只有FIRST图像(grid [0] [0])的onload事件被触发。但是,我注意到如果我在设置当前元素的src后立即发出警报,则会触发Firefox中的每个onload事件,并绘制整个图像。理想情况下,我希望这可以在所有4个浏览器中工作(我认为IE不会工作,因为它不支持画布),但我只是不知道发生了什么。感谢任何帮助/意见,谢谢!
答案 0 :(得分:10)
我认为问题是你没有把你的变量变成一个闭包。改变这一行:
grid[row][col].onload = function () {ctx.drawImage(grid[row][col], x, y);};
要
grid[row][col].onload = function () {window.alert('row:' + row + ' col:' + col);};
并且what you'll see是您的警报在每次调用时为row和col返回相同的值。您需要获取这些variables wrapped in a closure,以便您的函数处理值而不是引用:
var drawCanvasImage = function(ctx,grid,row,col,x,y) {
return function() {
ctx.drawImage(grid[row][col], x, y);
}
}
然后做:
grid[row][col].onload = drawCanvasImage(ctx,grid,row,col,x,y);
This example page适用于Firefox和Chrome。