【问题标题】:javascript: Image drawing(background) on canvasjavascript:画布上的图像绘制(背景)
【发布时间】:2017-02-04 17:21:17
【问题描述】:

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

获取背景图片并绘制的代码:

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(){} 有关,但我不明白为什么?

有人能解释一下到底发生了什么吗?

【问题讨论】:

  • 我没有看到任何地方定义了 Img 函数。
  • 你能做code snipper或jsfiddle吗?

标签: javascript node.js canvas drawing


【解决方案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);
});

【讨论】:

    【解决方案2】:

    因为您的 imgImport 是一个异步函数。 img.onload 内部的代码在图像加载后运行 - 但在图像仍在加载时,您的其余代码将运行,绘制行星。然后,过了一会儿,图像到达并将其绘制在上面。

    例如,您可以为 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';
    }
    

    并像这样执行它:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-20
      • 1970-01-01
      • 2021-02-14
      • 2019-04-16
      • 2016-08-05
      • 2017-02-23
      相关资源
      最近更新 更多