确定HTML5画布中的字符串宽度

edc*_*591 12 javascript html5 fonts text canvas

我在图像顶部的HTML5画布上绘制文本(模因生成器).我想计算字体大小,以便字符串将跨越画布的整个宽度.

所以基本上,在JavaScript中是否有一种方法可以确定给定宽度的某些字体的某些字符串应使用的字体大小?

ale*_*lex 27

fillText()方法有一个可选的第四个参数,它是渲染字符串的最大宽度.

MDN的文档说......

maxWidth

可选的; 绘制的最大宽度.如果指定,并且字符串被计算为宽于此宽度,则调整字体以使用更加水平压缩的字体(如果有一个可用,或者如果可以通过水平缩放当前字体来合成可合理读取的字体)或更小字体.

但是,在编写本文时,跨浏览器不支持此参数,这导致第二种解决方案measureText()用于确定字符串的尺寸而不渲染它.

var width = ctx.measureText(text).width;
Run Code Online (Sandbox Code Playgroud)

这是我怎么做的...

var canvas = document.getElementById('canvas'),
    ctx = canvas.getContext('2d');

// Font sizes must be in descending order. You may need to use `sort()`
// if you can't guarantee this, e.g. user input.
var fontSizes = [72, 36, 28, 14, 12, 10, 5, 2],
    text = 'Measure me!';

// Default styles.
ctx.textBaseline = 'top';
ctx.fillStyle = 'blue';

var textDimensions,
    i = 0;

do {
   ctx.font = fontSizes[i++] + 'px Arial';
   textDimensions = ctx.measureText(text);        
} while (textDimensions.width >= canvas.width);

ctx.fillText(text, (canvas.width - textDimensions.width) / 2, 10);?
Run Code Online (Sandbox Code Playgroud)

jsFiddle.

我有一个按降序排列的字体大小列表,我遍历列表,确定渲染的文本是否适合画布尺寸.

如果愿意,我将文本中心对齐.如果您必须在文本的左侧和右侧填充(这看起来更好),请textDimensions.width在计算文本是否合适时添加填充值.

如果您要尝试使用很长的字体大小列表,那么最好使用二进制搜索算法.但是,这会增加代码的复杂性.

例如,如果您有200个字体大小,则通过数组元素的线性迭代将为O(n).

二进制斩波应为O(log n).

这里是的功能.

var textWidth = (function me(fontSizes, min, max) {

    var index = Math.floor((min + max) / 2);

    ctx.font = fontSizes[index] + 'px Arial';

    var textWidth = ctx.measureText(text).width;

    if (min > max) {
        return textWidth;
    }

    if (textWidth > canvas.width) {
        return me(fontSizes, min, index - 1);
    } else {
        return me(fontSizes, index + 1, max);
    }

})(fontSizes, 0, fontSizes.length - 1);
Run Code Online (Sandbox Code Playgroud)

jsFiddle.