You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HTML Canvas绘制带边框填充图形的异常问题及优化问询

HTML Canvas绘制带边框填充图形的异常问题及优化问询

我最近在研究如何用HTML Canvas绘制带边框的填充图形,写了4个测试示例,但只有其中一个能得到干净清晰的效果,实在摸不透背后的原因,想请教各位大佬帮忙解惑!

先上我的测试代码:

let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
ctx.save();

let border = 2;

// 整数坐标
usingStroke(ctx, 50, 50, border, 1);
usingFill(ctx, 150, 50, border, 2);

// 半像素偏移
usingStroke(ctx, 50.5, 150.5, border, 3);
usingFill(ctx, 150.5, 150.5, border, 4);

ctx.restore();

function usingStroke(ctx, x, y, border, text) {
  ctx.beginPath();
  ctx.arc(x, y, 25, 0, 2 * Math.PI);
  ctx.rect(x+10, y, 50, 30);
  ctx.lineWidth = border * 2; // 一半会被填充层覆盖
  ctx.strokeStyle = 'darkred';
  ctx.stroke();
  ctx.fillStyle = 'salmon';
  ctx.fill();
  addText(ctx, text, x, y);
}

function usingFill(ctx, x, y, border, text) {
  ctx.beginPath();
  ctx.arc(x, y, 25 + border, 0, 2 * Math.PI);
  ctx.rect(x+10-border, y-border, 50+border*2, 30+border*2);
  ctx.fillStyle = 'darkred';
  ctx.fill();
  ctx.beginPath();
  ctx.arc(x, y, 25, 0, 2 * Math.PI);
  ctx.rect(x+10, y, 50, 30);
  ctx.fillStyle = 'salmon';
  ctx.fill();
  addText(ctx, text, x, y);
}

function addText(ctx, text, x, y) {
  ctx.font = "bold 20px sans";
  ctx.fillStyle = 'black';
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';
  ctx.fillText(text, x, y);
}
<canvas id="canvas" width="600" height="400"></canvas>

我用了两种不同的实现思路:

  • 示例1和3:先绘制边框(stroke),再填充内部(fill)
  • 示例2和4:用两次填充实现——第一次用边框色绘制更大一圈的图形,第二次用填充色绘制原尺寸图形

另外我也知道,奇数宽度的线条容易模糊,需要偏移半像素来获得清晰效果(所以做了示例3和4)。但我还是有几个困惑:

  1. 为什么只有示例2能得到清晰的效果?
  2. 示例1和3(用stroke的方式)的边框为什么不均匀?看起来图形左上角的边框比右下角要粗,一开始我以为是低分辨率的问题,加了半像素偏移也没解决……

现在我对stroke的实现方式有点头疼,想知道有没有更好的使用方法——我平时只需要1-3像素的细边框,stroke在粗边框时表现还行,但细边框就出问题了。

备注:内容来源于stack exchange,提问作者Yosko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 10:34:29