4

I am trying to put an image on a canvas. I read the following tutorial https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Using_images and tried to do something similar to it my canvas is <canvas id="canvas" width="400" height="400"></canvas> and I have created the function

  function putImage(){
         var img = new Image();
         img.src = "./path.png"; 
         var ctx = document.getElementById('canvas').getContext('2d');
         ctx.drawImage(img,8,8);            
  }

but the image is not appearing on the canvas. I have printed the image path and it is correct, so I was able to eliminate this issue. any suggestions?

thanks

Andressa
  • 44
  • 4
Quantico
  • 2,398
  • 7
  • 35
  • 59
  • Are you sure the image path is correct? Are you getting any errors on the developer console/firebug? – Hass Mar 11 '13 at 07:31
  • yes 100% sure i printed it to the console and it is the right path "./dir/image.png" no errors in the console – Quantico Mar 11 '13 at 07:48

3 Answers3

10

According to the tutorial, you're supposed to wrap your ctx.drawImage() inside img.onload like so

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  var img = new Image();
  img.onload = function() {
    ctx.drawImage(img, 0, 0);
  };
  img.src = '/files/4531/backdrop.png';
}

I hope this helps.

joe
  • 3,752
  • 1
  • 32
  • 41
Hass
  • 1,628
  • 1
  • 18
  • 31
  • 4
    To elaborate why you have to do this: When you set the `.src` attribute of an image, the image is requested from the server, but the program doesn't wait until the image has loaded. It keeps running, and when it comes to a ctx.drawImage method call which requires the not yet loaded image, it ignores this call. – Philipp Mar 11 '13 at 09:24
  • 1
    Which is why you have to wait for the image to load, then give it a callback function which then draws the image now that it's loaded – Justin Jun 03 '20 at 05:13
1

To add to Hass's answer: If you don't like the onload approach, you can await a Promise, like so:

async function draw() {
  let ctx = document.getElementById("canvas").getContext('2d');
  let url = "https://example.com/image.png";
  let img = new Image();
  await new Promise(r => img.onload=r, img.src=url);
  ctx.drawImage(img, 0, 0);
}
joe
  • 3,752
  • 1
  • 32
  • 41
1

If you don't like to use Promise or onload you can also use EventListener:

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  var img = new Image();
  img.addEventListener('load', function(){
    ctx.drawImage(img, 0, 0);
  });
  img.src = '/files/4531/backdrop.png';
}
Paweł Moskal
  • 613
  • 7
  • 10