canvas绘制字体偏上问题
引入
在使用canvas绘制文字时,我其他使文字垂直居中,我是用的方法是设置textBaseline
属性为middle,但该属性不同浏览器出现了不同的效果,在chrome上字体会靠上一些
而在火狐浏览器中文字是居中的
原因
这是由于字体的实际所占空间并非我们设定的font-size,而是字体元素内容高度(content-area),这是字体设计时产生的
在设计字体时可以设置一些度量线(ascender,descender,capital height,x-height等),有些值(顶线、基线)是超出em-square之外的值
而不同浏览器使用的默认字体也不同,字体不同自然字体元素的高度就不同,此时中线的位置虽然对齐了,但文字就可能偏上,导致了该情况的产生
除此之外字母使用大写还是小写也会导致视觉中线的不同
解决方法
通过canvas上下文的measureText
方法可以获取TextMetrics
对象,该对象定义了字体宽度和辅助线的距离
验证一下,在谷歌和火狐浏览器中分别调用该方法,可见确实两个浏览器的辅助线位置不同
首先熟悉一下用到的API
1.CanvasRenderingContext2D.measureText()方法
语法
ctx.measureText(text);
参数
-
text
需要测量的String
返回值
TextMetrics 对象。
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var text = ctx.measureText("foo"); // TextMetrics object
text.width; // 16;
2.TextMetrics对象
在 canvas 中,TextMetrics
接口表示文本的尺寸,通过 CanvasRenderingContext2D.measureText()方法创建。
水平方向相关属性
TextMetrics.width 只读
- double 类型,使用 CSS 像素计算的内联字符串的宽度。基于当前上下文字体考虑。
TextMetrics.actualBoundingBoxLeft 只读
- double 类型,平行于基线,从CanvasRenderingContext2D.textAlign 属性确定的对齐点到文本矩形边界左侧的距离,使用 CSS 像素计算。
TextMetrics.actualBoundingBoxRight 只读
- double 类型,平行于基线,从CanvasRenderingContext2D.textAlign 属性确定的对齐点到文本矩形边界右侧的距离,使用 CSS 像素计算。
垂直方向相关属性
TextMetrics.fontBoundingBoxAscent 只读
- double 类型,从CanvasRenderingContext2D.textBaseline 属性标明的水平线到渲染文本的所有字体的矩形最高边界顶部的距离,使用 CSS 像素计算。
TextMetrics.fontBoundingBoxDescent 只读
- double 类型,从CanvasRenderingContext2D.textBaseline 属性标明的水平线到渲染文本的所有字体的矩形边界最底部的距离,使用 CSS 像素计算。
TextMetrics.actualBoundingBoxAscent 只读
- double 类型,从CanvasRenderingContext2D.textBaseline 属性标明的水平线到渲染文本的矩形边界顶部的距离,使用 CSS 像素计算。
TextMetrics.actualBoundingBoxDescent 只读
- double 类型,从CanvasRenderingContext2D.textBaseline 属性标明的水平线到渲染文本的矩形边界底部的距离,使用 CSS 像素计算。
TextMetrics.emHeightAscent 只读
- double 类型,从CanvasRenderingContext2D.textBaseline 属性标明的水平线到线框中 em 方块顶部的距离,使用 CSS 像素计算。
TextMetrics.emHeightDescent 只读
- double 类型,从CanvasRenderingContext2D.textBaseline 属性标明的水平线到线框中 em 方块底部的距离,使用 CSS 像素计算。
TextMetrics.hangingBaseline 只读
- double 类型,从CanvasRenderingContext2D.textBaseline 属性标明的水平线到线框的 hanging 基线的距离,使用 CSS 像素计算。
TextMetrics.alphabeticBaseline 只读
- double 类型,从CanvasRenderingContext2D.textBaseline 属性标明的水平线到线框的 alphabetic 基线的距离,使用 CSS 像素计算。
TextMetrics.ideographicBaseline 只读
- double 类型,从CanvasRenderingContext2D.textBaseline 属性标明的水平线到线框的 ideographic 基线的距离,使用 CSS 像素计算。
这里主要使用的是TextMetrics.actualBoundingBoxAscent属性,该属性返回从CanvasRenderingContext2D.textBaseline 属性标明的水平线到渲染文本的矩形边界顶部的距离,所以将 textBaseline 设置为alphabetic(此时actualBoundingBoxDescent 为0),然后获取actualBoundingBoxAscent的值,该值表示整个字体所占的实际大小,将该值除2即是中点位置
限制
一些小写字母如y等可能偏下