为何修改Canvas 2D的fillStyle会改变已绘制矩形的颜色?
Canvas矩形颜色被意外覆盖的问题解决
你遇到的问题核心是Canvas 2D上下文的路径是累积式的:
- 每次调用
ctx.rect()都会把新的矩形路径添加到当前上下文的路径集合里,而非替换原有路径 - 调用
ctx.fill()时,会填充当前路径集合里的所有图形,不是只填充最后添加的那个
所以你的代码里:
- 第一次循环中,3个黄色矩形的路径被依次加入路径集合,每次
fill()都填充了当时的所有路径(第一次填第一个矩形,第二次填前两个,第三次填三个) - 修改
fillStyle为蓝色后调用ctx.fill(),会把路径集合里的全部4个矩形(3个小矩形+1个大矩形)用蓝色填充,导致所有矩形变蓝 - 注释第二个
fill()后,只有第一次循环的三次fill()生效,大矩形的路径没被填充,所以只显示3个黄色矩形
两种解决方法
方法1:每次绘制前重置路径(用beginPath())
每次绘制新图形前,调用ctx.beginPath()清空当前路径集合,后续的rect()只会添加到新路径,fill()也只填充当前新路径的图形:
const get = id => document.getElementById(id); const canv = get('canv'); const [w, h] = [canv.width, canv.height]; const ctx = canv.getContext("2d"); // 绘制黄色小矩形 ctx.fillStyle = 'yellow'; for (let x = 0; x < 3; x++) { ctx.beginPath(); // 每次绘制前重置路径 ctx.rect(10*x, 100, 3, 3); ctx.fill(); } // 绘制蓝色大矩形 ctx.fillStyle = 'blue'; ctx.beginPath(); // 重置路径,避免包含之前的矩形 ctx.rect(100, 100, 5, 5); ctx.fill();
方法2:直接使用fillRect()(更简洁)
fillRect()是直接填充指定矩形的API,会自动创建独立路径并完成填充,不会累积到上下文的路径集合里,代码更简洁:
const get = id => document.getElementById(id); const canv = get('canv'); const [w, h] = [canv.width, canv.height]; const ctx = canv.getContext("2d"); // 绘制黄色小矩形 ctx.fillStyle = 'yellow'; for (let x = 0; x < 3; x++) { ctx.fillRect(10*x, 100, 3, 3); // 直接填充,无需手动路径操作 } // 绘制蓝色大矩形 ctx.fillStyle = 'blue'; ctx.fillRect(100, 100, 5, 5);
补充说明
rect()属于路径构建API,需要配合fill()/stroke()完成绘制,且会累积路径fillRect()/strokeRect()属于直接绘制API,一步完成路径构建和填充/描边,不会累积路径,适合绘制独立的基础图形
内容的提问来源于stack exchange,提问作者user9163823
相关产品推荐
相关产品推荐

