user1777953
user1777953

Reputation: 11

HTML5 Canvas - text not written on first load

I've being doing a technical test for a recruiter and have come across and extremely annoying bug with html5/canvas/javascript.

The problem only occurs intermittently and usually only on the first load of the page.

The images all load ok but the 3 character code only loads when I reload the page manually.

I've tried adding callbacks and even a setTimeout but there appeasr to be something happening on the initial load but I can't trap it.

Here's my code:

function Rectangle() {

    this.w = 111;
    this.h = 111;
    this.font_color = "white";
    this.font_family = "18pt Novecentowide";

}

Icon.prototype = new Rectangle();

function Icon(data) {

    this.code = data['code'];
    this.bg_color = data['bg_color'];
    this.x = data['x'];
    this.y = data['y'];
    this.code_x = data['code_x'];
    this.code_y = data['code_y'];
    this.icon_src = data['icon_src'];
    this.icon_x = data['icon_x'];
    this.icon_y = data['icon_y'];

    this.drawIcon = function () {

        // setup canvas
        var c = document.getElementById("canvasId");
        var ctx = c.getContext("2d");

        // draw rectangle
        ctx.fillStyle = this.bg_color;
        ctx.fillRect(this.x, this.y, this.w, this.h);

        // apply icon
        var img = new Image();
        img.src = this.icon_src;

        var icon_x = this.icon_x;
        var icon_y = this.icon_y;

        // get text values
        var font_color = this.font_color;
        var font_family = this.font_family;
        var code = this.code;
        var code_x = this.code_x;
        var code_y = this.code_y;

        img.onload = function () {
        // Once the image has finished loading, draw the 
        // image and then the text.

            function DrawScreen() {
                ctx.drawImage(img, icon_x, icon_y);
            }

            DrawScreen();

        };

        function DrawText() {
            ctx.fillStyle = font_color;
            ctx.font = font_family;
            ctx.fillText(code, code_x, code_y);
        }

        DrawText();

    }

}

var icon1 = new Icon({code: "ABC", bg_color: "c64918", x: 0, y: 0, code_x: 13, code_y: 98, icon_src: "images/shape_icon.png", icon_x: 0, icon_y: 0 });

var icon2 = new Icon({code: "DEF", bg_color: "d37724", x: 195, y: 0, code_x: 208, code_y: 98, icon_src: "images/shape_icon.png", icon_x: 195, icon_y: 0 });

var icon3 = new Icon({code: "GHI", bg_color: "556a70", x: 0, y: 151, code_x: 13, code_y: 249, icon_src: "images/hand_icon.png", icon_x: 0, icon_y: 151 });

var icon4 = new Icon({code: "JKL", bg_color: "55777f", x: 195, y: 151, code_x: 208, code_y: 249, icon_src: "images/hand_icon.png", icon_x: 195, icon_y: 151 });

var icon5 = new Icon({code: "MNO", bg_color: "68a03d", x: 0, y: 303, code_x: 13, code_y: 400, icon_src: "images/dollar_icon.png", icon_x: 0, icon_y: 303 });

icon1.drawIcon();

icon2.drawIcon();

icon3.drawIcon();

icon4.drawIcon();

icon5.drawIcon();

Can anyone shed some light on why this is happening.

Link to demo is: http://www.mpwa.co/html5

Any help would be very much appreciated.


Resolved the problem.

I wasn't checking to see if the document had loaded and so the first attempt at drawing on the canvas was failing.

Basics!!

Here's the key part of the working code...


function init() {

icon1.drawIcon();

icon2.drawIcon();

icon3.drawIcon();

icon4.drawIcon();

icon5.drawIcon();

}

var readyStateCheckInterval = setInterval(function () {

if (document.readyState === "complete") {

    init();

    clearInterval(readyStateCheckInterval);

}

}, 10);


Upvotes: 1

Views: 413

Answers (1)

Shmiddty
Shmiddty

Reputation: 13967

You should do it like this:

    img.onload = function () {
    // Once the image has finished loading, draw the 
    // image and then the text.           
        DrawScreen();
        DrawText();
    };
    function DrawScreen() {
        ctx.drawImage(img, icon_x, icon_y);
    }
    function DrawText() {
        ctx.fillStyle = font_color;
        ctx.font = font_family;
        ctx.fillText(code, code_x, code_y);
    }

Upvotes: 2

Related Questions