I\'m playing with the canvas element in HTML5 and I have noticed a peculiar behavior. On initial load, an image I\'m displaying does not show. However, when I refresh the b
Images load asynchronously, so only after refresh it loads early enough because it's cached. Normally it isn't loaded yet at the time you call drawImage
. Use onload
:
var image = new Image();
image.src = "Images/smiley.png";
image.onload = function() {
context.drawImage(image, 50, 50);
};
Actually, even just using image.onload = function() {}
, you can still run into problems. Do use this technique (that's not at all what I'm saying), but move it to the bottom of your page.
As an example, I have a social networking site that uses canvas to show the profile photo (URI stored to the DB), and print it to canvas, then overlay a logo.
<section id="content">
<article id="personalbox" >
<h2>Hi! My name is {profile_name}</h2>
<a id="friendbutton" href=""><img src="views/default/images/friend.png" width="12" height="12" /><span>Add {profile_name} as a friend?</span></a>
<video id="profilevideo" width="240" height="144">DEBUG: Video is not supported.</video>
<canvas id="profilecanvas" width="240" height="144" >DEBUG: Canvas is not supported.</canvas>
<a id="gallerytextlink" href="gallery.html" >Click to visit {profile_name} Gallery</a>
<table id="profileinfotable1">
...
</section>
<script type="text/javascript">
function init() {
var cvs = document.getElementById("profilecanvas");
var ctx = cvs.getContext("2d");
var img = new Image();
img.src = "uploads/profile/{profile_photo}";
img.onload = function() {
// Ignore. I was playing with the photo.
ctx.drawImage(img, 42, 32, 186, 130, cvs.width/2 - (186-42)/2, cvs.height/2 - (130-32)/2, 186-42, 130-32);
drawLogo(cvs,ctx);
}
}
function drawLogo(cvs,ctx) {
var logo = "Enter Logo Here.";
ctx.fillStyle = "rgba(36,36,36,0.6)";
ctx.strokeStyle = "rgba(255,255,255,0.3)";
ctx.font = "bold italic 6pt Serif";
ctx.textAlign = "left";
ctx.textBaseline = "middle" ;
ctx.save();
ctx.strokeText(logo, 4, cvs.height-11);
ctx.strokeText(logo, 6, cvs.height-11);
ctx.strokeText(logo, 4, cvs.height-9);
ctx.strokeText(logo, 6, cvs.height-9);
ctx.fillText(logo, 5, cvs.height-10);
ctx.restore();
}
window.onload = init;
</script>
Ideally, this would go all the way at the bottom before the end </body>
tag, but I put it up higher because of my template system. Apparently, this gives the image time to load after the canvas element has been drawn to the screen and is ready to receive input.
I can't rely on setting the background of the canvas, and I have no desire to contend with refreshes. For whatever reason, just including the script with img.onload = function() {}
was not enough. Move it lower, and save yourself the headaches.
This happened with me as well (only for IE9 for me) anyways, i found a simple solution.
Set the background of the canvas to the initial image you wish to display.
var canvas = document.getElementById("canvas");
canvas.style.background="url('image.png')";
That should work!