0

I cannot get my image to display in an HTML canvas using drawImage(). I know the filepath is correct because the image displays just fine when I disable display: none; I know this can occur when you attempt to draw an image before it is loaded, which you can avoid by using the onload property.

Here is the relevant HTML.

<canvas id='gameScreen'></canvas>
<img id="imgBall"src="assets/images/ball2.png" alt="ball">
<script type="module"src="src/index.js"></script>

Here is the relevant Javascript.

// CANVAS SETUP
let canvas = document.getElementById("gameScreen");
canvas.width = 800;
canvas.height = 600;
let ctx = canvas.getContext("2d");

// DISPLAY BALL
let imgBall = document.getElementById('imgBall');

imgBall.onload = function() {
    console.log(imgBall.src + ' successfully loaded');
    ctx.drawImage(imgBall, 10, 10);
}

imgBall.onerror = function() {
    console.log(imgBall.src + ' failed to load');
}

What makes this so confusing to me is that I'm not getting any console messages from imgBall.onload, or from imgBall.onerror.

I'm pretty new to Javascript and canvas, so I apologize if the answer is extremely obvious.

Phinbo
  • 1
  • 1
  • 1
    Its possible that the image has finished loading before the javascript has a chance to add the onload handler. – Daniel Jul 24 '21 at 19:30
  • As an aside, your HTML attributes are missing a space between them. Also, if img is display: none is the browser bothering to load it? – A Haworth Jul 24 '21 at 19:38
  • 1
    this code works just fine in a snippet with a random pic, there's something amiss with your image? check the path should it be "./assets/images/ball2.png" or "/assets/images/ball2.png" ? – Scott Weaver Jul 24 '21 at 19:39

1 Answers1

0

To fix the issue I am dynamically creating an image tag and then giving it a src AFTER I have added the event handlers for error and onload.

This makes me think that the issue is due to the image loading BEFORE your script tag had a chance to add the event listeners to the img tag.

// CANVAS SETUP
let canvas = document.getElementById("gameScreen");
canvas.width = 800;
canvas.height = 600;
let ctx = canvas.getContext("2d");

// DISPLAY BALL
const imgBall = document.createElement("img");

imgBall.onload = function() {
    console.log(imgBall.src + ' successfully loaded');
    ctx.drawImage(fitImageOntoCanvas(imgBall,25,25), 10, 10);
}

imgBall.onerror = function() {
    console.log(imgBall.src + ' failed to load');
}

imgBall.src = "https://pngimg.com/uploads/football/football_PNG52737.png"


// need to resize because my ball image is huge
// thanks @markE https://stackoverflow.com/questions/38664890/resize-images-with-canvas-before-uploading
function fitImageOntoCanvas(img,MAX_WIDTH,MAX_HEIGHT){

    // calculate the scaling factor to resize new image to 
    //     fit MAX dimensions without overflow
    var scalingFactor=Math.min((MAX_WIDTH/img.width),(MAX_HEIGHT/img.height))

    // calc the resized img dimensions
    var iw=img.width*scalingFactor;
    var ih=img.height*scalingFactor;

    // create a new canvas
    var c=document.createElement('canvas');
    var ctx=c.getContext('2d');

    // resize the canvas to the new dimensions
    c.width=iw;
    c.height=ih;

    // scale & draw the image onto the canvas
    ctx.drawImage(img,0,0,iw,ih);
    
    // return the new canvas with the resized image
    return(c);
}
<canvas id="gameScreen" height="500" width="500"></canvas>
Daniel
  • 1,392
  • 1
  • 5
  • 16
  • 1
    Who votes against, please explain the reason with at least a couple of words in the commentary. It is very interesting to figure out what exactly is wrong - both to the author of the answer and to everyone else. – Gleb Kemarsky Jul 24 '21 at 19:54
  • 1
    I'm glad I answered this question, ended up using this code almost exactly for placing a logo inside a qr code the very next day. – Daniel Jul 25 '21 at 22:16