29

是否可以在画布上写图像并用背景写文本?例如像这样:

http://awesomescreenshot.com/09f1qf2213

4

3 回答 3

57

文本在画布中的工作原理

不幸的是,您不能使用 text 方法生成带有背景的文本 - 只能填充或勾勒文本本身。

这是因为如果需要,字体(字体)中的字形会转换为单独的形状或路径,其中它的背景将是字形本身的内部部分(使用填充时看到的部分)。除了使用其几何位置之外,字形正在使用的黑盒(字形适合的矩形)没有层,因此我们需要自己提供一种黑盒和轴承。

在旧计算机系统上,大多数字体在二进制字体中设置或清除像素。除了清除背景之外,还可以选择提供背景。默认情况下,基于矢量的字体不是这种情况(浏览器可以直接访问字形几何,因此可以通过这种方式提供背景)。

创建自定义背景

为了创建背景,您需要先使用其他方式(例如形状或图像)来绘制它。

例子:

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();
}

在线演示在这里

请注意,这种“测量”高度的方式并不准确。您可以使用临时 div/span 元素测量字体的高度,并在为其设置字体和文本时从中获取计算的样式。

于 2013-09-19T17:36:50.123 回答
10

我更简单的解决方案是调用 fillText 两次。首先是一个 Unicode+2588 █ 字符串,它是一个黑色矩形,使用背景颜色重复与文本相同的长度。然后用前景色照常调用fillText。

于 2018-07-25T08:54:33.797 回答
2

此功能为您提供带有背景的垂直和水平居中文本。它仅适用于等宽字体(具有相同宽度的字符)。该函数计算要打印的字符串中的字符数,并将它们乘以 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");
于 2019-05-03T05:48:24.843 回答