Question

I am trying to figure out how to switch images on a canvas without a small time of blankness in between.

To make my point here is an extreme example of this. In this program, when your spacebar is held down it redraws the image circle.png every milisecond. Because this is so fast the image dissappears.

I did try to preload my image but it didn't help.

Here is my full code:

// Access Canvas
var canvas = document.getElementById("gameBoard");
var ctx = canvas.getContext("2d");


// preload image
var circleReady = false;
var circleImage = new Image();
circleImage.onload = function () {
    circleReady = true;
};
circleImage.src = "images/Circle.png";



// Game objects
var circle = {
};

// circle location
circle.x = canvas.width / 2;
circle.y = canvas.height / 2;

// Keyboard events
var keysDown = {};

addEventListener("keydown", function (e) {
    keysDown[e.keyCode] = true;
}, false);

addEventListener("keyup", function (e) {
    delete keysDown[e.keyCode];
}, false);



// Update Objects

var update = function () {
    if (32 in keysDown) { // Player space pressed
        circleImage.src = "images/Circle.png"; //re-draws image
    }
};

// Draws Everything
var render = function () {
    ctx.fillStyle = "#FFFFFF";
    ctx.fillRect(0,0,600,609);

    if (circleReady) {
        ctx.drawImage(circleImage, circle.x, circle.y);
    }
};

// The main loop
var main = function () {
    update();
    render();

};

// Starts Function
var then = Date.now();
setInterval(main, 1); // Execute as fast as possible
Was it helpful?

Solution

You are reloading the image in the update function which is causing your delay:

circleImage.src = "images/Circle.png"; //re-draws image

All you have to do is drawImage without reloading the image:

ctx.drawImage(circleImage, circle.x, circle.y);

Here is an example of an image loader that loads all your images before execution begins:

    var imageURLs=[];  // put the paths to your images here
    var imagesOK=0;
    var imgs=[];
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house1.jpg");
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house2.jpg");
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house3.jpg");
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house4.jpg");
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house5.jpg");
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house6.jpg");
    loadAllImages(start);

    function loadAllImages(callback){
        for (var i=0; i<imageURLs.length; i++) {
            var img = new Image();
            imgs.push(img);
            img.onload = function(){ 
                imagesOK++; 
                if (imagesOK>=imageURLs.length ) {
                    callback();
                }
            };
            img.onerror=function(){alert("image load failed");} 
            img.crossOrigin="anonymous";
            img.src = imageURLs[i];
        }      
    }

    function start(){
        // all your images are fully loaded so begin your app
    }

OTHER TIPS

You can have two canvases, one for each image. When you want to switch. Remove or hide the one in the front, leaving (instantly) the one in the back.

Per your comment, here is an example of 26 letters of the alphabet. We only keep two canvases at a time. Each time the user clicks whe add a new only, and make the hidden one visible, with no delay.

function createCanvas(letter) {
    var canvas = document.createElement('canvas');
    canvas.id = letter;
    canvas.style.display = 'none';
    document.getElementById('container').appendChild(canvas);

    var image = new Image();
    image.src = 'http://icons.iconarchive.com/icons/iconicon/alpha-magnets/128/Letter-'+letter+'-icon.png';
    image.onload = function() {
      canvas.getContext('2d').drawImage(this, 0, 0);
    };

    return canvas;
}

createCanvas('a').style.display = '';
createCanvas('b');
var prevCharCode = 'a'.charCodeAt(0);
var charCode = 'b'.charCodeAt(0);

document.addEventListener('click', function() {
    document.getElementById(String.fromCharCode(charCode)).style.display = '';
    document.getElementById('container').removeChild(
        document.getElementById(String.fromCharCode(prevCharCode))
    );
    prevCharCode = charCode;
    if(++charCode > 'z'.charCodeAt(0)) {
      charCode = 'a'.charCodeAt(0);
    }
    createCanvas(String.fromCharCode(charCode));
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top