Use Javascript to get Maximum font size in canvas

后端 未结 2 1844
滥情空心
滥情空心 2020-11-27 22:53

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

  va         


        
相关标签:
2条回答
  • 2020-11-27 23:22

    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'
        }
    }
    
    0 讨论(0)
  • 2020-11-27 23:29

    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];
    }
    
    0 讨论(0)
提交回复
热议问题