Brk Brk - 7 months ago 8
HTML Question

how to parse html markup in fillText method of canvas

I have a canvas element which has labels. And each label is created using the

fillText
method.

I want to be able to send text like this: "CH2", but I don't get this as the final result. The element doesn't get parsed properly. How can I solve this issue?

Here is some example code:


var ctx = document.getElementById('canvas').getContext('2d');
ctx.font = "48px serif";
ctx.fillText("Hello <sub>world</sub>", 10, 50);

<canvas id="canvas" width=500 height=500 ><canvas>




K3N K3N
Answer

You can get around this using as @lipp mentions in comments Simon's solution and insert already sub-scripted characters into the string.

You can also make a simple parser that detects some code and renders next segment differently (see below).

There is also the possibility to use SVG to use HTML for drawing on canvas, but it has its backdraws such as async behavior, limited content (before security mechanisms prevent it from being drawn to a canvas) and lacking cross-browser support in some cases.

An example parser

This is just a start example. You can chose any code as well as adding new codes etc. This is just one way, there are many others...

If you have a HTML source string simply replace those tags with a code, or extend the parser to handle those as well.

var ctx = c.getContext("2d"),
    fontSize = 28,
    str = "This string has codes to enable |subscripted| text.";

setFontSize(fontSize);

// parse string
for(var i = 0, x = 10, tx = 0, isSub = false; i < str.length; i++) { // iterate over chars
  if (str[i] === "|") {                                              // special code?
    ctx.fillText(str.substring(tx, i), x, 50 + (isSub ? 7 : 0));     // draw current text seg
    x += ctx.measureText(str.substring(tx, i)).width;                // add width to x
    tx = ++i;                                                        // update start pointer
    isSub = !isSub;                                                  // toggle subscript mode
    setFontSize(isSub ? fontSize * 0.5 : fontSize);                  // set font size
  }
}

ctx.fillText(str.substring(tx, i), x, 50);                           // draw last text part

function setFontSize(sz) {ctx.font = sz + "px sans-serif"}
<canvas id=c width=600></canvas>