Javascript becomes unresponsive after button presses - javascript
When I push the buttons (N and O ) maybe 10 times, the script becomes very unresponsive, does anyone have a solution for this?
What I'm trying to do is to have 2 menus in a game. This is a test which should have the same effect.
//html code
<!DOCTYPE html>
<html lang ="en">
<head>
<meta charset="UTF-8">
<title>Snake</title>
</head>
<body>
<style>
canvas{
display: block;
position: absolute;
border: 1px solid "Black";
margin: auto;
top: 0;
bottom: 0;
right: 0;
left: 0;
}
</style>
<script type = "text/javascript" src = "menu2.js"></script>
<script type = "text/javascript" src = "menu1.js"></script>
<script type = "text/javascript" src = "main.js"></script>
<script type = "text/javascript">
main();
</script>
</body>
</html>
//main function
var
COLS = 20,
ROWS = 20,
canvas,
ctx,
keystate,
KEY_O = 79,
KEY_N = 78;
var main = function()
{
// create and initiate the canvas element
canvas = document.createElement("canvas");
canvas.width = COLS*20;
canvas.height = ROWS*20;
ctx = canvas.getContext("2d");
// add the canvas element to the body of the document
document.body.appendChild(canvas);
// sets an base font for bigger score display
ctx.font = "12px Ariel";
keystate = {};
// keeps track of the keybourd input
document.addEventListener("keydown", function(evt) {
keystate[evt.keyCode] = true;
});
document.addEventListener("keyup", function(evt) {
delete keystate[evt.keyCode];
});
menu1();
};
//first menu
var menu1 = function()
{
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "Red";
ctx.fillRect(0,0,canvas.height, canvas.width);
document.addEventListener('keydown', function(event) {
if (keystate[KEY_N]) {
menu2();
}});
};
//second menu
var menu2 = function()
{
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "Blue";
ctx.fillRect(0,0,canvas.height, canvas.width);
document.addEventListener('keydown', function(event) {
if (keystate[KEY_O]) {
menu1();
}});
};
Each time you call menu2(); or menu1(); you are adding a new EventListener, which again calls menu2(); or menu1(); ...and more event listeners get added every time. This means that your number of event listeners grows at an enormous rate as you keep pressing keys, and slows the script down. You only need one EventListener per key, set it outside of the menu function.
issue is with adding eventListeners on each call of menu1 and menu2 .what you need is simply put it out side of both in main like this:
document.addEventListener('keydown', function(event) {
if (keystate[KEY_N]) {
menu2();
}
if (keystate[KEY_O]) {
menu1();
}
});
<!DOCTYPE html>
<html lang ="en">
<head>
<meta charset="UTF-8">
<title>Snake</title>
</head>
<body>
<style>
canvas{
display: block;
position: absolute;
border: 1px solid "Black";
margin: auto;
top: 0;
bottom: 0;
right: 0;
left: 0;
}
</style>
<script type = "text/javascript">
var
COLS = 20,
ROWS = 20,
canvas,
ctx,
keystate,
KEY_O = 79,
KEY_N = 78;
var main = function()
{
// create and initiate the canvas element
canvas = document.createElement("canvas");
canvas.width = COLS*20;
canvas.height = ROWS*20;
ctx = canvas.getContext("2d");
// add the canvas element to the body of the document
document.body.appendChild(canvas);
// sets an base font for bigger score display
ctx.font = "12px Ariel";
keystate = {};
// keeps track of the keybourd input
document.addEventListener("keydown", function(evt) {
keystate[evt.keyCode] = true;
if (keystate[KEY_N]) {
menu2();
}
if (keystate[KEY_O]) {
menu1();
}
});
document.addEventListener("keyup", function(evt) {
delete keystate[evt.keyCode];
});
menu1();
};
//first menu
var menu1 = function()
{
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "Red";
ctx.fillRect(0,0,canvas.height, canvas.width);
};
//second menu
var menu2 = function()
{
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "Blue";
ctx.fillRect(0,0,canvas.height, canvas.width);
};
main();
</script>
</body>
</html>
Note: open snippet window then click inside it then press o and n to see the effect.
Related
Why does my game character keep accelerating when I use the keydown event?
I am trying to make a simple game. The green block is my game character. I used a the keydown event to make my character able to move right and left. When I hold down the right or left arrow key, the character keeps on accelerating. If you start by tapping the right or left arrow key, you will see that the space interval between where the character was and where it is increases as you click more. How can I make my character move at a constant speed with constant space intervals. //variables var canvas = document.getElementById("canvas"); var draw = canvas.getContext("2d"); var characterx = 20; var charactery = window.innerHeight - 60; var dx = 0.01; var dy = 0.01; //canvas size canvas.width = window.innerWidth; canvas.height = window.innerHeight; //main game function function run() { //loops the function requestAnimationFrame(run); //clears the screen draw.clearRect(0, 0, canvas.width, canvas.height) //draws the ground draw.beginPath(); draw.fillStyle = "#823819"; draw.fillRect(0, canvas.height - 20, canvas.width, 20); draw.fill(); draw.closePath(); //draws the main character draw.beginPath(); draw.fillStyle = "#128522"; draw.fillRect(characterx, charactery, 40, 40); draw.fill(); draw.closePath(); //key evevnts window.addEventListener("keydown",function(event) { if(event.keyCode == 39) { characterx += dx; } }); window.addEventListener("keydown",function(event) { if(event.keyCode == 37) { characterx -= dx; } }); }; run(); <!DOCTYPE html> <html> <head> <title>Test</title> <style type="text/css"> body { margin: 0; overflow: hidden; } canvas { margin: 0; overflow: hidden; } </style> </head> <body> <canvas id="canvas"></canvas> <script type="text/javascript" src="script.js"></script> </body> </html>
Your event listeners should be added outside of your game loop. Currently you are adding an extra listener for each keypress on every frame, meaning that on the first frame you will move dx * 1 for a keypress, but on frame 100 you will move dx * 100 for a single keypress. This is also why your dx value had to be so low - I've increased it in the sample below, but you can adjust it as needed. //variables var canvas = document.getElementById("canvas"); var draw = canvas.getContext("2d"); var characterx = 20; var charactery = window.innerHeight - 60; var dx = 3.0; var dy = 3.0; //canvas size canvas.width = window.innerWidth; canvas.height = window.innerHeight; //key evevnts window.addEventListener("keydown",function(event) { if(event.keyCode == 39) { characterx += dx; } }); window.addEventListener("keydown",function(event) { if(event.keyCode == 37) { characterx -= dx; } }); //main game function function run() { //loops the function requestAnimationFrame(run); //clears the screen draw.clearRect(0, 0, canvas.width, canvas.height) //draws the ground draw.beginPath(); draw.fillStyle = "#823819"; draw.fillRect(0, canvas.height - 20, canvas.width, 20); draw.fill(); draw.closePath(); //draws the main character draw.beginPath(); draw.fillStyle = "#128522"; draw.fillRect(characterx, charactery, 40, 40); draw.fill(); draw.closePath(); }; run(); <!DOCTYPE html> <html> <head> <title>Test</title> <style type="text/css"> body { margin: 0; overflow: hidden; } canvas { margin: 0; overflow: hidden; } </style> </head> <body> <canvas id="canvas"></canvas> <script type="text/javascript" src="script.js"></script> </body> </html>
Html5 canvas animation leaves a trail
I'm trying to make a little game to play around with canvas. I've decided to go for Flappy Bird as there are plenty of examples online. My goal was to make the game "responsive" for all devices. If you open it in a mobile or whichever screen, you should be able to play it normally. For this purpose I drew a background image within the canvas that will adapt the height to the screen's height and repeat it through the x-axis. The issue I'm having is that, when I animate the bird, this one leaves a trail behind it. As like so: An easy fix would be clearing the canvas as explained in this post: Canvas image leaves weird trail when moving left But it isn't possible because of the way I'm painting my background (I paint it once and repaint it if it resizes). Question How do I avoid this image trail with a static background? Is it maybe possible to have like a false static background that doesn't need to be repainted? I obviously want to do it in the canvas, without needing to have an image in the html. This is the code with the main functionality so that you can take a look: const cvs = document.getElementById("canvas"); const ctx = cvs.getContext("2d"); cvs.style.height = "100vh"; cvs.style.width = "100vw"; var bird = new Image(); var bg = new Image(); bird.src = "https://lh3.googleusercontent.com/prntPuix7QxlhKXx6IBtTxv7PrdEJtmzFJ4mopScNS1_klze86BVNy3PqHbQn2UQ4JyJdix3XQ=w128-h128-e365"; bg.src = "https://opengameart.org/sites/default/files/bg_5.png"; let gravity = 1; birdPositionY = 10; birdPositionX = 50; const draw = () => { ctx.drawImage(bird, birdPositionX, birdPositionY); birdPositionY += gravity; birdPositionX += 3; requestAnimationFrame(draw); }; const resizeCanvas = () => { const { width, height } = cvs.getBoundingClientRect(); cvs.height = height; cvs.width = width; let x = 0, y = 0; while (x < cvs.width && y < cvs.height) { ctx.drawImage(bg, x, y, 360, cvs.height); x += bg.width; } }; bg.onload = () => { resizeCanvas(); }; window.addEventListener("resize", resizeCanvas, false); draw(); <!DOCTYPE html> <html> <head> <title>Flappy Bird</title> <meta name="viewport" content="width=device-width, user-scalable=no" /> <style> html { overflow: hidden; } body { margin: 0; } canvas { width: 100vw; height: 100vh; } </style> </head> <body> <canvas id="canvas"></canvas> <script src="index.js"></script> </body> </html> Hope it did make sense! Thanks in advance!
Draw your background on a canvas that you will keep off-screen, then draw this canvas every frame on your visible one before you draw your moving parts. const cvs = document.getElementById("canvas"); const ctx = cvs.getContext("2d"); // our backround canvas that we won't append in the doc ("off-screen") const background = cvs.cloneNode(); const bg_ctx = background.getContext('2d'); cvs.style.height = "100vh"; cvs.style.width = "100vw"; var bird = new Image(); var bg = new Image(); bird.src = "https://lh3.googleusercontent.com/prntPuix7QxlhKXx6IBtTxv7PrdEJtmzFJ4mopScNS1_klze86BVNy3PqHbQn2UQ4JyJdix3XQ=w128-h128-e365"; bg.src = "https://opengameart.org/sites/default/files/bg_5.png"; let gravity = 1; birdPositionY = 10; birdPositionX = 50; const draw = () => { // first draw the background canvas ctx.drawImage(background, 0,0); // then your persona ctx.drawImage(bird, birdPositionX, birdPositionY); birdPositionY += gravity; birdPositionX += 3; requestAnimationFrame(draw); }; const resizeCanvas = () => { const { width, height } = cvs.getBoundingClientRect(); // resize both canvases cvs.height = background.height = height; cvs.width = background.width = width; let x = 0, y = 0; while (x < cvs.width && y < cvs.height) { // draw on the off-screen canvas bg_ctx.drawImage(bg, x, y, 360, cvs.height); x += bg.width; } }; bg.onload = () => { resizeCanvas(); draw(); }; window.addEventListener("resize", resizeCanvas, false); <!DOCTYPE html> <html> <head> <title>Flappy Bird</title> <meta name="viewport" content="width=device-width, user-scalable=no" /> <style> html { overflow: hidden; } body { margin: 0; } canvas { width: 100vw; height: 100vh; } </style> </head> <body> <canvas id="canvas"></canvas> <script src="index.js"></script> </body> </html>
I think you could just call resizeCanvas in your draw loop to redraw the background. EDIT: Apparently that does not work. Another option is just drawing it in the draw loop like this: const draw = () => { ctx.clearRect(0, 0, cvs.width, cvs.height) let x = 0, y = 0; while (x < cvs.width && y < cvs.height) { ctx.drawImage(bg, x, y, 360, cvs.height); x += bg.width; } ctx.drawImage(bird, birdPositionX, birdPositionY); birdPositionY += gravity; birdPositionX += 3; requestAnimationFrame(draw); }; Edit: That did not work either. The other option would be to make two canvases and overlap them with one drawing the background and one drawing the bird.
Change image source created by context.drawimage
This code allow me to draw cross, with its (x,y) coordinates, one by one with 5 seconds of interval , it works fine : <script src="http://alertifyjs.com/build/alertify.js"></script> <link rel="stylesheet" href="http://alertifyjs.com/build/css/alertify.css" /> <link rel="stylesheet" href="http://alertifyjs.com/build/css/themes/default.css" /> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <div style="width : 75%;margin : auto;"> <canvas id="Canvas" width="954" height="267"></canvas> <button class="play">Play</button> <button class="pause">Pause</button> </div> <script> var canvas = document.getElementById('Canvas'); var context = canvas.getContext("2d"); // Map sprite var mapSprite = new Image(); mapSprite.src = "v1.png"; var array_x = [351,315,353,352,318,485,351,748,568,645,373,350,572,374,650,240,240,320,707,235,402,539,256,410,433,405,353,745,404,320,514,322,692,474,293,418,418,690,237,513,378,478,433,405,285,429,458,622,568,536,564,389,641,534,567,454,575,482,459,539,431,327,464,374,348,520,279,378,509,516,232,744,351,710,481,540,429,642,537,459,513,689,324,463,375,747,431,265,484,591,458,460,485,407,720,483,376,520,691,376,232,413,536,430,653,714,484,715,629,573,263,408,436,300,544,407,432,568,536,462,485,346,610,524]; var array_y = [18,18,181,228,60,232,34,32,26,37,65,62,228,180,91,83,83,81,88,62,35,65,52,155,23,90,94,95,230,232,15,105,37,68,47,186,186,93,14,65,22,10,230,68,18,91,226,22,150,227,89,43,76,92,62,12,187,96,78,33,35,180,151,230,151,154,95,96,31,233,39,77,79,20,30,165,65,51,18,62,96,19,150,33,79,19,35,23,210,20,180,95,184,19,76,64,36,186,73,151,26,192,153,156,24,36,165,97,85,78,77,101,184,22,177,212,210,166,79,210,150,168,45,18]; var isPaused = false; var firstLoad = function () { context.font = "15px Georgia"; context.textAlign = "center"; } firstLoad(); var main = function () { draw(); }; var draw = function () { // Clear Canvas context.fillStyle = "#000"; context.fillRect(0, 0, canvas.width, canvas.height); // Draw map context.drawImage(mapSprite, 0, 0, 954, 267); //draw red cross cross = new Image(); cross.src = "cross.png"; // draw blue cross cross1 = new Image(); cross1.src = "cross-blue.png"; var t = window.setInterval(function() { if(!isPaused) { event_coor(); } }, 5000); i=0; function event_coor() { if (i < array_x.length) { context.drawImage(cross, array_x[i], array_y[i], 10, 10); i=i+1; } } } mapSprite.addEventListener('load', main); //with jquery $('.pause').on('click', function(e) { e.preventDefault(); isPaused = true; }); $('.play').on('click', function(e) { e.preventDefault(); isPaused = false; }); </script> What I want to do is to change the color of the image cross that will be displayed under mapSprite, let's say displaying it in red cross.png and after displaying the second one, the oldest will turn to blue cross-blue.png at the same time. As that I will always have the last one in red to catch the attention. How to change le last image source context.drawimage after few seconds? Thanks a lot. EDIT 1 : Redraw above the last one after 2seconds <script src="http://alertifyjs.com/build/alertify.js"></script> <link rel="stylesheet" href="http://alertifyjs.com/build/css/alertify.css" /> <link rel="stylesheet" href="http://alertifyjs.com/build/css/themes/default.css" /> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <div style="width : 75%;margin : auto;"> <canvas id="Canvas" width="954" height="267"></canvas> <button class="play">Play</button> <button class="pause">Pause</button> </div> <script> var canvas = document.getElementById('Canvas'); var context = canvas.getContext("2d"); // Map sprite var mapSprite = new Image(); mapSprite.src = "v1.png"; var array_x = [351,315,353,352,318,485,351,748,568,645,373,350,572,374,650,240,240,320,707,235,402,539,256,410,433,405,353,745,404,320,514,322,692,474,293,418,418,690,237,513,378,478,433,405,285,429,458,622,568,536,564,389,641,534,567,454,575,482,459,539,431,327,464,374,348,520,279,378,509,516,232,744,351,710,481,540,429,642,537,459,513,689,324,463,375,747,431,265,484,591,458,460,485,407,720,483,376,520,691,376,232,413,536,430,653,714,484,715,629,573,263,408,436,300,544,407,432,568,536,462,485,346,610,524]; var array_y = [18,18,181,228,60,232,34,32,26,37,65,62,228,180,91,83,83,81,88,62,35,65,52,155,23,90,94,95,230,232,15,105,37,68,47,186,186,93,14,65,22,10,230,68,18,91,226,22,150,227,89,43,76,92,62,12,187,96,78,33,35,180,151,230,151,154,95,96,31,233,39,77,79,20,30,165,65,51,18,62,96,19,150,33,79,19,35,23,210,20,180,95,184,19,76,64,36,186,73,151,26,192,153,156,24,36,165,97,85,78,77,101,184,22,177,212,210,166,79,210,150,168,45,18]; var isPaused = false; var firstLoad = function () { context.font = "15px Georgia"; context.textAlign = "center"; } firstLoad(); var main = function () { draw(); }; var draw = function () { // Clear Canvas context.fillStyle = "#000"; context.fillRect(0, 0, canvas.width, canvas.height); // Draw map context.drawImage(mapSprite, 0, 0, 954, 267); //draw red cross cross = new Image(); cross.src = "cross.png"; // draw blue cross cross1 = new Image(); cross1.src = "cross-blue.png"; var t = window.setInterval(function() { if(!isPaused) { event_coor(); } }, 5000); i=0; function event_coor() { if (i < array_x.length) { context.drawImage(cross, array_x[i], array_y[i], 10, 10); window.setInterval (function () { context.drawImage(cross1, array_x[i], array_y[i], 10, 10);}, 2000); i=i+1; } } } mapSprite.addEventListener('load', main); //with jquery $('.pause').on('click', function(e) { e.preventDefault(); isPaused = true; }); $('.play').on('click', function(e) { e.preventDefault(); isPaused = false; }); </script>
You have to redraw the whole scene, or if the cross is not overlapped by other elements / has solid color, just the cross. There is no way to change the src of already rendered element, since there is no history (scene graph) of what has been drawn on canvas previously.
Canvas width percent in javascript
I have a canvas that I have in html that is supposed to be 25% of the page. I made a variable named width in javascript, and put it's value as 25%. When I make a context.clearRect(); with the width variable as the width parameter, it doesn't fix it what I was trying to do (which I have done tons of times) which is when the player rectangle moves, the clearRect keeps the background circulating so the rectangle isn't drawing (leaving a mark). Here is my width variable: var width = 25%; Here is my clearRect(); context.clearRect(0, 0, width, height); Edit: I guess I will also post my whole entire code, to be easier. <html> <head> <title></title> <style type="text/css"> body { background-color: #222222; } canvas { background-color: #000000; width: 25%; height: 400px; } </style> </head> <body> <canvas id="mainCanvas"></canvas> <script type="text/javascript"> var canvas = document.getElementById("mainCanvas"); var context = canvas.getContext("2d"); var keys = []; var speed = 4; var width = 25%; var height = 400; window.addEventListener("keydown", function(e) { keys[e.keyCode] = true; }, false); window.addEventListener("keyup", function(e) { delete keys[e.keyCode]; }, false); var player = { x: 10, y: 10, width: 30, height: 30 }; function game() { update(); render(); } function update() { if (keys[40]) player.y++ * speed; if (keys[38]) player.y-- * speed; if (keys[37]) player.x-- * speed; if (keys[39]) player.x++ * speed; } function render() { context.clearRect(0, 0, (canvas.width * 0.25)), height); context.fillStyle = "white"; context.fillRect(player.x, player.y, player.width, player.height); } setInterval(function() { game(); }, 1000/30); </script>
You need to use something like this: context.clearRect(0, 0, (canvas.width * 0.25), height); Try this? <!DOCTYPE html> <html> <head> <title></title> <style type="text/css"> body { background-color: #222222; } canvas { background-color: #000000; width: 25%; height: 400px; } </style> </head> <body> <canvas id="mainCanvas"></canvas> <script type="text/javascript"> var canvas = document.getElementById("mainCanvas"); var context = canvas.getContext("2d"); var keys = []; var speed = 4; // var width = 25%; var height = 400; window.addEventListener("keydown", function(e) { keys[e.keyCode] = true; }, false); window.addEventListener("keyup", function(e) { delete keys[e.keyCode]; }, false); var player = { x: 10, y: 10, width: 30, height: 30 }; function game() { update(); render(); } function update() { if (keys[40]) player.y++ * speed; if (keys[38]) player.y-- * speed; if (keys[37]) player.x-- * speed; if (keys[39]) player.x++ * speed; } function render() { context.clearRect(0, 0, (canvas.width * 0.25), height); context.fillStyle = "white"; context.fillRect(player.x, player.y, player.width, player.height); } setInterval(function() { game(); }, 1000/30); </script> </body> </html>
Not sure what you actually wanted to ask yet your code has two syntax errors - thus it does not execute correctly: var keys = []; var speed = 4; //var width = 25%; //This is no valid assignment and the value is not used.. var height = 400; and function render() { //context.clearRect(0, 0, (canvas.width * 0.25)), height); //One bracket too much, can skip both tho.. context.clearRect(0, 0, canvas.width * 0.25, height);
You need to put your canvas in a container, and set up the container the way you want, then you make your canvas 100% of the containers properties using clientHeight and clientWidth JSFiddle: https://jsfiddle.net/53n2s0s9/
drawImage() not working consistently
When you put a picture named logo.png in the same directory as this html file and try to run it in a web browser the picture only appears 1 times out of 10 refreshes in IE and doesn't appear the first time in Firefox but does appear after further refreshes. What the heck is going on ? (drawImage() method is called in the showIntro() function) <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Example 1 - Title Screen</title> <script> window.onload = function () { var canvas = document.getElementById('myCanvas'); var c = canvas.getContext('2d'); var State = { _current: 0, INTRO: 0, LOADING: 1, LOADED: 2 } window.addEventListener('click', handleClick, false); window.addEventListener('resize', doResize, false); doResize(); function handleClick() { State._current = State.LOADING; fadeToWhite(); } function doResize() { canvas.width = document.body.clientWidth; canvas.height = document.body.clientHeight; switch (State._current) { case State.INTRO: showIntro(); break; } } function fadeToWhite(alphaVal) { // If the function hasn't received any parameters, start with 0.02 var alphaVal = (alphaVal == undefined) ? 0.02 : parseFloat(alphaVal) + 0.02; // Set the color to white c.fillStyle = '#FFFFFF'; // Set the Global Alpha c.globalAlpha = alphaVal; // Make a rectangle as big as the canvas c.fillRect(0, 0, canvas.width, canvas.height); if (alphaVal < 1.0) { setTimeout(function () { fadeToWhite(alphaVal); }, 30); } } function showIntro() { var phrase = "Click or tap the screen to start the game"; // Clear the canvas c.clearRect(0, 0, canvas.width, canvas.height); // Make a nice blue gradient var grd = c.createLinearGradient(0, canvas.height, canvas.width, 0); grd.addColorStop(0, '#ceefff'); grd.addColorStop(1, '#52bcff'); c.fillStyle = grd; c.fillRect(0, 0, canvas.width, canvas.height); var logoImg = new Image(); logoImg.src = './logo.png'; // Store the original width value so that we can keep // the same width/height ratio later var originalWidth = logoImg.width; // Compute the new width and height values logoImg.width = Math.round((50 * document.body.clientWidth) / 100); logoImg.height = Math.round((logoImg.width * logoImg.height) / originalWidth); // Create an small utility object var logo = { img: logoImg, x: (canvas.width / 2) - (logoImg.width / 2), y: (canvas.height / 2) - (logoImg.height / 2) } // Present the image c.drawImage(logo.img, logo.x, logo.y, logo.img.width, logo.img.height); // Change the color to black c.fillStyle = '#000000'; c.font = 'bold 16px Arial, sans-serif'; var textSize = c.measureText(phrase); var xCoord = (canvas.width / 2) - (textSize.width / 2); c.fillText(phrase, xCoord, (logo.y + logo.img.height) + 50); } } </script> <style type="text/css" media="screen"> html { height: 100%; overflow: hidden } body { margin: 0px; padding: 0px; height: 100%; } </style> </head> <body> <canvas id="myCanvas" width="100" height="100"> Your browser doesn't include support for the canvas tag. </canvas> </body> </html>
The problem is that you aren't waiting for the image to load when you call drawImage(). You could use something like: logo.img.onload = function(){ c.drawImage(logo.img, logo.x, logo.y, logo.img.width, logo.img.height); }; Although make sure you don't start modifying the canvas until this has happened.