Canvas 多路径绘制需通过单次 fill() 配合 fillRule(nonzero 或 evenodd)实现逻辑合并,而非逐个填充;路径方向影响 nonzero 规则下的镂空效果,Path2D 可封装复用并支持变换与命中检测。

Canvas 绘制复杂形状时,光靠单个闭合路径往往不够——比如镂空图标、带缺口的徽章、重叠区域需不同填充逻辑(如奇偶填充),这时就得用多路径合并与 fill 规则配合实现。
多路径不是叠加,而是逻辑组合
多个 beginPath() + 路径命令构成的独立路径,在调用 fill() 时会按当前 fillRule 合并处理,而不是简单地逐个填充。关键在于:所有路径定义完后,只调一次 fill()(或 stroke()),浏览器才按规则统一计算填充区域。
-
fillRule默认是"nonzero"(非零环绕规则):从某点引一条射线,统计路径交点方向(顺时针+1,逆时针−1),总和非零即填充 - 设为
"evenodd"(奇偶规则):只看交点总数奇偶性,奇数就填充,适合内外环反向绘制的镂空效果 - 路径方向很重要:外轮廓通常用逆时针,内孔用顺时针(
nonzero下可自动“挖空”);若用evenodd,方向可统一,靠数量判断
用 Path2D 实现可复用的多路径封装
手动写多段 beginPath() 容易出错,尤其涉及变换或重复使用时。推荐用 Path2D 对象预先定义好复合路径,再整体绘制:
用户要生成可打印的中文字帖/练习纸、导出多页 A4 PDF 报告,或把 SVG 设计稿零误差还原到 Canvas 时使用。本技能是「Canvas 内容工厂闭环」的总控,编排:网格渲染引擎(13 种教育网格+拼音标注) → 多页 PDF 导出(A4 合成) → SVG 精准复刻(坐标误差<0.001px)。触发词:生成字帖、练习纸、导出 PDF、SVG 转 Canvas、印刷级还原、A4 报告、米字格田字格。
- 创建一个
Path2D实例,然后多次调用其addPath()或直接用路径方法追加子路径 - 例如:先画外圆,再
moveTo()到内圆起点,画内圆(方向相反),整个对象传给ctx.fill(path, "evenodd") -
Path2D不依赖上下文状态,支持平移、缩放后复用,也方便做命中检测(isPointInPath())
fillRule 实际应用示例
画一个中间镂空的五角星徽章:
- 先用标准五角星路径(逆时针)作为外轮廓
- 再添加一个居中较小的正五边形路径(顺时针),表示“挖掉”的区域
- 调用
ctx.fill(path, "nonzero")—— 因方向相反,内五边形自然被排除在填充区外 - 若两个都用逆时针,改用
ctx.fill(path, "evenodd")同样能达到镂空效果,更容错
注意路径状态与渲染时机
多路径操作容易踩的坑:
- 不要在多个
beginPath()之间漏掉moveTo()—— 否则lineTo()会连到上一路径终点,造成意外连线 -
closePath()每个子路径建议单独调用,确保每段逻辑闭合,避免跨路径干扰 -
fillStyle、globalAlpha等样式必须在fill()前设置,且对整组路径生效 - 如果混用
stroke()和fill(),注意stroke()不受fillRule影响,只描边当前路径轮廓

















