写本编文章,是因为在使用 canvas
绘制图形时,遇到了一个问题:在绘制图形时,后面设置的图形样式(颜色、线宽等)覆盖了前面绘制图形的样式
。通过研究,发现是对 canvas
绘制路径时的相关方法beginPath()
了解不深导致的,在此记录说明,希望能为遇到同样问题的童鞋解惑!
下面直接通过例举示例说明。
通过 fillRect()
绘制矩形
const canvas_a = document.getElementById('canvas_a');
const ctx_a = canvas_a.getContext('2d');
ctx_a.fillStyle = '#2DE0A5'; // 绿色
ctx_a.fillRect(10, 10, 80, 40);
ctx_a.fillStyle = '#03a9f4'; // 蓝色
ctx_a.fillRect(10, 60, 80, 40);
通过 rect()
绘制矩形(错误的写法)
const canvas_b = document.getElementById('canvas_b');
const ctx_b = canvas_b.getContext('2d');
ctx_b.fillStyle = '#2DE0A5'; // 绿色
ctx_b.rect(10, 10, 80, 40);
ctx_b.fill();
ctx_b.fillStyle = '#03a9f4'; // 蓝色
ctx_b.rect(10, 60, 80, 40);
ctx_b.fill();
「发现」:绘制第二个矩形时设置的样式(蓝色)覆盖了第一个矩形的样式(绿色)
这里引用《红宝书》书中相关的话说明:
-
矩形是唯一一个可以 直接 在 2D 绘图上下文中绘制的形状。与绘制矩形相关的方法有 3 个:fillRect()、strokeRect()和 clearRect()。
-
要绘制路径,必须首先调用
beginPath()
方法以表示要开始绘制 新路径。 -
rect()
方法与strokeRect()
和fillRect()
的区别在于,它创建的是一条路径,而不是独立的图形。
通过 rect()
绘制矩形(正确的写法)
const canvas_c = document.getElementById('canvas_c');
const ctx_c = canvas_c.getContext('2d');
ctx_c.beginPath(); // 调用表示新路径
ctx_c.fillStyle = '#2DE0A5';
ctx_c.rect(10, 10, 80, 40);
ctx_c.fill();
ctx_c.beginPath(); // 调用表示新路径
ctx_c.fillStyle = '#03a9f4';
ctx_c.rect(10, 60, 80, 40);
ctx_c.fill();
绘制线条(错误的写法)
const canvas_x = document.getElementById('canvas_x');
const ctx_x = canvas_x.getContext('2d');
ctx_x.lineWidth = 15;
ctx_x.strokeStyle = '#2DE0A5';
ctx_x.moveTo(20, 20);
ctx_x.lineTo(120, 20);
ctx_x.stroke();
ctx_x.strokeStyle = '#03a9f4';
ctx_x.moveTo(20, 60);
ctx_x.lineTo(120, 60);
ctx_x.stroke();
绘制线条(正确的写法)
const canvas_x = document.getElementById('canvas_x');
const ctx_x = canvas_x.getContext('2d');
ctx_x.lineWidth = 15;
ctx_x.beginPath(); // 调用表示新路径
ctx_x.strokeStyle = '#2DE0A5';
ctx_x.moveTo(20, 20);
ctx_x.lineTo(120, 20);
ctx_x.stroke();
ctx_x.beginPath(); // 调用表示新路径
ctx_x.strokeStyle = '#03a9f4';
ctx_x.moveTo(20, 60);
ctx_x.lineTo(120, 60);
ctx_x.stroke();
至于具体原因,看到有人说是 canvas
每次的绘制会重新把整个画布上内容重新绘制一遍,待深入了解o(╥﹏╥)o !看到的大佬也欢迎解惑^v^