【问题标题】:Image onload doesn't work sometimes图片加载有时不起作用
【发布时间】:2014-03-22 10:00:18
【问题描述】:
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();
}

backofcardredbackofcardblue 有时不会渲染到画布上。大多数时候我看到backofcardredbackofcardblue 所以问题是间歇性的。取消注释 // + '?' + (new Date()).getTime(); 只会让问题变得更糟。有什么办法可以确保每次都加载图像吗?我不反对 jQuery。我还不确定为什么会出现问题。有谁知道为什么有时图像没有绘制到画布上?

感谢您发布...

【问题讨论】:

    标签: html image canvas onload drawimage


    【解决方案1】:

    实际上解决方案更多的是var 部分。请仔细检查我,但似乎他将backofcardredbackofcardblue 泄漏到全局范围内,导致顶部和底部几乎相同的代码行为不端。

    使用 image.onload:

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

    【讨论】:

    • 代码已经在运行img.addEventListener("load", fn),效果很好。没有理由使用 .onload 代替它。
    • @jfriend00 实际上,解决方案更多的是我的答案中的var 部分。请仔细检查我,但似乎他正在将 backofcardred 和 backofcardblue 泄漏到全局范围内,导致顶部和底部几乎相同的代码行为不端。
    • 下一次,如果这是您回答的重点,那么您实际上应该在回答中用文字说出来。他的代码编写方式,backofcardredbackofcardblue 需要在范围内是全局的,因为它们在其他函数中使用。可以将代码更改为不需要这些全局变量,但我不认为这是间歇性问题的根源,除非此代码被多次调用用于不同的卡。
    • @jfriend00 很公平 :) 我可能应该说我担心潜在的范围界定问题。
    • 我把 var 放在 image 前面。我还没有注意到那些属于全局范围。感谢您对此的关注。我认为如果它们都以相同的方式工作,使用 onload 会更短一些。我选择了 onload 并添加了 var。我将不得不做一些测试......
    【解决方案2】:

    我们无法真正了解您的整体调用上下文以了解可能出现的问题。因此,我建议使用一些防御性编码来消除许多问题来源。要做的主要事情是摆脱用于卡片的全局变量。如果您碰巧不止一次调用renderCanvas(),或者这些变量存在范围问题,那么它们可能在使用时被覆盖或超出范围。完全删除卡全局变量将防止这种情况发生。此外,我还尝试使用一些共享函数删除一堆重复代码。

    变化:

    1. 通过将卡片设为局部变量来移除卡片的全局变量。
    2. 在加载回调中使用this
    3. 用共享的本地函数替换大量重复代码(不是潜在解决方案的一部分,但会使代码更简洁)。
    4. 将事件处理函数移动为本地函数(不需要是全局函数)。

    更改代码:

    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);
        }
    }
    

    【讨论】:

    • 有了这么好的帖子,很难只选择一个作为我的答案,但是这篇文章中有很多好的指针,我认为它会被标记为答案。感谢您的发表。我喜欢将它用于 onload 功能
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多