使用Javascript在画布中获得最大字体大小 [英] Use Javascript to get Maximum font size in canvas

查看:533
本文介绍了使用Javascript在画布中获得最大字体大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在绘制一个需要在完整可用屏幕(100%宽度和高度)上的画布。我使用javascript这样设置画布的宽度和高度

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;

设置画布后,我需要在其中绘制一些文本,尺寸。请帮助我找到如何显示最大字体大小的文本的方式。文本可以包含单个字符(大写和小写)或字符串,并且还可以包含数字。我需要使用javascript而不是jquery。

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.

感谢您的帮助。

推荐答案

挑战



由于画布 measureText 目前不支持测量高度)我们需要做一个小的DOM技巧来获得行高。

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.

小提琴演示

Fiddle demo

结果将是垂直对齐的文本,总是适合画布的宽度。

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

此解决方案将自动获得字体的最佳大小。

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

第一个函数是将 measureText 包起来以支持height。如果文本指标的新实现不可用,请使用DOM:

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).

此函数至少有两个参数,上下文和文本,其他是可选的,如字体名称(仅名称),公差[0.0,1.0](默认0.02或2%)和样式(即粗体,斜体等。):

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];
}

这篇关于使用Javascript在画布中获得最大字体大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