# Struggling to define js sprite sheet

I've been working on this for a couple days, unable to get anything to load. Here is the whole page. Please help me find what I'm doing wrong. Right now, I'm only trying to render the first card in the upper left corner of the main canvas context.

<html>
<style>
canvas#game-canvas {
position: absolute;
top: 5%;
left: 5%;
background: lightblue;
height: 281px;
width: 500px;
}
body {
background: darkblue;
}
</style>
<script type="text/javascript" src="jquery1_10_2_min.js"></script>
<script>
var canvas = document.getElementById("game-canvas");
var context = canvas.getContext("2d");

function cardsheet(path, frameWidth, frameHeight) {

this.image = new Image();
this.frameHeight = frameHeight;
this.frameWidth = frameWidth;
this.image.src = path;

var card_sprites = [];
var card_names = [
'1d', '2d', '3d', '4d', '5d', '6d', '7d', '8d', '9d', '10d', 'Jd', 'Qd', 'Kd',
'1h', '2h', '3h', '4h', '5h', '6h', '7h', '8h', '9h', '10h', 'Jh', 'Qh', 'Kh',
'1s', '2s', '3s', '4s', '5s', '6s', '7s', '8s', '9s', '10s', 'Js', 'Qs', 'Ks',
'1c', '2c', '3c', '4c', '5c', '6c', '7c', '8c', '9c', '10c', 'Jc', 'Qc', 'Kc'];

framesPerRow = Math.floor(this.image.width / frameWidth);
framesPerCol = Math.floor(this.image.height / frameHeight);
k = 0;

for (i = 0; i < framesPerRow; i++) {
card_sprites[card_names[k] + '_canvas'] = document.createElement('canvas');
card_sprites[card_names[k] + '_canvas'].width = frameWidth;
card_sprites[card_names[k] + '_canvas'].height = frameHeight;
card_sprites[card_names[k] + '_context'] = card_sprites[card_names[k] + '_canvas'].getContext('2d');
card_sprites[card_names[k] + '_context'].drawImage(this.image, frameWidth * i, frameHeight, frameWidth, frameHeight, 0, 0, frameWidth, frameHeight);
k++;
}
};
return card_sprites;
}

var cards = cardsheet('small_playing_cards.png', 54, 65);
context.drawImage(cards['1d_canvas'], 10, 10);
</script>

<body>
<canvas id="game-canvas"></canvas>
</body>
</html>


UPDATE (Still not working...)

<script type="text/javascript" src="jquery1_10_2_min.js"></script>
<script>
var canvas = document.getElementById("game-canvas");
var context = canvas.getContext("2d");

var cards = cardsheet('small_playing_cards.png', 54, 65);
context.drawImage(card_sprites_context[0], 10, 10);
});

function cardsheet(path, frameWidth, frameHeight) {

this.image = new Image();
this.frameHeight = frameHeight;
this.frameWidth = frameWidth;
this.image.src = path;

var card_sprites_canvas = [];
var card_sprites_context = [];
var card_names = [
'1d', '2d', '3d', '4d', '5d', '6d', '7d', '8d', '9d', '10d', 'Jd', 'Qd', 'Kd',
'1h', '2h', '3h', '4h', '5h', '6h', '7h', '8h', '9h', '10h', 'Jh', 'Qh', 'Kh',
'1s', '2s', '3s', '4s', '5s', '6s', '7s', '8s', '9s', '10s', 'Js', 'Qs', 'Ks',
'1c', '2c', '3c', '4c', '5c', '6c', '7c', '8c', '9c', '10c', 'Jc', 'Qc', 'Kc'];

framesPerRow = Math.floor(this.image.width / frameWidth);
framesPerCol = Math.floor(this.image.height / frameHeight);
k = 0;

for (i = 0; i < framesPerRow; i++) {
card_sprites_canvas[k] = document.createElement('canvas');
card_sprites_canvas[k].width = frameWidth;
card_sprites_canvas[k].height = frameHeight;
card_sprites_context[k] = card_sprites_canvas[k].getContext('2d');
card_sprites_context[k].drawImage(this.image, frameWidth * i, frameHeight, frameWidth, frameHeight, 0, 0, frameWidth, frameHeight);
k++;
}

return card_sprites_context;
}

</script>

• You are creating multiple new images (in your case, canvas elements), for each frame of the sprite sheet. This is not exactly in line with the idea of a sprite sheet, which is generally defined as a single image from which smaller regions can be drawn, which removes the need to swap images. A 2dcanvas offers this functionality natively: developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/… Feb 23, 2016 at 15:02

I can see a few issues with this code. The first is that you get the canvas variable before it actually exists. To fix this, put all of the code outside of the cardsheet function into a different function, and make that function load on window.onload = function() {outsideFunction()};.

The second issue is to do with the card_sprites array, as the function effectively returns nothing. This is because of the way you access the array. In order to access the first element of an array, you need to use exampleArray[0], and increase 0 for each element in the array. You can see how it's nonsensical, then, to try and access card_sprites["1d_canvas"]

To give you an idea of how to actually use arrays, see the below code snippet:

for (i = 0; i < framesPerRow; i++) {
card_sprites_canvas[i] = document.createElement('canvas');
card_sprites_canvas[i].width = frameWidth;
card_sprites_canvas[i].height = frameHeight;
}

• I've gone over it again, and still nothing. Please review my updated code? Thank you. Feb 16, 2016 at 12:33
• Do you not see anything obvious that's wrong with your current code? Take a moment and look over it. Feb 16, 2016 at 14:18

You are referencing card_sprites_context in your document.ready-function, even though it's not defined at that scope. You should switch that line to context.drawImage(cards[0], 10, 10);.

• While these are both correct answers that solve my problem, I gave the solution credit to the underdog, with only 36 points at the time of this writing, to your 705. Thank you for clearing this up. I'm just about ready to rock now :-) Feb 16, 2016 at 20:56
• Feel free to hand out some upvotes for both of us then. :)
– user35344
Feb 17, 2016 at 5:37