leaferjs-undo-redo
v1.0.2
Published
A robust Undo/Redo system for LeaferJS applications based on the Command Pattern.
Downloads
415
Maintainers
Readme
leaferjs-undo-redo
一个基于命令模式的 LeaferJS 应用程序的健壮且灵活的撤销/重做系统。
English Version | 中文版
目录
特性
- 基于命令模式: 清晰、可扩展的架构,用于管理操作。
- 撤销/重做堆栈: 轻松撤销和重做操作。
- 支持 LeaferJS 元素: 与
Rect和其他Leafer显示对象无缝协作。 - 可定制命令: 为任何 LeaferJS 操作实现您自己的命令。
- 批量命令: 将多个命令分组到一个可撤销/重做单元中。
- TypeScript 支持: 完整类型定义,提供更好的开发体验。
安装
使用 npm、yarn 或 pnpm 安装此包:
npm install leaferjs-undo-redo
# 或
yarn add leaferjs-undo-redo
# 或
pnpm add leaferjs-undo-redo使用方法
核心概念
该系统围绕 CommandManager 和 ICommand 接口展开。
ICommand: 所有命令必须实现的接口,定义了execute()、undo()和redo()方法。CommandManager: 管理已执行命令的历史记录,提供executeCommand()、undo()和redo()方法。
创建自定义命令
要创建自定义命令,请实现 ICommand 接口。例如,一个 MoveCommand:
// src/commands/MoveCommand.ts
import { ICommand } from '../command';
import { Rect } from 'leafer-ui';
export class MoveCommand implements ICommand {
private target: Rect;
private fromX: number;
private fromY: number;
private toX: number;
private toY: number;
constructor(target: Rect, fromX: number, fromY: number, toX: number, toY: number) {
this.target = target;
this.fromX = fromX;
this.fromY = fromY;
this.toX = toX;
this.toY = toY;
}
execute(): void {
this.target.set({
x: this.toX,
y: this.toY
});
}
undo(): void {
this.target.set({
x: this.fromX,
y: this.fromY
});
}
redo(): void {
this.execute();
}
}示例应用
以下是如何在 LeaferJS 应用程序中使用它的示例:
import { Leafer, Rect } from 'leafer-ui';
import { CommandManager } from 'leaferjs-undo-redo'; // 从您的包导入
import { AddElementCommand, MoveCommand, ResizeCommand } from 'leaferjs-undo-redo/dist/commands'; // 或导入单个命令
// ... (LeaferJS 的其余设置)
document.addEventListener('DOMContentLoaded', () => {
const appElement = document.getElementById('app');
if (!appElement) {
console.error('#app element not found!');
return;
}
const app: Leafer = new Leafer({
view: appElement,
width: window.innerWidth,
height: window.innerHeight,
});
const commandManager = new CommandManager();
// 添加一个矩形
const rect = new Rect({ x: 100, y: 100, width: 50, height: 50, fill: 'red', draggable: true });
const addCommand = new AddElementCommand(app, rect);
commandManager.executeCommand(addCommand);
// 处理拖动事件以进行移动
app.on('dragend', (e: any) => { // 在此处使用适当的 LeaferJS 事件类型
const target = e.target as Rect;
// 如果可能,从 dragstart 捕获 fromX, fromY
const moveCommand = new MoveCommand(target, e.startX, e.startY, target.x, target.y);
commandManager.executeCommand(moveCommand);
});
// 通过键盘快捷键撤销/重做
document.addEventListener('keydown', (e) => {
if (e.ctrlKey && e.key === 'z') {
commandManager.undo();
}
if (e.ctrlKey && e.key === 'y') {
commandManager.redo();
}
});
});更多详细示例,请参阅项目仓库中的 example/ 目录。
架构
该系统围绕经典的命令模式设计。主要组件包括:
ICommand: 定义了所有命令的execute()、undo()和redo()方法的接口。CommandManager: 一个单例(或每个上下文的实例),维护ICommand对象的历史堆栈,允许顺序撤销和重做操作。- 具体命令:
ICommand的特定实现,用于各种 LeaferJS 操作,例如AddElementCommand、MoveCommand、ResizeCommand、RemoveElementCommand和BatchCommand。
命令模式简化UML图
未来展望
- 批量命令: 已经实现,允许多个操作被视为一个可撤销/重做步骤。这对于多选或分组操作等复杂交互至关重要。
- 序列化/反序列化: 能够保存和加载命令历史记录。
- 命令缓冲/优化: 对于非常快速的操作(例如,实时绘图),优化命令添加到堆栈的方式,以防止过度的内存使用或性能瓶颈。
- UI 集成: 与 UI 元素更复杂的集成(例如,当没有可用的操作时禁用撤销/重做按钮)。
开发与贡献
要设置开发环境:
git clone [your-repo-url]
cd leaferjs-undo-redo
npm install
npm run build要运行示例应用程序:
npm run dev要运行测试:
npm test欢迎贡献!请提出问题或提交拉取请求。
许可证
本项目采用 MIT 许可证。
