javascript:画布上的图像绘制(背景)

时间:2017-02-04 17:21:18

标签: javascript node.js canvas drawing

所以我遇到的问题是我先无法绘制背景,然后在背景上绘制其他所有内容。在我的代码中的某些地方(在循环函数中)它可以工作,但在我的初始化函数中却没有。首先介绍一下我的代码:

获取背景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()函数,行星将被绘制在背景后面,这意味着它们无法被看到。如果我改变代码的顺序就会发生同样的情况,这很明显。现在我通过取消注释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(){}有关,但我不明白为什么?

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

2 个答案:

答案 0 :(得分:1)

在您的第一个代码中,您正在等待完成加载的背景,然后绘制它。这比其他图像的绘制要晚得多。在你的第二个代码中,你没有等待加载。最好的解决方案是回调:

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

答案 1 :(得分:0)

因为你的imgImport是一个异步函数。 function imgImport(imgName,ctx,callback){ var img = new Image(); img.onload = function(){ ctx.drawImage(img,0,0); callback() }; img.src = 'client/img/' + imgName + '.jpg'; } 内部的代码在图像加载后运行 - 但是当图像仍在加载时,其余代码将运行,绘制行星。然后,过了一会儿,图像到达并将其绘制在顶部。

例如,您可以为imgImport函数提供第三个回调参数,并在那里运行其余代码:

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

执行它:

    static String GetUserNames(List<string> userNames)
    {
        List<string> userNamesCopy = userNames.ToList();

        string strComment = "";
        Random r = new Random();
        int userIndex;
        do
        {
            userIndex = r.Next(0, userNamesCopy.Count);
            strComment += (userNamesCopy[userIndex] + " ");
            userNamesCopy.RemoveAt(userIndex);
        }
        while (userNamesCopy.Count > 0);
        return strComment;
    }