Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write text on canvas with background

People also ask

How do you put text on a picture in canvas?

To draw text on a canvas, the most important property and methods are: font - defines the font properties for the text. fillText(text,x,y) - draws "filled" text on the canvas. strokeText(text,x,y) - draws text on the canvas (no fill)

Which of the following method is use to write text on the canvas?

There are two methods fillText() and strokeText() to draw text on canvas.


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.

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 measureText to find out the width of the text (in the future also the height: ascend + descend) and use that as a basis:

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.


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.


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.

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