如何在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 分享