2

I am drawing a canvas that needs to be on full available screen (100% width and height). I set the width and height of canvas using javascript like this

  var w = window.innerWidth;
  var h = window.innerHeight;
  var canvas = document.getElementById("myCanvas");
  canvas.width  = w;
  canvas.height = h;

After setting the canvas, I need to draw some text in it which needs to get the maximum available font size. Please help me finding the way how can I display text with maximum font size. The text may contain a single character (both upper and small case) or a string and can also contain numbers. I need to do it with javascript not jquery.

Thank you for your help.

Tayyab Shabab
  • 259
  • 1
  • 6
  • 16

2 Answers2

8

Challenge

As canvas' measureText doesn't currently support measuring height (ascent + descent) we need to do a little DOM trick to get the line-height.

As the actual height of a font - or typeface - does not necessarily (rarely) correspond with the font-size, we need a more accurate way of measuring it.

Solution

Fiddle demo

The result will be a vertical aligned text which always fit the canvas in width.

snap

This solution will automatically get the optimal size for the font.

The first function is to wrap the measureText to support height. If the new implementation of the text metrics isn't available then use DOM:

function textMetrics(ctx, txt) {

    var tm = ctx.measureText(txt),
        w = tm.width,
        h, el;  // height, div element
    
    if (typeof tm.fontBoundingBoxAscent === "undefined") {
    
        // create a div element and get height from that
        el = document.createElement('div');
        el.style.cssText = "position:fixed;font:" + ctx.font +
                           ";padding:0;margin:0;left:-9999px;top:-9999px";
        el.innerHTML = txt;

        document.body.appendChild(el); 
        h = parseInt(getComputedStyle(el).getPropertyValue('height'), 10);
        document.body.removeChild(el);

    } 
    else {
        // in the future ...
        h = tm.fontBoundingBoxAscent + tm.fontBoundingBoxDescent;
    }

    return [w, h];
}

Now we can loop to find the optimal size (here not very optimized, but works for the purpose - and I wrote this just now so there might be bugs in there, one being if text is just a single char that doesn't exceed width before height).

This function takes minimum two arguments, context and the text, the others are optional such as font name (name only), tolerance [0.0, 1.0] (default 0.02 or 2%) and style (ie. bold, italic etc.):

function getOptimalSize(ctx, txt, fontName, tolerance, tolerance, style) {

    tolerance = (tolerance === undefined) ? 0.02 : tolerance;
    fontName = (fontName === undefined) ? 'sans-serif' : fontName;
    style = (style === undefined) ? '' : style + ' ';
    
    var w = ctx.canvas.width,
        h = ctx.canvas.height,
        current = h,
        i = 0,
        max = 100,
        tm,
        wl = w - w * tolerance * 0.5,
        wu = w + w * tolerance * 0.5,
        hl = h - h * tolerance * 0.5,
        hu = h + h * tolerance * 0.5;
    
    for(; i < max; i++) {

        ctx.font = style + current + 'px ' + fontName;
        tm = textMetrics(ctx, txt);
        
        if ((tm[0] >= wl && tm[0] <= wu)) {
            return tm;
        }
        
        if (tm[1] > current) {
            current *= (1 - tolerance);
        } else {
            current *= (1 + tolerance);
        }            
    }
    return [-1, -1];
}
Community
  • 1
  • 1
-1

Try this.

FIDDLE DEMO

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var x = canvas.width / 2;
var y = canvas.height / 2 - 10;
var text = 'I M @ CENTER!';
context.font = '10pt Calibri'; //try changing values 10,15,20
context.textAlign = 'center';
context.fillStyle = 'red';
context.fillText(text, x, y);

You can provide your conditions depending on the window size.Create a simple function like following:

function Manipulate_FONT(window.widht, window.height) {
    if (window.widht == something && window.height == something) {
        font_size = xyz //put this in ---> context.font = '10pt Calibri'
    }
}
mishik
  • 9,973
  • 9
  • 45
  • 67
HIRA THAKUR
  • 17,189
  • 14
  • 56
  • 87
  • Where is the answer to question "how to get the maximum available font size"? This is just showing how to draw text aligned centered but only with static values. – Sebastian Mar 12 '15 at 10:24