我正在尝试使用画布绘制平铺地图。需要将三种类型的切片绘制到画布上,因此我不是为每个单独的图像调用函数三次,而是将图像数组作为参数传递,循环遍历数组,并告诉画布绘制每个图像。但是,当我这样做时,我得到一个空白画布,没有返回错误消息。当我没有传入数组但是为每个图像手动调用函数时,图像被绘制到画布上。谁能向我解释我做错了什么?
window.onload = function(){
var basemap = document.getElementById("basemap");
var basemapCtx = basemap.getContext("2d");
initMap(Map.map, basemapCtx, basemap);
}
function initMap(map, ctx, canvas){
var deepWater = new Image();
var shallowWater = new Image();
var coastalWater = new Image();
deepWater.src = "deepWater.png";
shallowWater.src = "shallowWater.jpg";
coastalWater.src = "coastalWater.jpg";
//Does not draw the images
drawMap(map, [deepWater, shallowWater, coastalWater], ctx, canvas, [-2, -1, 0]);
//Does draw the images
//drawMap(map, deepWater, ctx, canvas, -2);
//drawMap(map, shallowWater, ctx, canvas, -1);
//drawMap(map, coastalWater, ctx, canvas, 0);
}
function drawMap(map, image, ctx, canvas, pos){
var screenWidth = canvas.width;
var screenHeight = canvas.height;
var tileWidth = 0;
var tileHeight = 0;
var xPos = 0;
var yPos = 0;
for(var i = 0; i < image.length; i++){
image[i].onload = function(){
for(var rows = 0; rows < map.length; rows++){
tileHeight = (screenHeight / map.length);
for(var cols = 0; cols < map[rows].length; cols++){
tileWidth = (screenWidth / map[rows].length);
if(map[rows][cols] == pos[i]){
ctx.drawImage(image[i], xPos, yPos, tileWidth, tileHeight);
}
xPos += tileWidth;
}
xPos = 0;
yPos += tileHeight;
}
yPos = 0;
tileWidth = 0;
tileHeight = 0;
}
}
}
答案 0 :(得分:1)
在当前函数返回且Javascript什么都不做之前,onload事件才会触发。 for循环使用变量i。当onload事件触发时,i的值将是最后一个图像的image.length
。
您需要为每个onload事件创建对该调用唯一的变量。你可以使用闭包来做到这一点。
更改代码如下
function drawMap(map, image, ctx, canvas, pos){
function setOnLoad(i){ // this function creates closure over the variable i so
// that it is unique each time this function and the onload
// function runs.
var screenWidth = canvas.width;
var screenHeight = canvas.height;
var tileWidth = 0;
var tileHeight = 0;
var xPos = 0;
var yPos = 0;
// the following function closes over all the variables in this function
image[i].onload = function(){
for(var rows = 0; rows < map.length; rows++){
tileHeight = (screenHeight / map.length);
for(var cols = 0; cols < map[rows].length; cols++){
tileWidth = (screenWidth / map[rows].length);
if(map[rows][cols] == pos[i]){
ctx.drawImage(image[i], xPos, yPos, tileWidth, tileHeight);
}
xPos += tileWidth;
}
xPos = 0;
yPos += tileHeight;
}
}
}
for(var i = 0; i < image.length; i++){
setOnLoad(i);
}
}
因此,每次调用onload函数时,您都将拥有一组唯一的变量。