Html 在有背景的画布上书写文字

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18900117/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 13:35:48  来源:igfitidea点击:

Write text on canvas with background

htmlcanvastexthtml5-canvas

提问by rask

Is it possible to write image on canvas and write text with background? For example like this:

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

http://awesomescreenshot.com/09f1qf2213

http://awesomescreenshot.com/09f1qf2213

回答by

How text works in canvas

文本在画布中的工作原理

Unfortunately no, you can't produce text with background with the text methods - only fill or outline the text itself.

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

This is because the glyphs from the typeface (font) are converted to individual shapes or paths if you want, where the background of it would be the inner part of the glyph itself (the part you see when using fill). There is no layer for the black-box (the rectangle which the glyph fits within) the glyph is using besides from using its geometric position, so we need to provide a sort-of black-box and bearings ourselves.

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

On the old computer systems most fonts where binary font which where setting or clearing a pixels. Instead of just clearing the background one could opt to provide a background instead. This is not the case with vector based typefaces by default (a browser has direct access to the glyphs geometry and can therefor provide a background this way).

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

Creating custom background

创建自定义背景

In order to create a background you would need to draw it first using other means such as shapes or an image.

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

Examples:

例子:

ctx.fillRect(x, y, width, height);

or

或者

ctx.drawImage(image, x, y  [, width, height]);

then draw the text on top:

然后在顶部绘制文本:

ctx.fillText('My text', x, y);

You can use measureTextto find out the width of the text (in the future also the height: ascend + descend) and use that as a basis:

您可以使用measureText来找出文本的宽度(将来也可以使用高度:上升 + 下降)并将其用作基础:

var width = ctx.measureText('My text').width; /// width in pixels

You can wrap all this in a function. The function here is basic but you can expand it with color and background parameters as well as padding etc.

您可以将所有这些包装在一个函数中。这里的功能是基本的,但您可以使用颜色和背景参数以及填充等来扩展它。

/// 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

在线演示在这里

Just note that this way of "measuring" height is not accurate. You can measure height of a font by using a temporary div/span element and get the calculated style from that when font and text is set for it.

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

回答by ToonTalk

I simpler solution is to call fillText twice. First a string of Unicode+2588 █ which is a black rectangle repeated the same length as the text using the background color. And then call fillText as normal with the foreground color.

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

回答by Olof

This function gives you vertically and horizontally centered text with a background. It only works well with monospaced fonts (characters with the same width). The function counts the number of character in the string you which to print and multiplies them with 0.62 (assuming that the width of the font is slightly less than 0.62 times the height). The background is 1.5 times bigger than the font size. Change this to fit your needs.

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

So calling the function would look something like this.

所以调用函数看起来像这样。

centeredText("Hello World", 30, "red");