HTML5 Canvas:渲染别名文本

时间:2018-08-21 19:31:59

标签: text html5-canvas

当您在HTML5画布上渲染文本时(例如,使用fillText命令),该文本将进行抗锯齿处理,这意味着文本看起来更平滑。缺点是,在尝试呈现小文本或特别是非锯齿的字体(例如Terminal)时,它变得非常明显。因此,我要做的是使文本呈现别名,而不是消除锯齿。

有什么办法吗?

1 个答案:

答案 0 :(得分:0)

不幸的是,没有本机方法可以关闭文本的抗锯齿功能。

解决方案是使用传统的位图字体方法,也就是说,对于HTML5 canvas,是一个精灵表,您可以在其中将每个位图字母复制到画布。通过使用具有透明背景的Sprite-sheet,您还可以轻松更改其颜色/渐变等。

此类位图的示例:

bitmap font sprite-sheet

要使其正常工作,您需要知道其中包含哪些字符(“地图”),每个字符的宽度和高度以及字体位图的宽度。

注意:在大多数情况下,您可能最终会得到等宽字体,其中所有单元格都具有相同的大小。您可以使用比例字体,但在这种情况下,您需要意识到需要将每个字符映射到一个绝对位置,并包括其单元格的宽度和高度。

带有注释的示例:

const ctx = c.getContext("2d"), font = new Image;
font.onload = () => {
  // define some meta-data
  const charWidth = 12;                          // character cell, in pixels
  const charHeight = 16;
  const sheetWidth = (font.width / charWidth)|0; // width, in characters, of the image itself

  // map so we can use index of a char. to calc. position in bitmap
  const charMap = " !\"#$% '()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~§";

  // Draw some demo text
  const timeStart = performance.now();
  fillBitmapText(font, "Demo text using bitmap font!", 20, 20);
  fillBitmapText(font, "This is line 2...", 20, 45);
  const timeEnd = performance.now();
  console.log("Text above rendered in", timeEnd - timeStart, "ms");
  
  // main example function
  function fillBitmapText(font, text, x, y) {
    // always make sure x and y are integer positions
    x = x|0;
    y = y|0;
    // current x position
    let cx = x;
    // now, iterate over text per char.
    for(let char of text) {
      // get index in map:
      const i = charMap.indexOf(char);
      if (i >= 0) { // valid char
        // Use index to calculate position in bitmap:
        const bx = (i % sheetWidth) * charWidth;
        const by = ((i / sheetWidth)|0) * charHeight;
        
        // draw in character on canvas
        ctx.drawImage(font, 
          // position and size from font bitmap
          bx, by, charWidth, charHeight,
          // position on canvas, same size
          cx, y, charWidth, charHeight);
      }
      cx += charWidth;  // increment current canvas x position
    }
  }
}
font.src = "//i.stack.imgur.com/GeawH.png";
body {background:#fff}
<canvas id=c width=640></canvas>

这应该产生类似于以下的输出:

demo output

您可以根据自己的需要进行修改。请注意,这里使用的位图不是透明的-我将其留给OP。