是否可以在画布上书写图像并用背景书写文字? 例如:
答案 0 :(得分:37)
不幸的是,不能用文本方法生成带背景的文本 - 只填写或勾勒文本本身。
这是因为字体(字体)中的字形会根据需要转换为单独的形状或路径,其中背景将是字形本身的内部部分(使用填充时看到的部分)。除了使用它的几何位置之外,没有用于黑盒子(字形适合的矩形)的图层,因此我们需要自己提供一种黑盒子和轴承。
在旧计算机系统上大多数字体所在的二进制字体,其中设置或清除像素。而不是仅仅清除背景可以选择提供背景。默认情况下,基于矢量的字体不是这种情况(浏览器可以直接访问字形几何体,因此可以通过这种方式提供背景)。
要创建背景,您需要先使用其他方法(如形状或图像)绘制背景。
示例:
ctx.fillRect(x, y, width, height);
或
ctx.drawImage(image, x, y [, width, height]);
然后在上面绘制文字:
ctx.fillText('My text', x, y);
您可以使用measureText
找出文本的宽度(将来也是高度:上升+下降)并将其作为基础:
var width = ctx.measureText('My text').width; /// width in pixels
您可以将所有这些包装在一个函数中。这里的函数是基本的,但您可以使用颜色和背景参数以及填充等扩展它。
/// expand with color, background etc.
function drawTextBG(ctx, txt, font, x, y) {
/// lets save current state as we make a lot of changes
ctx.save();
/// set font
ctx.font = font;
/// draw text from top - makes life easier at the moment
ctx.textBaseline = 'top';
/// color for background
ctx.fillStyle = '#f50';
/// get width of text
var width = ctx.measureText(txt).width;
/// draw background rect assuming height of font
ctx.fillRect(x, y, width, parseInt(font, 10));
/// text color
ctx.fillStyle = '#000';
/// draw text on top
ctx.fillText(txt, x, y);
/// restore original state
ctx.restore();
}
<强> ONLINE DEMO HERE 强>
请注意,这种“测量”高度的方式并不准确。您可以使用临时div / span元素测量字体的高度,并从为其设置字体和文本时获取计算出的样式。
答案 1 :(得分:3)
我更简单的解决方案是两次调用fillText。首先是一个Unicode + 2588█字符串,它是一个黑色矩形,其重复长度与使用背景色的文本相同。然后正常调用带有前景色的fillText。
答案 2 :(得分:0)
此功能为您提供带有背景的垂直和水平居中文本。它仅适用于等宽字体(相同宽度的字符)。该函数计算要打印的字符串中的字符数,然后将它们乘以0.62(假设字体的宽度略小于高度的0.62倍)。背景是字体大小的1.5倍。更改此设置以适合您的需求。
function centeredText(string, fontSize, color) {
var i = string.length;
i = i*fontSize*0.62;
if (i > canvas.width) {
i = canvas.width;
}
ctx.fillStyle = "RGBA(255, 255, 255, 0.8)";
ctx.fillRect(canvas.width / 2 - i / 2,canvas.height / 2 - (fontSize * 1.5) / 2, i, (fontSize * 1.5) );
ctx.font = fontSize.toString() + "px monospace";
ctx.fillStyle = color;
ctx.textBaseline = "middle";
ctx.textAlign = "center";
ctx.fillText(string, canvas.width / 2, canvas.height / 2);
}
因此,调用该函数将类似于以下内容。
centeredText("Hello World", 30, "red");