Skip to content Skip to sidebar Skip to footer

Html5 Canvas Font Size Based On Canvas Size

I have the canvas size set to 1/3 the window.innerHeight and window.innerWidth of the browser. Most of the elements on the canvas are also set based on the width and height of the

Solution 1:

Simply scale the font-size with a factor.

The basis

Lets say your canvas default size is 1000 pixels and the font size is 80 pixels (canvas converts pt to pixels - I use 80 here for simplicity, see bottom).

Snap

That will create a relationship of:

ratio = 80 / 1000 = 0.08

Lets verify when canvas width is 1000 by multiply with that ratio:

fontSize = 1000 * ratio = 80;

And we see we have 80 for the font as expected.

Now that the canvas size is smaller, lets say 500 pixels:

fontSize = 500 * ratio = 40;

That should correspond about to the relationship. Note that fonts do not behave linearly like that but it will be approximately correct.

Now simply set the size of the font:

ctx.font = (fontSize|0) + 'px myFont';

Solution

The final code from this is in essence very simple:

var fontBase = 1000,                   // selected default width for canvas
    fontSize = 70;                     // default size for fontfunction getFont() {
    var ratio = fontSize / fontBase;   // calc ratiovar size = canvas.width * ratio;   // get font size based on current widthreturn (size|0) + 'px sans-serif'; // set font
}

Every time you need to update the font (ie. resize) just call:

ctx.font = getFont();                  // call getFont to set new font size

The default values are snapshot of whatever size works in the moment/during development.

Live demo

To convert point to pixel size you simply use system DPI / 72:

80 pt * (96 / 72) = 107 pixels @ 96 DPI.

Solution 2:

Many responsive designs use media breakpoints to control font sizes.

The font size remains fixed through a range of media sizes.

In your resize event handler, apply a font size to a range of canvas sizes:

if(canvas.width<480){
    context.font='14px verdana';
}elseif(canvas.width<768){
    context.font='30px verdana';
}else{
    context.font='80px verdana';
}

[ And more efficiently... ]

Predefine some font sizes for each media format:

var fontSizes={
    phone:{
        XSmall:6,
        Small:8,
        Medium:10,
        Large:12,
        XLarge:14
    },
    tablet:{
        XSmall:10,
        Small:12,
        Medium:16,
        Large:24,
        XLarge:30
    },
    desktop:{
        XSmall:14,
        Small:18,
        Medium:30,
        Large:40,
        XLarge:80
    },
}

You can use these predefined font sizes for your canvas text:

context.font=fontSizes[media].XSmall+" verdana";
context.fillText("XSmall text",20,20);

context.font=fontSizes[media].Large+" verdana";
context.fillText("Large text",20,20);

Then in your resize handler, you just have to set the appropriate media type.

This way you don't need to recode context.font everywhere in your project.

var media="desktop";

if(canvas.width<480){
    media="phone";
}elseif(canvas.width<768){
    media="tablet";
}else{
    media="desktop";
}

Solution 3:

You should think your coordinates as virtual coordinates : if the canvas takes 1/3 of the screen, ask your self : how much room (relative) should the font take, not its size.

Decide once and for all of a virtual resolution of your canvas, then draw draw everything in that resolution... provided you scaled the canvas before.

For instance you could decide your canvas has a 600 x 200 virtual resolution. When you know the real window size, you'll have the real canvas size. Then scale the canvas with scale(realWidth/600, realHeight/200), and all will look the same on all devices.

I just made a small fiddle to illustrate, you will see that it generates the 'same' image for very differently sized canvas : http://jsbin.com/tisoguve/1/edit?js,output

enter image description here

Solution 4:

I do not like using a determined width or height for any application. Instead, I use the window object to determine the amount of space on the screen instead of saying "width=1000" it would look more like the code below. I take note of the current screen resolution I am using so that when adjusting content size on the screen everything scales as it should based on the size when it was created. Assuming that the original screen resolution is 1366 and we want the original font set at 20 .....

<canvas id="canvas"" width="0" height="0" style="position:relative;" ></canvas>
var canvas = document.getElementById("canvas");
var context= canvas.getContext('2d');
var canvas.width = document.body.clientWidth;
var canvas.height = document.body.clientHeight;
var px= 20-(((1366-canvas.width)/1366)*20); 
var fontStyle = "italic";
var fontWeight = "bold";
var fontSize = +px+"px";
var fontFamily = "Verdana";
var b = "";
context.font = fontStyle + b + fontWeight + b + fontSize + b + fontFamily;

I have tried this using Safari, IE, Chrome, Firefox, with responsive design view, and it works. Trying to save, scale, and restore in my application created a foreground image with lower resolution on top of the old canvas. Trying to run through a range of media sizes the way it is shown above seems large I would think. I think I may be tempted to use the following accompanied with a good style sheet for the page layout.

var px= 20-(((1366-canvas.width/3)/1366)*20);
context.font = +px+"px";
//place text here for this font
px= 12-(((1366-canvas.width/3)/1366)*12); 
context.font = +px+"px";
//place text here for this font

For other objects I would try to use the same approach but, limit images drawn to canvas with javascript, use as much css with % as you can and redraw images if necessary to prevent the user from scaling the page.

context.fillText  ("Click To Start", canvas.width/3, canvas.height/1.7);
context.strokeText  ("Click To Start", canvas.width/3, canvas.height/1.7);  

Post a Comment for "Html5 Canvas Font Size Based On Canvas Size"