为什么图像数组不能在HTML5 Canvas中绘制

Why would array of images not be drawing in HTML5 Canvas?

本文关键字:Canvas 绘制 HTML5 图像 数组 不能 为什么      更新时间:2023-09-26

我正在尝试使用画布绘制平铺地图。有三种类型的贴图需要绘制到画布上,所以我不是为每个单独的图像调用该函数三次,而是传递一个图像数组作为参数,循环遍历该数组,并告诉canvas绘制每个图像。然而,当我这样做时,我得到一个空白画布,没有返回任何错误消息。当我不传入数组,而是为每个图像手动调用函数时,图像被绘制到画布上。有人能告诉我我哪里做错了吗?

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

onload事件将不会触发,直到当前函数返回并且Javascript不做任何事情。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函数时,您将拥有一组唯一的变量。