Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML5 Canvas blinking on drawing

I'm beginning with an isometric game, and my canvas is blinking(Not in IE) when draws all the parts of the ground. When I set fps to 20 or less, the blinking stops. How can I solve that? Any ideas?

var camerax = 300, cameray = 100;
var fps = 60;

function draw() {
    clearCanvas();
    drawGround();
}

function drawGround() {
    var img = new Image();
    img.onload = function() {
    var width = img.width;
    var height = img.height;
    for (var x = 0; x < 3; x++) {
        for (var y = 3; y >= 0; y--) {
                mx = (x-y)*height + camerax;
                my = (x+y)*height/2 + cameray; 
                ctx.drawImage(img, mx, my);
             }
        }
    }
    img.src = "ground.png";
}

var loop = setInterval(function() {
    update();
    draw();
}, 1000/fps);
like image 419
Marcilio Leite Avatar asked Jun 23 '13 13:06

Marcilio Leite


People also ask

Is HTML5 canvas still used?

The HTML5 canvas has the potential to become a staple of the web, enjoying ubiquitous browser and platform support in addition to widespread webpage support, as nearly 90% of websites have ported to HTML5.

Does HTML5 support canvas element?

The canvas element is part of HTML5 and allows for dynamic, scriptable rendering of 2D shapes and bitmap images.

Does HTML5 canvas work on mobile?

Browser/Platform Support.HTML5 Canvas is supported by all major browsers and can be accessed from desktops, tablets, and smartphones – once created a canvas application can run almost anywhere (unlike Flash and Silverlight). HTML5 Canvas offers great portability from desktops to mobile devices.

How do I reset my HTML canvas?

To clear the Canvas, you can use the clearRect() method. This method performs pretty well than others for clearing the canvas (such as resetting the width/height, destroying the canvas element and then recreating it, etc..) const context = canvas. getContext('2d'); context.


1 Answers

Right now you're reloading the image every frame and unless the onload callback fires within the 16ms of the frame you're going to see a blank canvas.

You should only need to call the new Image, img.onload sequence once, to preload your images. The onload callback would then kick off your first frame, and the draw calls are free to use the image in memory.

Something like:

var camerax = 300, cameray = 100;
var fps = 60;
var img;
var loop;

function init() {
    img = new Image();
    img.onload = function() {
        loop = setInterval(function() {
            update();
            draw();
        }, 1000/fps);
    };
    img.src = "ground.png";
}

function draw() {
    clearCanvas();
    drawGround();
}

function drawGround() {
    var width = img.width;
    var height = img.height;
    for (var x = 0; x < 3; x++) {
        for (var y = 3; y >= 0; y--) {
                mx = (x-y)*height + camerax;
                my = (x+y)*height/2 + cameray; 
                ctx.drawImage(img, mx, my);
             }
        }
    }
}

Of course, it gets more complex once you're waiting for multiple images to preload since you need to start the loop only once all of them are done.

like image 174
freejosh Avatar answered Oct 17 '22 03:10

freejosh