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

如何在原生Canvas中填充自定义闭合路径的外侧而非内侧区域

实现方案

原生Canvas实现闭合路径外侧填充有两种成熟的实现思路,无需引入第三方库即可完成需求:

方案1:使用evenodd填充规则 + 画布级矩形路径

原理是利用Canvas 2D的奇偶填充规则,先绘制覆盖整个画布的矩形,再叠加自定义闭合路径,填充时自动识别内外区域:

const context = canvas.getContext('2d')
const canvasWidth = canvas.width
const canvasHeight = canvas.height

canvas.addEventListener('mouseup', function (e) {
      context.closePath();
      // 新增覆盖整个画布的矩形路径
      context.rect(0, 0, canvasWidth, canvasHeight);
      // 设置填充色和填充规则
      context.fillStyle = 'green';
      context.fill('evenodd');
      draw = false;
});
  • evenodd填充规则会判断像素点所在的路径层数,画布矩形为最外层,自定义闭合路径为内层,最终填充的就是两层路径之间的外侧区域
  • 不需要修改原有鼠标绘制路径的逻辑,改动量最小

方案2:使用裁剪(clip)能力实现

如果不想调整填充规则,也可以通过裁剪功能实现需求:

const context = canvas.getContext('2d')
const canvasWidth = canvas.width
const canvasHeight = canvas.height

canvas.addEventListener('mouseup', function (e) {
      context.closePath();
      context.save(); // 保存当前绘图状态
      context.clip(); // 将绘制的闭合路径设为裁剪区域
      context.clearRect(0, 0, canvasWidth, canvasHeight); // 清空裁剪区域内的内容
      context.restore(); // 恢复状态取消裁剪
      // 填充整个画布,此时只有原路径外侧会被上色
      context.fillStyle = 'green';
      context.fillRect(0, 0, canvasWidth, canvasHeight);
      draw = false;
});
  • 逻辑直观,不需要理解填充规则的差异
  • 如果需要保留画布上原有的其他内容,可以在执行clip操作前将原有内容缓存到离屏Canvas,填充完成后再绘制回来即可

内容的提问来源于stack exchange,提问作者Gregory Kafanov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 10:06:02