Tuesday, 6 November 2012

HTML5 Growing A Canvas To Fill The Window

A little while back I played a HTML5 game that included a button just below it to grow the canvas used for the game to fill the window the game is being played in. It is a pretty nice feature. I thought this is probably pretty easy to in something similar using JQuery.

Turns out it is, although I have not clone the features exactly.

First up we need a little html document.
<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="jquery-1.8.2.min.js"></script>
    <script type="text/javascript" src="main.js"></script>
    <link rel="stylesheet" href="style.css" type="text/css" media="screen" />
  </head>
<body>
  <div class='center-me'>
    <canvas id='my-canvas'></canvas>
  </div>
  <div id='toolbar' class="center-me">
    <button id='click-me'>Grow</button>    
  </div>

</body>
</html>

As you can see it is pretty basic. The layout is a centred canvas with a toolbar containing one button below it. When you click the button the canvas will grow to fill the window but still leave the toolbar visible. Click the button again and the canvas will shrink to its original size. In terms of css here is what we have in our style.css file.
body {
    width:100%;
    overflow:hidden;
    margin:0;
}

.center-me{    
    text-align:center;
}

#my-canvas{
    width:300px;
    height:300px;
    border-width:1px;
    border-style:solid;
}

#click-me {
    margin-bottom:10px;
}
Apart from the centreing bits we have added a little bit of a margin to the button otherwise it seemed to get a little bit cut off when we expand. I am not sure why this is so if anyone has any ideas?

We also turn off scrollbar as the dynamic appearance (when needed) in both chrome and FireFox complicates things some what. An alternative is to always have them visible using overflow-y: scroll; in the css for the html element. That way you could push the tool bar off the screen to gain some vertical space in return for loosing some horizontal space. Depending on your trade-offs one me be preferable to the other.

Finally we are onto the javascript. Here is my main.js file
var start_up = function(){
  var ctx = $('#my-canvas')[0].getContext('2d');

  // draw some random stuff.
  ctx.fillRect(50,50,50,50);
  ctx.fillStyle='#cc3333';
  ctx.fillRect(50,10,80,30);

  var fullWindow = false;

  $('#click-me').on('click', function(){
    var width;
    var height;

    if(fullWindow){
      height= 300;
      width = 300;
    }else{
      width = $(window).width();
      height= $(window).height()-$('#toolbar').outerHeight(true);
    }
    fullWindow = !fullWindow; // toggle the flag.

    $('#my-canvas').animate({
      width:width,
      height:height
    }, 2000);

    $('#click-me').text( fullWindow ? 'Shrink' : 'Grow');
  });
};

$(start_up);
So I dip into my canvas element and draw a few rects. After that we hook up the on click callback for the grow/shrink button such that we animate the size of the canvas. Note the use of outerHeight along with the true flag to get the full height including the margin.

An important thing to note is we are changing the width and height that the canvas is drawn at not the internal dimensions. If you try out my example code you will see the image stretched. This may or may not be what you wanted.

If you are happy to stretch you image it is probable you will want to keep the aspect ratio rather than growing to fill as much space as possible. However if you are taking the approach of want to draw as much of a map as possible then you will probably want to set the width and height of the canvas object once the animation stops.

Perhaps sounds a bit odd if you have not encountered this before but it does make quite a bit of sense when thought on for a while.

Anyway that just about wraps it up.

No comments:

Post a Comment