HTML5 Canvas [53]
Example 4-7. Rotation transformation
var tileSheet = new Image();
tileSheet.addEventListener('load', eventShipLoaded , false);
tileSheet.src = "tanks_sheet.png";
var animationFrames = [1,2,3,4,5,6,7,8];
var frameIndex = 0;
var rotation = 90;
var x = 50;
var y = 50;
function eventShipLoaded() {
drawScreen();
}
function drawScreen() {
//draw a background so we can see the Canvas edges
context.fillStyle = "#aaaaaa";
context.fillRect(0,0,500,500);
context.save();
context.setTransform(1,0,0,1,0,0)
context.translate(x+16, y+16);
var angleInRadians = rotation * Math.PI / 180;
context.rotate(angleInRadians);
var sourceX = Math.floor(animationFrames[frameIndex] % 8) *32;
var sourceY = Math.floor(animationFrames[frameIndex] / 8) *32;
context.drawImage(tileSheet, sourceX, sourceY,32,32,-16,-16,32,32);
context.restore();
}
function eventShipLoaded() {
drawScreen();
}
Figure 4-8 shows the output for this example.
Figure 4-8. Applying a rotation transformation
Let’s take this one step further by applying the animation technique from Example 4-5 and looping through the eight tiles while facing the tank at the 90-degree angle.
Animating a Transformed Image
To apply a series of image tiles to the rotated context, we simply have to add back in the frame tick loop code and increment the frameIndex variable on each frame tick. Example 4-8 has added this into the code for Example 4-7.
Example 4-8. Animation and rotation
var tileSheet = new Image();
tileSheet.addEventListener('load', eventShipLoaded , false);
tileSheet.src = "tanks_sheet.png";
var animationFrames = [1,2,3,4,5,6,7,8];
var frameIndex = 0;
var rotation = 90;
var x = 50;
var y = 50;
function eventShipLoaded() {
startUp();
}
function drawScreen() {
//draw a background so we can see the Canvas edges
context.fillStyle = "#aaaaaa";
context.fillRect(0,0,500,500);
context.save();
context.setTransform(1,0,0,1,0,0)
var angleInRadians = rotation * Math.PI / 180;
context.translate(x+16, y+16)
context.rotate(angleInRadians);
var sourceX = Math.floor(animationFrames[frameIndex] % 8) *32;
var sourceY = Math.floor(animationFrames[frameIndex] / 8) *32;
context.drawImage(tileSheet, sourceX, sourceY,32,32,-16,-16,32,32);
context.restore();
frameIndex++;
if (frameIndex==animationFrames.length) {
frameIndex=0;
}
}
function startUp(){
setInterval(drawScreen, 100 );
}
When you test Example 4-8, you should see that the tank has rotated 90 degrees, and the tank tracks loop through their animation frames.
As we did in Example 4-6, let’s move the tank in the direction it is facing. This time, it will move to the right until it goes off the screen. Example 4-9 has added back in the dx and dy movement vectors; notice that dx is now 1, and dy is now 0.
Example 4-9. Rotation, animation, and movement
var tileSheet = new Image();
tileSheet.addEventListener('load', eventShipLoaded , false);
tileSheet.src = "tanks_sheet.png";
var animationFrames = [1,2,3,4,5,6,7,8];
var frameIndex = 0;
var rotation = 90;
var x = 50;
var y = 50;
var dx = 1;
var dy = 0;
function eventShipLoaded() {
startUp();
}
function drawScreen() {
x = x+dx;
y = y+dy;
//draw a background so we can see the Canvas edges
context.fillStyle = "#aaaaaa";
context.fillRect(0,0,500,500);
context.save();
context.setTransform(1,0,0,1,0,0)
var angleInRadians = rotation * Math.PI / 180;
context.translate(x+16, y+16)
context.rotate(angleInRadians);
var sourceX=Math.floor(animationFrames[frameIndex] % 8) *32;
var sourceY=Math.floor(animationFrames[frameIndex] / 8) *32;
context.drawImage(tileSheet, sourceX, sourceY,32,32,−16,−16,32,32);
context.restore();
frameIndex++;
if (frameIndex ==animationFrames.length) {
frameIndex=0;
}
}
function startUp(){
setInterval(drawScreen, 100 );
}
When Example