Next page | Contents page |

Slice and draw cards

To cut each card out of the big image we need to draw the image into a canvas and then use a method of the canvas context called getImageData(). That method returns an object of type ImageData and to convert that to an Image we would need to use toDataURL() and wait for the result, like we did in the converter for the big image.

There are 2 methods of the canvas context for drawing images:

So I decided that the most efficient process would be (in pseudocode):


	wd = width for finally drawing a card 
	ht = height ..  ..  ..
	make an off-screen canvas (14 * wd) x (4 * ht)
	draw the big image, scaling to fit that new canvas
	cut out each card as ImageData, at the final required size

Then when it comes to drawing each card on the real displayed canvas we can use putImageData(). So in gameB.js sliceImage(), mentioned on the previous page after setting required card width and height, should be like this:


function sliceImage ()
{ const CNV = document.createElement ("canvas"); // Off screen
  const WD = Card.prototype.width, HT = Card.prototype.height;
  CNV.width = WD * 14;
  CNV.height = HT * 4;
  const G2 = CNV.getContext ("2d");
  // Scale IMSHEET into CNV to get required card size:
  G2.drawImage (GAME.IMSHEET, 0, 0, CNV.width, CNV.height);
  // Get ImageData objects for all cards:
  GAME.JOKER1 = G2.getImageData (13 * WD, 0, WD, HT);
  GAME.JOKER2 = G2.getImageData (13 * WD, HT, WD, HT);
  GAME.BACK = G2.getImageData (13 * WD, 2 * HT, WD, HT);
  GAME.CLUBS = [];
  GAME.DIAMONDS = [];
  GAME.HEARTS = [];
  GAME.SPADES = [];
  for (var i = 0; i < 13; i++)
  { GAME.CLUBS.push (G2.getImageData (i * WD, 0, WD, HT));
    GAME.DIAMONDS.push (G2.getImageData (i * WD, HT, WD, HT));
    GAME.HEARTS.push (G2.getImageData (i * WD, 2 * HT, WD, HT));
    GAME.SPADES.push (G2.getImageData (i * WD, 3 * HT, WD, HT));
} }

Drawing the cards now becomes simpler than it was before. We need the following 2 methods in cardB.js.


Card.prototype.getImageData = function ()
{ switch (this.suit)
  { case SUITS.CLUB: return GAME.CLUBS [this.value - 1];
    case SUITS.DIAMOND: return GAME.DIAMONDS [this.value - 1];
    case SUITS.HEART: return GAME.HEARTS [this.value - 1];
    case SUITS.SPADE: return GAME.SPADES [this.value - 1]; 
  }
  return null;// Should not happen
};

Card.prototype.draw = function (xLeft, yTop)
{ if (this.faceUp)
    GAME.g2.putImageData (this.getImageData (), xLeft, yTop);
  else GAME.g2.putImageData (GAME.BACK, xLeft, yTop);
};
Next page | Contents page |