Konva.JS中基于命令模式的撤銷重做功能實現
本文介紹如何在Konva.js繪圖應用中,利用命令模式實現撤銷(Ctrl+Z)和重做(Ctrl+Y)功能。 我們將圖形操作封裝成命令對象,并使用命令棧管理這些操作,從而實現圖形編輯的回退和前進。
首先,定義一個基礎Command類:
class Command { constructor() { this.states = []; // 用于存儲狀態快照 } execute() { throw new Error('execute method must be implemented'); } undo() { throw new Error('undo method must be implemented'); } saveState(state) { this.states.push(state); } restoreState() { return this.states.pop() || null; // 返回上一個狀態,或null } }
接下來,創建一個具體的命令類,例如繪制矩形的命令:
class DrawRectangleCommand extends Command { constructor(stage, layer, rect) { super(); this.stage = stage; this.layer = layer; this.rect = rect; } execute() { this.saveState(this.layer.toJSON()); // 保存當前圖層狀態 this.layer.add(this.rect); this.layer.draw(); } undo() { this.rect.destroy(); const prevState = this.restoreState(); if (prevState) { this.layer.destroyChildren(); // 清空圖層 this.layer = Konva.Node.create(prevState, this.stage); // 恢復上一個狀態 this.stage.add(this.layer); this.layer.draw(); } } }
然后,實現命令管理器:
class CommandManager { constructor() { this.undoStack = []; this.redoStack = []; } executeCommand(command) { command.execute(); this.undoStack.push(command); this.redoStack = []; // 執行新命令后,清空重做棧 } undo() { if (this.undoStack.length === 0) return; const command = this.undoStack.pop(); command.undo(); this.redoStack.push(command); } redo() { if (this.redoStack.length === 0) return; const command = this.redoStack.pop(); command.execute(); this.undoStack.push(command); } }
最后,在Konva.js應用中使用:
const stage = new Konva.Stage({ container: 'container', width: window.innerWidth, height: window.innerHeight }); const layer = new Konva.Layer(); stage.add(layer); const commandManager = new CommandManager(); stage.on('click', (e) => { const rect = new Konva.Rect({ x: e.evt.layerX, y: e.evt.layerY, width: 50, height: 50, fill: 'red', draggable: true }); const command = new DrawRectangleCommand(stage, layer, rect); commandManager.executeCommand(command); }); document.addEventListener('keydown', (e) => { if (e.ctrlKey && e.key === 'z') { commandManager.undo(); } else if (e.ctrlKey && e.key === 'y') { commandManager.redo(); } });
這段代碼實現了簡單的矩形繪制和撤銷重做功能。 您可以擴展Command類來支持其他圖形操作,例如移動、縮放、旋轉等。 記住在每個操作的execute方法中保存當前狀態,并在undo方法中恢復之前狀態。 這將確保您的撤銷重做功能能夠正確工作。
? 版權聲明
文章版權歸作者所有,未經允許請勿轉載。
THE END