This is about the creation of a tile map (64x64 pixel PNGs).
For demonstration purposes I simplified my code and reduced the grid to a 3x3 field.
The issue is essentially that the images are still loading when I draw the grid, so the canvas won't show on first load. On refresh however, the grid loads fine as all image files are now cached.
<body>
    <canvas id="canvas" width="200px" height="200px"></canvas>
    <script>
        var canvas = document.getElementById('canvas');
        var context = canvas.getContext('2d');
        // 3X3 GRID
        var mapArray=[
            ["tile1","tile3","tile1"],
            ["tile1","tile1","tile2"],
            ["tile3","tile1","tile2"]
        ];
        var tile1 = new Image();
        var tile2 = new Image();
        var tile3 = new Image();
        tile1.src='../images/test/tile1.png';
        tile2.src='../images/test/tile2.png';
        tile3.src='../images/test/tile3.png';
        var posX=0;
        var posY=0;
            for(var i=0; i < mapArray.length; i++) {
                for(var j=0; j < mapArray[i].length; j++) {
                    switch(mapArray[i][j]) {
                        case "tile1":
                            context.drawImage(tile1, posX, posY, 64, 64);
                            break;
                        case "tile2":
                            context.drawImage(tile2, posX, posY, 64, 64);
                            break;
                        case "tile3":
                            context.drawImage(tile3, posX, posY, 64, 64);
                            break;
                    }
                    posX+=64;
                }
                posX=0;
                posY+=64;
            }
        </script>
</body>
Similar issues can be found:
Canvas image not displaying until second attempt
Why do my canvases only load on refresh?
In this case though I am trying to generate not just one image, but a grid of images and my attempt at solving this seems to run into issues as nothing loads at all:
<body>
    <canvas id="canvas" width="200px" height="200px"></canvas>
    <script>
        var canvas = document.getElementById('canvas');
        var context = canvas.getContext('2d');
        // 3X3 GRID
        var mapArray=[
            ["tile1","tile3","tile1"],
            ["tile1","tile1","tile2"],
            ["tile3","tile1","tile2"]
        ];
        var tile1 = new Image();
        var tile2 = new Image();
        var tile3 = new Image();
        var posX=0;
        var posY=0;
            for(var i=0; i < mapArray.length; i++) {
                for(var j=0; j < mapArray[i].length; j++) {
                    switch(mapArray[i][j]) {
                        case "tile1":
                            //use onload so drawing waits until image file is loaded
                            tile1.onload = function() {
                                //draw image
                                context.drawImage(tile1, posX, posY, 64, 64);
                            };
                            //load image file
                            tile1.src='../images/test/tile1.png';
                            break;
                        case "tile2":
                            tile2.onload = function() {
                                context.drawImage(tile2, posX, posY, 64, 64);
                            };
                            tile2.src='../images/test/tile2.png';
                            break;
                        case "tile3":
                            tile3.onload = function() {
                                context.drawImage(tile3, posX, posY, 64, 64);
                            tile3.src='../images/test/tile3.png';
                            break;
                    }
                    posX+=64;
                }
                posX=0;
                posY+=64;
            }
        </script>
</body>
As you can see, my 3 switch options each are now waiting for the image to load before drawing it.
I read somewhere that it might be to do with the FOR loop, and I'd have to use an IIFE which I found more on here: What is the (function() { } )() construct in JavaScript? However, am completely unfamiliar with this term / concept nor do I know if I'm on the right track.
I was also trying to load this via an external js and then onload="drawTileMap()" in the body tag, however that throws up even funkier behaviour, because then it really seems to load random tiles instead of the entire grid.
Any help much appreciated!
 
    