加载图像以在 javascript 中的画布上绘图

Loading images for drawing on canvas in javascript

本文关键字:绘图 图像 javascript 加载      更新时间:2023-09-26

我一直在尝试教我 11 岁的儿子用 javascript 编程,但我自己是一名 java 程序员,我不太确定让以下内容发挥作用。 编写的代码在drawRocket方法中显示一个简单的块,但我儿子希望它显示火箭的图像。 但是,如果我在 drawImage 方法中注释并注释掉drawRect方法,则它不会显示火箭图像。

通过阅读堆栈溢出上有关此主题的各种线程,我了解到问题是 javascript 不会同步加载图像,因此我需要在火箭图像对象上使用 onload 侦听器编写代码。 但是,我尝试用以下代码替换main()调用(并从 main 方法中删除两行):

var rocket = new Image();
rocket.onload = main(rocket);
rocket.src = "rocket.jpg";

它仍然没有奏效。 我尝试了其他各种事情,但似乎没有什么对我有用。 火箭.jpg图像很好。

毫无疑问,答案非常简单,但 2 小时后我仍然在挣扎。 请帮忙吗?

谢谢!

三.

附言煤动力火箭是下一件大事;)

<head>
<script>
function drawSky(ctx) {
   ctx.fillStyle = "rgb(0,0,50)";
   ctx.fillRect(0, 0, 300, 300);
}
function drawGround(ctx) {
   ctx.fillStyle = "rgb(150,150,127)";
   ctx.fillRect(0, 295, 300, 5);
}
function drawRocket(ctx, rocket, height) {
   var drawHeight = 250 - height*2;
   if (drawHeight > 245)
      drawHeight = 245;
//   ctx.drawImage(rocket, 140, drawHeight, 20, 50);
   ctx.fillStyle = "rgb(255,0,0)";
   ctx.fillRect(140, drawHeight, 20, 50);
}
function drawExplosion(ctx, size) {
   ctx.fillStyle = "rgb(255,102,0)";
   ctx.beginPath();
   ctx.arc(150, 295, size, 180*Math.PI/180, 360*Math.PI/180);
   ctx.fill();
}
function drawCoalBar(ctx, coal) {
   ctx.fillStyle = "rgb(255,255,255)";
   ctx.fillText("COAL", 10, 25);   

   if (coal <= 15)
      ctx.fillStyle = "rgb(255,0,0)";  
   else if (coal <= 30)
      ctx.fillStyle = "rgb(255,125,0)";
   else
      ctx.fillStyle = "rgb(255,225,0)";

   ctx.fillRect(45, 15, coal*4, 10);   
   ctx.strokeStyle = "rgb(255,255,255)";
   ctx.strokeRect(45, 15, 60*4, 10);   
}
function main() {
var canvas = document.getElementById('gameview');
var ctx = canvas.getContext('2d');
var rocket = new Image();
rocket.src = "rocket.jpg";
drawSky(ctx);
drawGround(ctx);
var name = prompt("What is your name?");
document.write("<p>Good luck Captain " + name + "!</p>");
var height = 100;
var speed = 0;
var coal = 60;
var burn = 0;
var gravity = 5;
var maxSpeedForSafeLanding = 8;
document.write("<p>");
document.write("The maximum speed for a safe landing is " + maxSpeedForSafeLanding + "m/s.");
document.write("<p>");
while (height > 0)
{
   document.write("Burn: " + burn + "kg");
   document.write(" - Height: " + height + "m");
   document.write(" - Speed: " + speed + "m/s");
   document.write(" - Coal: " + coal + "kg");
   document.write("<br />"); 
   drawSky(ctx);
   drawGround(ctx);
   drawRocket(ctx, rocket, height);
   drawCoalBar(ctx, coal);   

   // Ask for ammount of coal to burn
   var burn = prompt("How much coal do you want to burn?");
   burn = Number(burn);
   if (burn > coal)
     burn = coal;
   if (-burn > coal)
     burn = -coal;

   if (burn >= 0)
     coal = coal - burn;
   else
     coal = coal + burn;
   speed = speed + gravity - burn;
   height = height - speed; 
}
document.write("</p>");
drawSky(ctx);
drawGround(ctx);

if (speed <= maxSpeedForSafeLanding) {
   drawRocket(ctx, 0);
   document.write("<p>Congratulations Captain " + name + ".  You landed safely with a speed of " + speed + "m/s and you still have " + coal + "kg of coal left.</p>");
} else {
   drawExplosion(ctx, 25+coal*2+speed*2);
   document.write("<p>Rest In Peace Captain " + name + ".  You crashed with a speed of " + speed + "m/s and you still had " + coal + "kg of coal left.You will be burried on the planet you crashed on.</p>");
}
drawCoalBar(ctx, coal);
}
</script>
</head>
<body>
<h1>Rocket Lander Game</h1>
<canvas id="gameview" width="300" height="300"></canvas>
<script>
main();
</script>
</body>

试试这个:

var rocket = new Image();
rocket.onload = function(){ main(rocket) };
rocket.src = "rocket.jpg";

正在发生的事情是,您正在调用函数main(),而main的结果将提供给onload

你可以简单地这样写它来引用main

rocket.onload = main;  //main will be invoked when image is loaded

rocket.onload = function(e) { main() };

在后者中,我们给出一个匿名函数作为参数,当调用该函数时,main()在其中被调用。如果要在调用 main() 之前对映像执行其他操作,这将非常有用。

由于rocket在这种情况下是全局可用的,因此无需将其作为参数提供给main但是如果您需要使用其他图像调用main,这当然是一种很好的方法。但是你可以添加一个参数变量到main:

function main(image) {
    /// ctx.drawImage(image, 0, 0); etc..
}

还可以考虑为图像实现一个onerror回调处理程序,以防由于图像加载而出错。