实现原理:
- 保存快照:每完成一次绘制操作则保存一份 canvas 快照到
canvasHistory
数组(生成快照使用 canvas 的toDataURL()
方法,生成的是 base64 的图片);- 撤销和反撤销:把
canvasHistory
数组中对应索引的快照使用 canvas 的drawImage()
方法重绘一遍;- 绘制新图像:执行新的绘制操作时,删除当前位置之后的数组记录,然后添加新的快照。
// 变量定义 let myCanvas = document.querySelector('#myCanvas'); let ctx = myCanvas.getContext('2d'); let canvasWidth = 200; let canvasHeight = 200; let canvasHistory = []; let step = -1; // 绘制方法 canvasDraw() { step++; if (step < canvasHistory.length) { canvasHistory.length = step; // 截断数组 } // 执行绘制的相关操作(如绘制图片、线条等) // ... // ... canvasHistory.push(myCanvas.toDataURL()); // 添加新的绘制到历史记录 } // 撤销方法 canvasUndo() { if (step >= 0) { step--; ctx.clearRect(0, 0, canvasWidth, canvasHeight); let canvasPic = new Image(); canvasPic.src = canvasHistory[step]; canvasPic.addEventListener('load', () => { ctx.drawImage(canvasPic, 0, 0); }); } else { console.log('不能再继续撤销了'); } } // 反撤销方法 canvasRedo() { if (step < canvasHistory.length - 1) { step++; let canvasPic = new Image(); canvasPic.src = canvasHistory[step]; canvasPic.addEventListener('load', () => { ctx.clearRect(0, 0, canvasWidth, canvasHeight); ctx.drawImage(canvasPic, 0, 0); }); } else { console.log('已经是最新的记录了'); } }