Eae
Eae

Reputation: 4321

Image onload doesn't work sometimes

function rendercanvas()
{
    if(!window.isDirty && !gameover)
    {
        context.clearRect(0,0,window.innerWidth,1000);

        backofcardred = new Image();
        backofcardred.addEventListener('load', drawDealerStack);
        backofcardred.src = "graphics/backofcardred.jpg";// + '?' + (new Date()).getTime();


        backofcardblue = new Image();
        backofcardblue.addEventListener('load', drawClientStack);
        backofcardblue.src = "graphics/backofcardblue.jpg";// + '?' + (new Date()).getTime();


        context.beginPath();
        context.rect(100, 195, 100, 146);
        context.fillStyle = 'blue';
        context.fill();
        context.lineWidth = 1;
        context.strokeStyle = 'black';
        context.stroke();

        context.beginPath();
        context.rect(100, 343, 100, 146);
        context.fillStyle = 'red';
        context.fill();
        context.lineWidth = 1;
        context.strokeStyle = 'black';
        context.stroke();

        context.beginPath();
        context.fillStyle = 'black';
        context.strokeStyle = 'black';
        context.font = 'italic 30pt Calibri';
        var message = "Client Score:"+clientTally+" Dealer Score:"+dealerTally;
        context.fillText(message, 220,100);

        if(currentWinner!="")
        {

        }
    }

    if(window.isDirty && !gameover)
    {
        context.clearRect(0,0,window.innerWidth,1000);

        context.beginPath();
        context.fillStyle = 'black';
        context.strokeStyle = 'black';
        context.font = 'italic 30pt Calibri';
        var message = "Client Score:"+clientTally+" Dealer Score:"+dealerTally;
        context.fillText(message, 220,100);

        context.fillStyle = 'black';
        context.strokeStyle = 'black';
        context.font = 'italic 10pt Calibri';

        backofcardred = new Image();
        backofcardred.addEventListener('load', drawDealerStack);
        backofcardred.src = "graphics/backofcardred.jpg";// + '?' + (new Date()).getTime();


        backofcardblue = new Image();
        backofcardblue.addEventListener('load', drawClientStack);
        backofcardblue.src = "graphics/backofcardblue.jpg";// + '?' + (new Date()).getTime();


        if( clientwarareastack.cards[0] != null)
        {
            context.beginPath();
            context.rect(100,343,100,146);
            context.fillStyle = 'white';
            context.fill();
            context.lineWidth = 1;
            context.strokeStyle = 'white';
            context.stroke();
            context.beginPath();

            suitecharacter( clientwarareastack.cards[0] );
            var message = clientwarareastack.cards[0].rank + " " + suitUChar;
            context.fillText(message, 100+10, 343+25);
        }
        else
        {
            context.beginPath();
            context.rect(100, 343, 100, 146);
            context.fillStyle = 'red';
            context.fill();
            context.lineWidth = 1;
            context.strokeStyle = 'black';
            context.stroke();       
        }

        if( dealerwarareastack.cards[0] != null)
        {
            context.beginPath();
            context.rect(100,195,100,146);
            context.fillStyle = 'white';
            context.fill();
            context.lineWidth = 1;
            context.strokeStyle = 'white';
            context.stroke();   

            suitecharacter( dealerwarareastack.cards[0] );
            var message = dealerwarareastack.cards[0].rank + " " + suitUChar;
            context.fillText(message, 100+10, 195+25);
        }
        else
        {
            context.beginPath();
            context.rect(100, 195, 100, 146);
            context.fillStyle = 'blue';
            context.fill();
            context.lineWidth = 1;
            context.strokeStyle = 'white';
            context.stroke();       
        }

    }

    if(gameover)
    {
        context.clearRect(0,0,window.innerWidth,1000);
        context.fillText("GAME OVER. REFRESH THE PAGE TO START OVER.FINAL WINNER:"+finalwinner, 100+10, 195+25);
    }
}

function drawDealerStack() {
    context.beginPath();
    context.drawImage(backofcardblue, 100, 50);
    context.stroke();
}
function drawClientStack() {
    context.beginPath();
    context.drawImage(backofcardred, 100, window.originYclientstack);
    context.stroke();
}

backofcardred and backofcardblue sometimes do not render to the canvas. Most of time I see backofcardred and backofcardblue so the problem is intermittent. Uncommenting // + '?' + (new Date()).getTime(); only makes the problem far worse. Is there anything that can be done to make sure the image loads every time? I'm not opposed to jQuery. I'm not sure yet why the problem is happening. Does anyone know why the image sometimes isn't drawn to the canvas?

