javascript:canvas上的图像(背景)

所以我的问题是我不能先画背景,然后在背景上画一切。 在我的代码中的一些地方(在循环function),它的工作原理,但在我的初始化函数不。 先介绍一下我的代码:

代码获取背景img并绘制它:

function imgImport(imgName,ctx){ var img = new Image(); img.onload = function(){ ctx.drawImage(img,0,0); }; img.src = 'client/img/' + imgName + '.jpg'; } module.exports = imgImport; 

很酷,现在在我的初始化函数我使用上面的代码是这样的:

 // var img = new Image(); // img.src = 'client/img/spaceship.jpg'; // ctx.drawImage(img,0,0); Img('spaceship',ctx); drawGrayzonePlanets(ctx,serverObjects); 

现在不要介意3条注释行。 第一个活动行Img('spaceship',ctx):是通过nodejs使用的上述imgImport函数。 DrawGrayzonePlanets如下所示:

 function drawGrayzonePlanets(ctx,serverObjects){ for(object in serverObjects){ obj = serverObjects[object]; Drawobjects(ctx,obj); } } 

本质上上面的函数从服务器获取数据,并使用Drawobjects()函数绘制行星,如下所示:

 function drawObjects(ctx,status){ switch(status.shape){ case "circle": var status = status.cic; console.log(status); ctx.fillStyle = status.color; ctx.beginPath(); ctx.arc(status.x,status.y,status.planetSize,0,2*Math.PI); ctx.stroke(); ctx.fill(); break; } } module.exports = drawObjects; 

现在,如果我先运行Img()函数,然后drawGrayzonePlanets()函数,行星将被绘制在背景后面,这意味着他们不能被看到。 同样的情况发生,如果我改变了代码的顺序,这是显而易见的。 现在我find了解决这个问题的方法,取消注释3行并取消img()函数。 并保留drawGrayzonePlanets()函数。 像这样:

 var img = new Image(); img.src = 'client/img/spaceship.jpg'; ctx.drawImage(img,0,0); //Img('spaceship',ctx); drawGrayzonePlanets(ctx,serverObjects); 

上面的代码工作,行星将被绘制在背景上。 但我只是不明白为什么该方法的作品,而不仅仅是通过使用Img()函数。 这可能与img.onload = function(){}有关,但我看不出为什么?

有人可以解释实际发生的事情吗?

因为你的imgImport是一个asynchronous函数。 img.onload里面的代码是在图像加载完成后运行的 – 但是当图像还在加载的时候,代码的其余部分就会运行,画出行星。 然后,一段时间后,图像到达并绘制在上面。

例如,您可以给imgImport函数一个第三个callback参数,并在其中运行代码的其余部分:

 function imgImport(imgName,ctx,callback){ var img = new Image(); img.onload = function(){ ctx.drawImage(img,0,0); callback() }; img.src = 'client/img/' + imgName + '.jpg'; } 

并执行它像这样:

 Img('spaceship',ctx,function() { drawGrayzonePlanets(ctx,serverObjects); }); 

在你的第一个代码中,你等待背景完成加载,然后绘制它。 这远远比其他图像的绘制晚。 在你的第二个代码你不等待加载。 最好的解决办法是callback:

 function imgImport(imgName,ctx,callback){ var img = new Image(); img.onload = function(){ ctx.drawImage(img,0,0); callback(); }; img.src = 'client/img/' + imgName + '.jpg'; } 

比这样使用:

  Img('spaceship',ctx,function(){ alert("bckground loading finished. Continue loading..."); drawGrayzonePlanets(ctx,serverObjects); });