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

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

问题描述

我在图片上方的HTML5画布中绘制文字(模型生成器)。我想计算一个字体大小,以便字符串将跨越画布的整个宽度。



因此,基本上,在JavaScript中有一种方法来确定在给定宽度的某个字体的某些字符串应该使用什么字体大小?

解决方案

fillText() 方法具有可选的第四个参数,即最大宽度 >

MDN的文档说...


maxWidth p>

可选;要绘制的最大宽度。如果指定了字符串,并且字符串
被计算得比这个宽度宽,则字体被调整为使用
更多的水平缩合字体(如果有一个字体可用或者如果一个
合理可读


但是,在写入时,这个参数不支持跨浏览器,这导致第二个解决方案使用 measureText() 确定字符串的尺寸,而不渲染它。

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

以下是我的操作方法...

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

//字体大小必须按降序排列。你可能需要使用`sort()`
//如果你不能保证这一点。用户输入。
var fontSizes = [72,36,28,14,12,10,5,2],
text ='Measure me!

//默认样式。
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



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



如果会,我使文本中心对齐。如果你必须在文本的左边和右边有填充(这将看起来更好),在计算是否文本将适合添加填充值到 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);

jsFiddle


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.

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?

解决方案

The fillText() method has an optional fourth argument, which is the max width to render the string.

MDN's documentation says...

maxWidth

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.

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;

Here is how I may do it...

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.

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.

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

The binary chop should be O(log n).

Here is the guts of the function.

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天全站免登陆