canvas绘制字体偏上不居中问题、文字垂直居中后偏上问题、measureText方法和TextMetrics对象

引入

在使用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等可能偏下
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要实现canvas绘制圆环,在圆环上有文字跟随角度位置的效果,可以使用以下步骤: 1. 创建一个canvas元素,并获取它的绘图上下文。 2. 设置圆环的位置、半径、线条宽度和颜色等属性,使用绘图上下文绘制一个圆环。 3. 计算每个文字所在的角度,根据文字的长度、字体大小和圆环半径等参数进行计算。 4. 使用绘图上下文中的translate和rotate方法将绘图坐标系旋文字所在的位置,然后使用fillText方法绘制文字。 示例代码如下: ``` // 获取canvas元素 var canvas = document.getElementById('canvas'); if (canvas.getContext) { // 获取绘图上下文 var ctx = canvas.getContext('2d'); // 设置圆环属性 var x = canvas.width / 2; var y = canvas.height / 2; var radius = 50; var lineWidth = 10; var color = '#000'; var startAngle = 0; var endAngle = Math.PI * 2; // 绘制圆环 ctx.beginPath(); ctx.arc(x, y, radius, startAngle, endAngle); ctx.lineWidth = lineWidth; ctx.strokeStyle = color; ctx.stroke(); // 设置文字属性 var text = 'Hello World!'; var font = '20px Arial'; var textWidth = ctx.measureText(text).width; var textHeight = parseInt(font); var step = Math.PI * 2 / text.length; // 每个文字所在的角度增量 var angle = 0; // 绘制文字 ctx.textAlign = 'center'; ctx.font = font; for (var i = 0; i < text.length; i++) { var char = text.charAt(i); var x = canvas.width / 2 + Math.cos(angle) * (radius + lineWidth + textWidth / 2); var y = canvas.height / 2 + Math.sin(angle) * (radius + lineWidth + textHeight / 2); ctx.translate(x, y); ctx.rotate(angle + Math.PI / 2); ctx.fillText(char, 0, 0); ctx.rotate(-(angle + Math.PI / 2)); ctx.translate(-x, -y); angle += step; } } ``` 该代码会在canvas绘制一个圆环,并在圆环上按照指定的角度位置绘制文字
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

列队猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值