在 HTML Canvas 中添加字母间距

Jam*_*rke 5 html fonts text canvas

我读过很多 StackOverflow 答案和其他页面,讨论如何在 Canvas 中设置字母间距。更有用的之一是画布元素中的字母间距

正如另一个问题所说,“我有一个画布元素,我正在向其中绘制文本。我想设置类似于 CSS letter-spacing 属性的字母间距。我的意思是在绘制字符串时增加字母之间的像素数量。请注意,字母间距有时被错误地称为字距调整。

我注意到一般方法似乎是逐个字母地输出字符串,使用measureText(letter) 获取字母的宽度,然后添加额外的间距。这样做的问题是它没有考虑字母字距调整对等。请参阅上面的链接以获取此示例和相关评论。

在我看来,对于“间距”的行距,执行此操作的方法是执行以下操作:

  1. 从位置 (X, Y) 开始。
  2. 使用measureText()测量wAll,即整个字符串的宽度
  3. 删除字符串中的第一个字符
  4. 使用 fillText() 打印位置 (X, Y) 处的第一个字符
  5. 使用measureText() 测量wShorter,即生成的较短字符串的宽度。
  6. 从整个字符串的宽度中减去较短字符串的宽度,得到字符的紧缩宽度,wChar = wAll - wShorter
  7. 将 X 增加 wChar + 间距
  8. wAll = wShorter
  9. 从步骤 3 开始重复

这不会考虑字距调整吗?我错过了什么吗?measureText() 是否添加了根据最外层字符或其他内容而变化的填充负载,如果添加了, fillText() 不会使用相同的系统来输出字符,从而消除该问题?上面的链接中有人提到“像素对齐字体提示”,但我不明白这如何适用于这里。任何人都可以一般性或具体地建议这是否有效或是否存在问题?

编辑:这不是另一个问题的重复 - 它链接到并引用。问题不在于如何根据建议的副本执行“画布中的字母间距”;这是针对这个问题和其他问题提出一个可能的解决方案(据我所知没有其他人建议),并询问是否有人可以看到或知道该提议的解决方案的任何问题 - 即它询问提议的解决方案和它的要点,包括measureText()、fillText()和“像素对齐字体提示”的详细信息。

Jam*_*rke 4

好吧,我已经根据上面的伪代码编写了代码,并通过屏幕截图和目视差异进行了一些比较(缩放,使用例如剪辑框中的直线来比较每个字符的 X 位置和宽度)。对我来说看起来完全一样,间距设置为 0。

这是 HTML:

<canvas id="Test1" width="800px" height="200px"><p>Your browser does not support canvas.</p></canvas>
Run Code Online (Sandbox Code Playgroud)

这是代码:

this.fillTextWithSpacing = function(context, text, x, y, spacing)
{
    //Start at position (X, Y).
    //Measure wAll, the width of the entire string using measureText()
    wAll = context.measureText(text).width;

    do
    {
    //Remove the first character from the string
    char = text.substr(0, 1);
    text = text.substr(1);

    //Print the first character at position (X, Y) using fillText()
    context.fillText(char, x, y);

    //Measure wShorter, the width of the resulting shorter string using measureText().
    if (text == "")
        wShorter = 0;
    else
        wShorter = context.measureText(text).width;

    //Subtract the width of the shorter string from the width of the entire string, giving the kerned width of the character, wChar = wAll - wShorter
    wChar = wAll - wShorter;

    //Increment X by wChar + spacing
    x += wChar + spacing;

    //wAll = wShorter
    wAll = wShorter;

    //Repeat from step 3
    } while (text != "");
}
Run Code Online (Sandbox Code Playgroud)

演示/眼球测试代码:

element1 = document.getElementById("Test1");
textContext1 = element1.getContext('2d');

textContext1.font = "72px Verdana, sans-serif";
textContext1.textAlign = "left";
textContext1.textBaseline = "top";
textContext1.fillStyle = "#000000";

text = "Welcome to go WAVE";
this.fillTextWithSpacing(textContext1, text, 0, 0, 0);
textContext1.fillText(text, 0, 100);
Run Code Online (Sandbox Code Playgroud)

理想情况下,我会向其抛出多个随机字符串并进行逐像素比较。我也不确定 Verdana 的默认字距调整有多好,尽管我知道它比 Arial 更好 - 关于其他字体的建议,请尝试感激地接受。

所以...到目前为止看起来还不错。事实上它看起来很完美。还是希望有人能指出这个过程中的任何缺陷。

与此同时,我会将其放在这里供其他人看看他们是否正在寻找解决方案。