如何调整Canvas 2D文本绘制顺序及避免fillStyle覆盖(含Chart.js场景)
我尝试在Canvas 2D上下文下绘制带文本的圆角矩形弧时,遇到两类问题:一是文本绘制在弧下方被遮挡,二是弧的fillStyle填充样式被后续文本的fillStyle覆盖无法正常生效。
问题原因分析
圆角矩形填充样式被覆盖的问题
核心原因是代码中每次调用fillText()之后,都额外执行了一次无目标路径的context.fill()。Canvas的路径是全局共享的,绘制完圆角矩形调用fill()之后路径并不会自动清空,后续设置了绿色的fillStyle之后再调用空的fill(),会用绿色重新填充之前的圆角矩形路径,直接覆盖了原本的红色填充。另外roundRect函数未主动调用closePath()闭合路径,也会加剧路径残留的问题。文本被圆角矩形遮挡的问题
Canvas按绘制顺序堆叠层级,先绘制的内容在下层、后绘制的在上层。如果将文本坐标调整到圆角矩形区域内,但先绘制文本、后绘制圆角矩形,文本自然会被后绘制的图形盖住。另外原代码中textAlign设置在fillText之后,对齐规则不会生效,也会导致文本位置不符合预期。
修正后的代码
HTML代码
<canvas width="500" height="300"></canvas>
JS代码
var roundRect = function(ctx, x, y, w, h, r) { var x2 = x + w; var y2 = y + h; if (w < 2 * r) r = w / 2; if (h < 2 * r) r = h / 2; ctx.beginPath(); ctx.moveTo(x + r, y); ctx.arcTo(x2, y, x2, y2, r); ctx.arcTo(x2, y2, x, y2, r); ctx.arcTo(x, y2, x, y, r); ctx.arcTo(x, y, x2, y, r); ctx.closePath(); // 主动闭合路径,避免路径残留 }; var canvas = document.querySelector('canvas'); var context = canvas.getContext('2d'); context.font = '16px sans-serif'; // 明确设置字体,避免文本渲染异常 // 第一个圆角矩形+文本 context.save(); roundRect(context, 0, 0, 50, 60, 20); context.fillStyle = 'red'; context.fill(); context.restore(); context.save(); context.fillStyle = 'green'; context.textAlign = "center"; // 对齐规则放在绘制前才会生效 context.fillText('Hey', 25, 35); // 后绘制文本,保证在上层不被遮挡 context.restore(); // 第二个圆角矩形+文本 context.save(); roundRect(context, 100, 100, 50, 90, 20); context.fillStyle = 'red'; context.fill(); context.restore(); context.save(); context.fillStyle = 'green'; context.textAlign = "center"; context.fillText('Hey', 125, 145); context.restore(); // 第三个圆角矩形+文本 context.save(); roundRect(context, 300, 100, 50, 120, 20); context.fillStyle = 'red'; context.fill(); context.restore(); context.save(); context.fillStyle = 'green'; context.textAlign = "center"; context.fillText('Hey', 325, 160); context.restore();
修正点说明
- 删除了所有多余的无路径
fill()调用,避免重复填充之前的图形路径 - 给
roundRect函数新增closePath()调用,主动闭合路径减少残留风险 - 调整绘制顺序,始终先绘制圆角矩形、后绘制文本,保证文本在上层显示
- 将
textAlign设置移到fillText之前,让对齐规则正常生效 - 给canvas设置固定宽高,避免默认小尺寸裁剪内容,新增字体设置保证文本渲染正常
- 调整文本坐标,让文本居中显示在对应圆角矩形内部
内容的提问来源于stack exchange,提问作者Abhishek Soni
相关产品推荐
相关产品推荐

