1

I was wondering how to resize a canvas and all of its drawings as the screen size changes. I know it is 100% possible as this game does (resize your browser and it will fit to any ratio).

http://html5games.com/Game/Smarty-Bubbles/d8f24956-dc91-4902-9096-a46cb1353b6f

Do I have to draw all my shapes with % or multiply them all by a % each time they are drawn? I can appreciate having to redraw on a screen size change but how do I affect the canvas and its components?

forty2011111
  • 115
  • 7
  • http://stackoverflow.com/questions/1664785/resize-html5-canvas-to-fit-window – Kazekage Gaara Feb 21 '15 at 19:35
  • But what about the objects inside? If a draw a 10x10 square and then increase the window size by 100%, will my square be 20x20? What if I then need to draw another 10x10 square - I would want it to automatically upscale with the new browser size. It must know the window size before it draws itself, yes? – forty2011111 Feb 21 '15 at 19:37

1 Answers1

1
  1. At the start of the app, save the beginning window width and the beginning canvas size.

    var originalWindowWidth=window.innerWidth;
    var canvas=document.getElementById('canvas');
    var originalCanvasWidth=canvas.width;
    var originalCanvasHeight=canvas.height;
    
  2. Listen for the window resize event

  3. Calculate by how much the window width as changed

    scale=window.innerWidth/originalWindowWidth;
    

If your canvas content is complete & unchanging, you can rescale your canvas with CSS. This way you don't have to redraw the canvas content.

4a. (option#1) Scale using CSS:

// rescale both CSS width & height by the SAME SCALE FACTOR
$('#canvas').css('width',originalCanvasWidth*scale);
$('#canvas').css('width',originalCanvasWidth*scale);

If your canvas content is not complete & unchanging, you should rescale your canvas element itself. This causes all canvas content to be lost so you must redraw it. You can use the context.scale command to automatically redraw your content at the new scale factor. Using this method is also less likely to result in pixelated content versus resizing with CSS which "stretches" & "squeezes" existing pixels to fit the new CSS size.

4b. (Option#2) Scale the canvas element itself

    var canvas=document.getElementById("myCanvas");
    var ctx=canvas.getContext("2d");

    canvas.width=originalCanvasWidth*scale;
    canvas.height=originalCanvasHeight*scale;

    context.scale(scale,scale);

    // now reissue all the drawing commands
    // (no need to adjust coordinates or sizes -- context.scale does that for you!
markE
  • 102,905
  • 11
  • 164
  • 176
  • Now that I have this working, how can I draw a rectangle in the middle of the screen that always takes up the same size of the screen? Do I always need to multiply by a % or base everything off a defaults scale? – forty2011111 Feb 22 '15 at 04:20
  • You have several options: (1) Don't do context.scale which means fillrect(x,y,10,10) will draw a rect that's visually 10x10. (2) Do `context.scale` which causes all new drawings to enlarge/shrink by the supplied scaling factor(s) and fillrect(x,y,10,10) will result in a rect that's visually 20x20. If you want a 10x10 square then fillRect(x,y,10/scale,10/scale). The same two options apply to the x,y coordinates. Your original question was "I would want it to automatically upscale with the new browser size" so I added context.scale. If you don't need it you can leave it off and draw normally ;-) – markE Feb 22 '15 at 06:07
  • Thanks. What I did was make a function called myCoordX / myCoordY and they take an input value from 0 - 1 (basically a %) then I multiply it by the width or height of the window. It works perfect but is kinda annoying to have to put every value through it. – forty2011111 Feb 22 '15 at 17:19
  • If you find the repeated `*scale` annoying, you could fairly quickly wrap the context drawing commands to automatically adjust for scale: `function myFillRect( x, y, w, h ){ fillRect(x*scale, y*scale, width*scale, height*scale); }` – markE Feb 22 '15 at 17:26