1. 基本清除方法
1.1 使用 clearRect
方法清除指定区域
clearRect(x, y, width, height)
是 Canvas
提供的内置方法,用于清除指定矩形区域内容(变为透明),而不影响画布的其他部分。
ctx.clearRect(x, y, width, height);
- 优点:简单高效,直接清除。
- 局限:只能清除矩形区域,其他形状需结合路径裁剪。
1.2 使用路径裁剪后清除
对于非矩形区域,可以先定义一个路径并裁剪后清除内容。
ctx.beginPath();
ctx.arc(x, y, radius, 0, 2 * Math.PI);
ctx.clip(); // 设置裁剪区域
ctx.clearRect(0, 0, canvas.width, canvas.height); // 清除裁剪区域内内容
ctx.restore(); // 恢复上下文状态
- 优点:支持任意形状的清除。
- 局限:需要额外管理裁剪区域的状态。
2. 使用混合模式清除内容
2.1 使用 globalCompositeOperation
设置 globalCompositeOperation
为 "destination-out"
,然后绘制透明的形状以清除内容。
ctx.globalCompositeOperation = "destination-out";
ctx.beginPath();
ctx.arc(x, y, radius, 0, 2 * Math.PI);
ctx.fill(); // 填充透明形状,清除内容
ctx.globalCompositeOperation = "source-over"; // 恢复默认模式
- 优点:支持复杂形状的清除。
- 局限:需要处理混合模式的状态,可能影响后续绘制。
3. 仅重绘需要清除的部分
3.1 保存内容到离屏画布
将内容绘制到离屏画布(OffscreenCanvas
)中,使用时再绘制到主画布。清除时只需重绘未清除部分。
const offscreenCanvas = document.createElement('canvas');
const offCtx = offscreenCanvas.getContext('2d');
// 在离屏画布上绘制
offCtx.drawImage(...);
// 将离屏内容绘制到主画布
ctx.drawImage(offscreenCanvas, 0, 0);
- 优点:内容分层,清除指定部分不影响其他内容。
- 局限:离屏画布占用额外的内存。
3.2 使用数据缓存重绘
通过 getImageData
保存画布内容,再用 putImageData
恢复指定区域的内容。
// 保存画布内容
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
// 清除指定区域
ctx.clearRect(x, y, width, height);
// 恢复内容
ctx.putImageData(imageData, 0, 0);
- 优点:适用于简单的内容保存与恢复。
- 局限:复杂内容性能较差,不适合频繁更新。
4. 实现代码示例
矩形区域清除
ctx.clearRect(50, 50, 100, 100);
圆形区域清除
ctx.save();
ctx.beginPath();
ctx.arc(100, 100, 50, 0, 2 * Math.PI);
ctx.clip();
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.restore();
复杂形状清除(使用混合模式)
ctx.globalCompositeOperation = "destination-out";
ctx.beginPath();
ctx.rect(50, 50, 100, 100);
ctx.fill();
ctx.globalCompositeOperation = "source-over";
离屏画布清除并重绘
const offscreenCanvas = document.createElement('canvas');
offscreenCanvas.width = canvas.width;
offscreenCanvas.height = canvas.height;
const offCtx = offscreenCanvas.getContext('2d');
// 在离屏画布上绘制
offCtx.fillStyle = "blue";
offCtx.fillRect(50, 50, 200, 200);
// 在主画布上绘制离屏内容
ctx.drawImage(offscreenCanvas, 0, 0);
// 清除主画布部分内容并重新绘制离屏内容
ctx.clearRect(50, 50, 100, 100);
ctx.drawImage(offscreenCanvas, 0, 0);
5. 注意事项
- 使用
clearRect
清除时,背景默认透明(rgba(0, 0, 0, 0)
)。 - 使用裁剪区域时,必须在
clip()
后立即清除,不然可能导致意外结果。 - 离屏画布适用于复杂多层场景,但需注意内存占用。
- 对于动态交互(如鼠标拖拽),建议配合离屏画布或
ImageData
提高性能。