确定 HTML5 画布中字符串的宽度 [英] Determine width of string in HTML5 canvas

查看:24
本文介绍了确定 HTML5 画布中字符串的宽度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm drawing text in an HTML5 canvas on top of an image (a meme generator). I want to calculate a font size so that the string will span the entire width of the canvas.

所以基本上,JavaScript 中有没有一种方法可以确定对于给定宽度的某种字体的某些字符串应该使用什么字体大小?

So basically, is there a way in JavaScript to determine what font size I should use for some string of a certain font for a given width?

推荐答案

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

MDN 的文档说...

MDN's documentation says...

最大宽度

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

Optional; the maximum width to draw. If specified, and the string is computed to be wider than this width, the font is adjusted to use a more horizontally condensed font (if one is available or if a reasonably readable one can be synthesized by scaling the current font horizontally) or a smaller font.

然而,在撰写本文时,此参数在跨浏览器中并未得到很好的支持,这导致使用 measureText() 确定一个字符串的维度而不渲染它.

However, at the time of writing, this argument isn't supported well cross browser, which leads to the second solution using measureText() to determine the dimensions of a string without rendering it.

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

我可以这样做...

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);​

jsFiddle.

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

I have a list of font sizes in descending order and I iterate through the list, determining if the rendered text will fit within the canvas dimensions.

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

If it will, I render the text center aligned. If you must have padding on the left and right of the text (which will look nicer), add the padding value to the textDimensions.width when calculating if the text will fit.

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

If you have a long list of font sizes to try, you'd be better off using a binary search algorithm. This will increase the complexity of your code, however.

例如,如果您有 200 种字体大小,则数组元素的线性 O(n) 迭代可能会非常慢.

For example, if you have 200 font sizes, the linear O(n) iteration through the array elements could be quite slow.

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

The binary chop should be 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);

jsFiddle.

这篇关于确定 HTML5 画布中字符串的宽度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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