2010-07-15 10 views
6

Me encuentro con problemas al intentar dibujar un gran conjunto de imágenes 2D en un lienzo. Usando un programa separado, tomo un archivo de imagen grande y lo divido en pedazos más pequeños y uniformes. Estoy usando la matriz 2D para representar esta "cuadrícula" de imágenes, e idealmente cuando asigno el src de cada elemento en la cuadrícula, esa imagen se dibujará en su punto adecuado en el lienzo una vez que esté lista. Sin embargo, mi código no está funcionando.Dibujar varias imágenes en un lienzo usando image.onload

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"; 
     } 
    } 

He intentado ejecutar este código en Opera, Firefox, Chrome y Safari. Los eventos de carga no se disparan en absoluto en Opera, Chrome y Safari (coloqué una alerta dentro de la función de carga, nunca apareció). En Firefox, solo se dispara el evento de carga de la PRIMERA imagen (grid [0] [0]). Sin embargo, noté que si colocaba una alerta justo después de configurar el src del elemento actual, cada evento de carga en Firefox se activa y se dibuja toda la imagen. Idealmente, me gustaría que esto funcione en los 4 navegadores (supongo que IE no funcionará porque no admite Canvas), pero simplemente no sé lo que está sucediendo. Cualquier ayuda/entrada es apreciada, ¡gracias!

Respuesta

9

Creo que el problema es que no está consiguiendo sus variables en un cierre. Cambie esta línea:

grid[row][col].onload = function() {ctx.drawImage(grid[row][col], x, y);}; 

Para

grid[row][col].onload = function() {window.alert('row:' + row + ' col:' + col);}; 

Y what you'll see es que sus alertas están regresando el mismo valor para la fila y columna en cada llamada. Que necesita para obtener estos variables wrapped in a closure para que sus ofertas de función con los valores y no las referencias:

var drawCanvasImage = function(ctx,grid,row,col,x,y) { 
    return function() { 
     ctx.drawImage(grid[row][col], x, y); 
    } 
} 

Después, realice:

grid[row][col].onload = drawCanvasImage(ctx,grid,row,col,x,y); 

This example page me funciona en Firefox y Chrome.

+0

¡Muchas gracias! Ese era el problema allí mismo. – Kaz

Cuestiones relacionadas