如何在Konva.js中實現命令類Command類以支持撤銷和重做功能?

如何在Konva.js中實現命令類Command類以支持撤銷和重做功能?

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
喜歡就支持一下吧
點贊11 分享