我已经阅读了很多StackOverflow答案以及其他讨论如何在Canvas中进行字母间距的页面。其中一个更有用的是Letter spacing in canvas element
正如其他问题所说,'我有这个画布元素,我正在绘制文字。我想设置字母间距类似于CSS字母间距属性。我的意思是在绘制字符串时增加字母之间的像素数量。请注意,字母间距有时会被错误地称为字距调整。
我注意到一般的方法似乎是逐字母输出字符串,使用measureText(字母)来获取字母的宽度,然后添加额外的间距。这个问题是它没有考虑字母字距调整对等。有关此示例和相关注释,请参阅上面的链接。
对我而言,对于“间距”的行间距,这样做的方法是做类似的事情:
这不会考虑到字距调整吗?我错过了什么吗? measureText()是否会根据最外面的字符或其他内容添加一个填充加载,如果是,则fillText()不会使用相同的系统输出字符,否定该问题?上面的链接中有人提到'像素对齐字体提示',但我不知道这是如何适用的。任何人都可以一般或具体地建议这是否有效或者是否有问题?
编辑:这不是另一个问题的重复 - 它链接到并引用。根据拟议的副本,问题不在于如何做“画布上的字母间距”;这提出了一个可能的解决方案(据我所知,其他人没有建议)解决这个问题和其他问题,并询问是否有人能够看到或知道该提出的解决方案的任何问题 - 即它询问提出的解决方案和它的要点,包括measureText(),fillText()和'像素对齐字体提示'的细节。
答案 0 :(得分:2)
嗯,我已根据上面的伪代码编写了代码,并通过截屏和眼球对差异进行了一些比较(缩放,使用例如剪辑框的直线来比较每个的X位置和宽度)字符)。对我来说看起来完全一样,间距设置为0。
这是HTML:
<canvas id="Test1" width="800px" height="200px"><p>Your browser does not support canvas.</p></canvas>
以下是代码:
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 != "");
}
演示/眼球测试代码:
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);
理想情况下,我会在其上投掷多个随机字符串并逐个像素地进行比较。我也不确定Verdana的默认字距是多么好,虽然我明白它比Arial更好 - 其他字体的建议值得感激接受。
所以...到目前为止看起来不错。事实上它看起来很完美。 仍然希望有人能指出这个过程中的任何缺陷。
与此同时,我会把这个放在别人面前,看看他们是否在寻找解决方案。
答案 1 :(得分:0)
我的回答被删除了。 所以,我使用的是Chrome,这是我的完整代码。
second_image = $('#block_id').first();
canvas = document.getElementById('canvas');
canvas.style.letterSpacing = '2px';
ctx = canvas.getContext('2d');
canvas.crossOrigin = "Anonymous";
canvasDraw = function(text, font_size, font_style, fill_or_stroke){
canvas.width = second_image.width();
canvas.height = second_image.height();
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(second_image.get(0), 0, 0, canvas.width, canvas.height);
//refill text
ctx.font = font_size +'px '+ font_style + ',Symbola';
$test = ctx.font;
ctx.textAlign = "center";
if(fill_or_stroke){
ctx.fillStyle = "#d2b76d";
ctx.strokeStyle = "#9d8a5e";
ctx.strokeText(text,canvas.width*$left,canvas.height*$top);
ctx.fillText(text,canvas.width*$left,canvas.height*$top);
}
else{
ctx.strokeStyle = "#888888";
ctx.strokeText(text,canvas.width*$left,canvas.height*$top);
}
};
您不需要使用此功能this.fillTextWithSpacing
。我没有使用它,它就像一个魅力)