如何使用Canvas创建弧形文本?已参考相关方案仍存疑问
用Canvas创建弧形文本的实现方法
当然可以用Canvas实现弧形文本!你之前看到的顶部/底部弯曲效果只是弧形文本的两种基础样式,只要调整一下字符位置的计算逻辑,就能做出任意弧度的弧形文本——不管是向上拱起、向下凹陷,还是环绕成半圆甚至整圆形。
核心思路
弧形文本的本质是把每个字符单独绘制在圆弧的对应位置上,并且让每个字符的朝向贴合圆弧的切线方向。具体步骤大概是这样:
- 先计算整个文本的总宽度,确定弧形的起始角度
- 逐个遍历每个字符,计算它在圆弧上的精确坐标
- 旋转字符,让它和圆弧切线方向一致
- 依次绘制每个字符
原生Canvas实现代码示例
下面是一个可以自定义弧度方向、半径的完整示例,你可以直接运行试试:
function drawArcText(ctx, text, centerX, centerY, radius, isClockwise = false) { ctx.save(); ctx.font = '24px Arial'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; // 计算每个字符的宽度,以及文本总宽度 const charWidths = Array.from(text).map(char => ctx.measureText(char).width); const totalWidth = charWidths.reduce((sum, width) => sum + width, 0); // 计算起始角度:让文本在圆弧上居中 const startAngle = (Math.PI - totalWidth / radius) / 2; let currentAngle = isClockwise ? -startAngle : startAngle; Array.from(text).forEach((char, index) => { // 计算当前字符的弧度偏移 const charHalfWidth = charWidths[index] / 2; const angleOffset = charHalfWidth / radius; // 计算字符的绘制位置 const x = centerX + radius * Math.cos(currentAngle); const y = centerY + radius * (isClockwise ? Math.sin(currentAngle) : -Math.sin(currentAngle)); // 保存当前状态,旋转字符后绘制 ctx.save(); ctx.translate(x, y); // 旋转角度要贴合圆弧切线 ctx.rotate(isClockwise ? currentAngle - Math.PI / 2 : currentAngle + Math.PI / 2); ctx.fillText(char, 0, 0); ctx.restore(); // 更新下一个字符的角度 currentAngle += (isClockwise ? 1 : -1) * (charWidths[index] / radius); }); ctx.restore(); } // 使用示例 const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); drawArcText(ctx, '这是一段弧形文本', canvas.width/2, canvas.height/2, 150); drawArcText(ctx, 'Clockwise Arc Text', canvas.width/2, canvas.height/2 + 200, 120, true);
关键细节说明
radius参数控制弧形的曲率:半径越小,弯曲程度越大;半径越大,越接近直线isClockwise参数可以切换弧形方向:false是向上拱起的“屋顶”效果,true是向下凹陷的“山谷”效果,调整逻辑还能实现环绕整圆的文本- 字符旋转角度的计算是关键:要让字符的中轴线和圆弧切线方向一致,这样文字才会自然贴合弧形
用Fabric.js实现的思路
如果你习惯用Fabric.js,可以自定义一个ArcText类,继承fabric.Text,重写_render方法,在里面实现上述字符拆分和位置计算逻辑,这样就能像使用普通文本对象一样操作弧形文本了。
内容的提问来源于stack exchange,提问作者Ali Kazmi
相关产品推荐
相关产品推荐

