清空画布后图像未绘制(HTML5画布)

3
我正在尝试用JavaScript制作Boomshine游戏的变体,当我使用arc函数绘制圆形时一切正常。但是,当我尝试使用drawImage函数替换arc函数以使用硬币图像而不是圆形时,在清除画布以删除先前绘制的圆形形状时就会出现问题。如果在渲染图像之前不清除画布,则会在画布上绘制图像,但旧图像仍然存在于画布上。但是,当我在再次渲染图像之前清除画布时,画布上没有绘制任何内容。
我已经包含了屏幕截图,链接如下。
这是我清除画布的方法:
var ctx = game.context;
ctx.fillStyle = "darkgray";
ctx.fillRect(0, 0, game.canvas.width, game.canvas.height);

这是我绘制图像的方法:
function drawImageBall(x,y,radius,startAngle,color)
{
var img = document.createElement('img');
img.src = 'img/coin-icon.png';

var tmpCtx= game.context;
var ax = x-radius;
var ay = y-radius;

img.onload = function() {
    tmpCtx.save();
    tmpCtx.beginPath();
    tmpCtx.arc(x, y, radius, 0, Math.PI * 2, true);
    tmpCtx.closePath();
    tmpCtx.clip();

    tmpCtx.drawImage(img, ax, ay, img.width, img.height);

    tmpCtx.beginPath();
    tmpCtx.arc(0, 0, radius, 0, Math.PI * 2, true);
    tmpCtx.clip();
    tmpCtx.closePath();
    tmpCtx.restore();
};
}

清空画布(截图) 不清空画布(截图)


我不确定我们是否有足够的源代码来解决这个问题。实际上,我写了一个fiddle作为概念证明;我唯一调整的是起始角度以模拟弧形绘制,所以你发布的代码基本上没有问题。抱歉会出现闪烁,我只是想尽快得到一些结果。 - sfdcfox
你只在图像加载时绘制图像,而不是每次调用drawImageBall时都绘制。 - nasso
2个回答

1

请记住,下载 img 会花费一些时间。

在下载期间,Javascript 不会停止(!)。相反,JS 将继续执行任何后续的代码。这会导致您出现意外的问题。

因此,在应用程序开始时只需下载一次 img。这样,您的 drawImage 将按照您预期的顺序完成,因为在下载图像时不会有延迟。


我将图像添加到全局游戏对象中,现在它可以正常工作了! - Ferre12
@FerreTahon。很高兴你解决了它。干杯! - markE

1
使用您的代码,我做了一些更改,删除了tmpTcx.clip(),请看fidlle。提示:为了性能问题,您不需要每次想要写画布时都加载图像。
糟糕的示例:https://jsfiddle.net/wf4z0d2h/1/
function clearCanvas(){
        var ctx = game.context;
        ctx.fillStyle = "darkgray";
        ctx.fillRect(0, 0, game.canvas.width, game.canvas.height);
    }

    function drawImageBall(x,y,radius,startAngle,color)
    {
        if(x == undefined){x = 100;}
        if(y == undefined){y = 100;}
        if(radius == undefined){radius = 40;}

        //var img = document.createElement('img');
        //img.src = 'img/coin-icon.png';
        //img.src = "http://ps2.lansa.com/images/icons/normal/256/coin_256.png";

        var tmpCtx= game.context;
        var ax = x-radius;
        var ay = y-radius;


        //img.onload = function() {
            tmpCtx.save();
            tmpCtx.beginPath();
            tmpCtx.arc(x, y, radius, 0, Math.PI * 2, true);
            tmpCtx.stroke(); // Draw it
            tmpCtx.closePath();
            //tmpCtx.clip();


            tmpCtx.drawImage(img, ax, ay, img.width, img.height);

            //tmpCtx.beginPath();
            //tmpCtx.arc(0, 0, radius, 0, Math.PI * 2, true);
            ////tmpCtx.clip();
            //tmpCtx.stroke(); // Draw it
            //tmpCtx.closePath();
            //tmpCtx.restore();
        //};
    }
    var img = document.createElement('img');
        //img.src = 'img/coin-icon.png';
        img.src = "http://ps2.lansa.com/images/icons/normal/256/coin_256.png";

    //drawImageBall();
    img.onload = function(){
    x = 0;
    y = 0;
    setInterval(function(){
        x = x+10;
        y = y+10;
        clearCanvas();
        drawImageBall(x,y);

    },300);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接