Click this link to our Dog Race project for this post. This version has been updated to adapt to your browser.
Re-size your browser window and refresh the page. You should see the size of the canvas change. The finish line moves and the dogs still end at the right hand edge.
The good news is that there are several values that the browser will reveal to us. We can use JavaScript to gather information about the current size of the window. Look at the following code:
alert(window.innerWidth + " x " + window.innerHeight);
You can find all the details here at: W3Schools.
I know it is a bit annoying, but I have left the alert in the code so that you can try different window sizes and see the values on your own screen.
I have put the height of the window in there for you to see, but this page doesn't use it anywhere. Instead we will make horizontal adjustments only. We are not checking for changes to the size while the app is running, only when it is refreshed.
To make all this work, we set up a few global variables:
var currentWidth = window.innerWidth;We have been using canvasLeft all along, but now we are going to set it to 5% of the window size. We are adding canvasWidth which will be 88% of the window size. That number came about from experimenting with different values.
var canvasLeft = currentWidth * 0.05;
var canvasWidth = currentWidth * 0.88;
It only requires a few changes to the original script to place things in the right spot no matter what the size of the window. First we will set the size of our game board:
function clearCanvas(thisColor){
ctx.fillStyle = thisColor;
ctx.rect(canvasLeft,0,canvasWidth,400);
ctx.fill();
}
We also need to make sure the finish line moves:
//draw the finish line
ctx.strokeStyle = 'black'
ctx.beginPath();
ctx.lineWidth = 1;
ctx.moveTo(canvasLeft + canvasWidth - 30,15);
ctx.lineTo(canvasLeft + canvasWidth - 30,380);
ctx.closePath();
ctx.stroke();
We will use the same variable to adjust the spot on the canvas that where we want the dogs to stop:
var leaderNose = canvasLeft + canvasWidth - 90;When it came time to print the finishing order next to each dog at the end of the race, I decided to switch the alignment from left to right so that I didn't have to worry about the width of the character:
ctx.textAlign="right";
ctx.fillText(place,canvasLeft+canvasWidth,dog*60 + 60);
Sometimes the fanciest effects are the easiest to code. If you want to copy and paste the entire script into your own editor, here it is below. Don't forget to give Drop Your Anchor a try. C U Next Time!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="generator" content="CoffeeCup HTML Editor (www.coffeecup.com)">
<meta name="description" content="">
<meta name="keywords" content="">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="viewport" content="width=device-width; initial-scale=1.0; user-scalable=1;">
<title>Dog Race</title>
<style>body{color:#FFFFFF}</style>
<script type="text/javascript">
/* Demo Script for 'Writing Games with Canvas in HTML5'
© Copyright 2013, Budd Churchward
*/
var myRed = "#FE0000"; //red - first value is 254
var myBlue = "#0200DD"; //blue - first value is 2
var myYellow = "#FCFF00"; //yellow - first value is 252
var myMagenta = "#660066"; //magenta - first value is 253
var myOrange = "#FF6600"; //orange is - first value is 255
var myGreen = "#06FF00"; //green is - first value is 6
var myBrown = "#993300"; //brown is - first value is 153
var myBackground = "#007777"; //background -- first value is 0
var currentWidth = window.innerWidth;
var canvasLeft = currentWidth * 0.05;
var canvasWidth = currentWidth * 0.88;
function canvasDogRaces(){
// Get the canvas element.
canvas = document.getElementById("myCanvas");
// Make sure you got it.
if (canvas.getContext){
ctx = canvas.getContext("2d");
alert(window.innerWidth + " x " + window.innerHeight);
clearCanvas(myBackground);
drawDog(myGreen, canvasLeft + 20, 10);
drawDog(myYellow, canvasLeft + 20, 70);
drawDog(myBrown, canvasLeft + 20, 130);
drawDog(myRed, canvasLeft + 20, 190);
drawDog(myBlue, canvasLeft + 20, 250);
drawDog(myMagenta, canvasLeft + 20, 310);
//draw the finish line
ctx.strokeStyle = 'black'
ctx.beginPath();
ctx.lineWidth = 1;
ctx.moveTo(canvasLeft + canvasWidth - 30,15);
ctx.lineTo(canvasLeft + canvasWidth - 30,380);
ctx.closePath();
ctx.stroke();
// set start point for each dog and image array
for (var x = 0; x < 6; x++){
hisSpot[x] = canvasLeft + 2;
dogImage[x] = 0;
}
dogCatcher();
delayLoop=self.setInterval(function(){scooter(15)},20);
}else{
alert("Your browser does not\n support 'Canvas'");
}
}
var delayLoop = 0;
var runningDogX = canvasLeft;
var testSpot = 0;
var hisSpot = new Array();
var dogImage = new Array();
var thisDog = new Array();
thisDog[0] = "Arlo";
thisDog[1] = "O'Yeller";
thisDog[2] = "Brownie";
thisDog[3] = "Red Rover";
thisDog[4] = "Bo";
thisDog[5] = "Max";
var placeText = new Array();
placeText[0] = "1st Place: ";
placeText[1] = "2nd Place: ";
placeText[2] = "3rd Place: ";
function showWinner(dog){
ctx.fillStyle='White';
ctx.font="24px Arial";
ctx.textAlign="left";
ctx.fillText(placeText[place] + thisDog[dog],canvasLeft + 20,40*place+30);
}
function goAgain(){
location.reload();
}
function dogCatcher(){
for(var dog = 0; dog < 6; dog++){
dogImage[dog] = ctx.getImageData(hisSpot[dog], dog * 60 + 15,70 ,55);
//ctx.putImageData(dogImage[dog],0,dog * 60);
}
}
var leaderNose = canvasLeft + canvasWidth - 90;
var place = 0;
function scooter(){
var step = 1;
var keepGoing = 0;
for(var dog = 0; dog < 6; dog++){
if(hisSpot[dog]>0){
step = Math.floor(Math.random() * 8)+1;
hisSpot[dog] = hisSpot[dog] + step;
ctx.putImageData(dogImage[dog],hisSpot[dog],dog * 60 + 15);
keepGoing++;
if(hisSpot[dog]>leaderNose){
hisSpot[dog]=0;
if(place<3){showWinner(dog); }
place++;
ctx.textAlign="right";
ctx.fillText(place,canvasLeft+canvasWidth,dog*60 + 60);
}
}
}
if(keepGoing==0){clearInterval(delayLoop); }
}
function myDogSpot(x,y){
ctx.putImageData(dogImage,x, y);
}
function drawDog(thisColor,dogX,dogY){
// draw tail
ctx.beginPath();
ctx.lineWidth = 3;
ctx.strokeStyle = 'black';
ctx.moveTo(dogX + 5,dogY+32);
ctx.lineTo(dogX-10,dogY + 25);
ctx.closePath();
ctx.stroke();
// draw body
ctx.fillStyle = thisColor;
ctx.beginPath();
ctx.rect(dogX+8,dogY + 30,24,16);
ctx.rect (dogX,dogY + 35, 10, 25);
ctx.rect (dogX + 30,dogY + 35, 10, 25);
ctx.fill();
ctx.arc(dogX + 8, dogY + 38, 8, 0, 2*Math.PI, true);
ctx.arc(dogX + 32, dogY + 38, 8, 0, 2*Math.PI, true);
ctx.closePath();
ctx.fill();
// draw head
ctx.beginPath();
ctx.arc(dogX + 36, dogY + 22, 8, 0, 2*Math.PI, true);
ctx.closePath();
ctx.fill();
ctx.beginPath();
ctx.arc(dogX + 40, dogY + 22, 8, 0, Math.PI, false);
ctx.closePath();
ctx.fill();
// draw nose
ctx.fillStyle = 'black';
ctx.beginPath();
ctx.rect(dogX +46,dogY +22,3,3);
ctx.closePath();
ctx.fill();
// draw eye
ctx.beginPath();
ctx.rect(dogX +40,dogY +20,3,3);
ctx.closePath();
ctx.fill();
// draw ear
ctx.beginPath();
ctx.arc(dogX + 30, dogY + 18, 4, Math.PI, 0.2 *Math.PI, false);
ctx.closePath();
ctx.fill();
}
function clearCanvas(thisColor){
ctx.fillStyle = thisColor;
ctx.rect(canvasLeft,0,canvasWidth,400);
ctx.fill();
}
</script>
</head>
<body onload="canvasDogRaces()" bgcolor="#339999">
<h3>
<div id="rowOne_text">Welcome to the Races</div>
<div id="rowTwo_text">Pick Your Dog</div>
</h3>
<canvas id="myCanvas" width="1440" height="400" ;">
</canvas>
</body>
</html>