javascript:canvas 上的图像绘图(背景)
javascript: Image drawing(background) on canvas
所以我遇到的问题是我无法先绘制背景,然后再在背景之上绘制其他所有内容。在我的代码中的某些地方(在循环函数中)它有效,但在我的初始化函数中它不起作用。首先介绍一下我的代码:
获取背景图片并绘制的代码:
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(){} 有关,但我不明白为什么?
谁能解释一下到底发生了什么?
因为你的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);
});
在您的第一个代码中,您正在等待背景完成加载,然后绘制它。这显然晚于其他图像的绘制。在您的第二个代码中,您没有等待加载。最好的解决方案是回调:
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);
});
所以我遇到的问题是我无法先绘制背景,然后再在背景之上绘制其他所有内容。在我的代码中的某些地方(在循环函数中)它有效,但在我的初始化函数中它不起作用。首先介绍一下我的代码:
获取背景图片并绘制的代码:
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(){} 有关,但我不明白为什么?
谁能解释一下到底发生了什么?
因为你的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);
});
在您的第一个代码中,您正在等待背景完成加载,然后绘制它。这显然晚于其他图像的绘制。在您的第二个代码中,您没有等待加载。最好的解决方案是回调:
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);
});