Thank you for posting...

Upvotes: 0

Views: 1715

Answers (2)

markE
markE

Reputation: 105035

Actually the solution is more the var part. Please double check me, but it appears he's leaking backofcardred & backofcardblue into global scope causing the almost identical code on-top and on-bottom to misbehave.

Use image.onload:

var image = new Image();
image.onload = function() {
    // the image is fully loaded and ready to use
}
image.src = "yourImage.png";

Upvotes: 1

jfriend00
jfriend00

Reputation: 707456

We can't really see enough of your overall calling context to understand what might be going wrong. As such, what I would recommend is some defensive coding that removes many sources of issues. The main thing to do is to get rid of the global variables you are using for the cards. If you happen to be calling renderCanvas() more than once or there's a scoping issue with those variables, then they may be getting overwritten while they are being used or go out of scope. Removing the card global variables entirely will protect against that. In addition, I've tried to remove a bunch of duplicate code with a few shared functions.

Changes:

  1. Removed global variables for the cards by making them local variables.
  2. Use this in the load callbacks.
  3. Replace lots of duplicate code with shared local functions (not part of the potential solution, but makes code a lot cleaner).
  4. Moved event handler functions to be local functions (no need to be global).

Changed code:

function rendercanvas() {
    function makeCards() {
        var backofcardred = new Image();
        backofcardred.addEventListener('load', drawDealerStack);
        backofcardred.src = "graphics/backofcardred.jpg";// + '?' + (new Date()).getTime();


        var backofcardblue = new Image();
        backofcardblue.addEventListener('load', drawClientStack);
        backofcardblue.src = "graphics/backofcardblue.jpg";// + '?' + (new Date()).getTime();
    }

    function drawRect(x, y, w, h, fill, width, stroke){
        context.beginPath();
        context.rect(x,y,w,h);
        context.fillStyle = fill;
        context.fill();
        context.lineWidth = width;
        context.strokeStyle = stroke;
        context.stroke();
    }

    function drawText(msg) {
        context.beginPath();
        context.fillStyle = 'black';
        context.strokeStyle = 'black';
        context.font = 'italic 30pt Calibri';
        context.fillText(msg, 220,100);
    }

    function drawDealerStack() {
        context.beginPath();
        context.drawImage(this, 100, 50);
        context.stroke();
    }

    function drawClientStack() {
        context.beginPath();
        context.drawImage(this, 100, window.originYclientstack);
        context.stroke();
    }

    if(!window.isDirty && !gameover)
    {
        context.clearRect(0,0,window.innerWidth,1000);
        makeCards();
        drawRect(100, 195, 100, 146, 'blue', 1, 'black');
        drawRect(100, 343, 100, 146, 'red', 1, 'black');
        drawText("Client Score:"+clientTally+" Dealer Score:"+dealerTally);


        if(currentWinner!="")
        {

        }
    }

    if(window.isDirty && !gameover)
    {
        context.clearRect(0,0,window.innerWidth,1000);
        drawText("Client Score:"+clientTally+" Dealer Score:"+dealerTally);
        makeCards();

        if( clientwarareastack.cards[0] != null)
        {
            drawRect(100,343,100,146, 'white', 1, 'white');
            context.beginPath();
            suitecharacter( clientwarareastack.cards[0] );
            var message = clientwarareastack.cards[0].rank + " " + suitUChar;
            context.fillText(message, 100+10, 343+25);
        }
        else
        {
            drawRect(100, 343, 100, 146, 'red', 1, 'black');
        }

        if( dealerwarareastack.cards[0] != null)
        {
            drawRect(100,195,100,146, 'white', 1, 'white');
            suitecharacter( dealerwarareastack.cards[0] );
            var message = dealerwarareastack.cards[0].rank + " " + suitUChar;
            context.fillText(message, 100+10, 195+25);
        }
        else
        {
            drawRect(100, 195, 100, 146, 'blue', 1, 'white');
        }

    }

    if(gameover)
    {
        context.clearRect(0,0,window.innerWidth,1000);
        context.fillText("GAME OVER. REFRESH THE PAGE TO START OVER.FINAL WINNER:"+finalwinner, 100+10, 195+25);
    }
}

Upvotes: 2

Related Questions