为什么canvas绘制文字定位不准确?
前言
之前做了一个《在线拼图》的项目,其中有一个添加文字的功能。用户点击下载按钮后,要先将文字绘制到canvas画布上然后再下载到本地。
看了菜鸟教程的教学,发现了有两个细节是教程中没有提到的。而这两个细节却决定了文字在画布上的定位是否准确。
如果能搞清楚这两个遗漏的细节,就可以根据实际情况解决问题。所以以下内容围绕这两个细节详细展开说明。
顺便附上菜鸟教程的地址:
canvas fillText()用法.
canvas textAlign用法.
细节一:fillText()定位的是文字左下角,而不是左上角。
首先,看菜鸟教程对y坐标的解释:注意开始绘制这几个字(坑)。
然后,根据菜鸟教程开始编写代码:意图将文字绘制在(250, 100)开始的位置。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<canvas id="myCanvas" width="500" height="500" style="border:5px solid #000;">
<script type="text/javascript">
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
//在(250, 100)画一个黑色竖线
ctx.strokeStyle = "black";
ctx.moveTo(250, 100);
ctx.lineTo(250, 400);
ctx.stroke();
ctx.font = "30px Arial"; // 字号
// 绘制文字
ctx.fillText("HelloWorld", 250, 100);
</script>
</body>
</html>
上述代码想象中的效果:找到文字左上角(250, 100),然后开始绘制。HelloWorld应该在红色点的下方。
实际运行效果: HelloWorld在红色点的上方。
由此得出结论:
fillText()的x轴y轴的定位,定位的是文字左下角,而不是左上角。
细节二:关于汉字和字母(gjpqy)的定位。
首先,要知道设置字体大小其实设置的是字体框的大小。相同大小的字体框与字体框之间是水平对齐的。所以汉字的定位相对较为准确。
其次,英文字母可以用小时候抄英文字母的四线格来理解。从上往下数第三根线姑且称它为基线。使用fillText()定位时,y轴定位就落在字母的基线。
注意!!!
当文字中有小写字母“gjpqy”时,容易出错。
比如:现在想把ABabcgjpqy这串字母完全放置在黑色竖线的上方。
实现代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<canvas id="myCanvas" width="500" height="500" style="border:5px solid #000;">
<script type="text/javascript">
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
//在(250, 100)画一个黑色竖线
ctx.strokeStyle = "black";
ctx.moveTo(250, 100);
ctx.lineTo(250, 400);
ctx.stroke();
ctx.font = "50px Arial";
ctx.textAlign = "center"; // 文字中心
// 绘制文字
ctx.fillText("ABabcgjpqy", 250, 100);
</script>
</body>
</html>
想象中的效果:英文字母完全在竖线(250, 100)的上方。
实际上显示的效果:四线格基线上的字母完全处于竖线上方,而超过基线的字母则有一部分处于竖线的下方。
由此得出结论:
fillText()汉字定位:y轴定位在汉字框底部。
fillText()字母定位:y轴定位在四线格基线。
总结
综上所述,文字定位不准确的来源是y轴定位不明确的问题。
最后用以下表格来总结一下y轴到底是怎么定位的。
y轴 | 描述 |
---|---|
起始点 | 位于左下角(对齐方式默认为左时) |
汉字 | 位于文字框底部 |
字母 | 位于四线格基线 |