basic
本文回答:基础 API =
Engine.undoManager.{undo, redo, canUndo, canRedo, getUndoCount, getRedoCount}。命令版 = 命令行UNDO/REDO(没有U别名)或快捷键Ctrl+Z(仅撤销;菜单上显示的Ctrl+Y并未绑定)。undo()/redo()/undoSteps()只改数据、不刷新画布,之后要自己Engine.regen()。批量撤销 / 重做 N 步用undoSteps(n)/redoSteps(n),可按名称或步数。
一、最小 API
const u = Engine.undoManager;
u.undo(); Engine.regen(); // undo/redo/undoSteps 只改数据不刷新画布(返回值是所需重绘级别)
u.redo(); Engine.regen();
if (u.canUndo()) console.log('可撤销');
if (u.canRedo()) console.log('可重做');
console.log('剩余撤销步数:', u.getUndoCount());
console.log('剩余重做步数:', u.getRedoCount());
MCP 参考:vjcad/doc/undo/index.md、vjcad/example/undo/01basic.js。
二、批量撤销 / 重做
// 撤销 3 步
u.undoSteps(3);
// 按名称撤销 — 撤销到最近一次匹配(含),无匹配则不执行
u.undoSteps('绘制直线');
// 静默撤销:silent 只抑制逐步的 UndoStackChanged(undoSteps 结束时仍派发一次);
// UndoManager 本身从不写命令行
u.undoSteps(3, { silent: true });
Engine.regen();
// 重做
u.redoSteps(2);
u.redoSteps('绘制圆');
// 静默回滚最后一组操作(用于对话框取消等):全程不派发 UndoStackChanged,UI 撤销按钮不会刷新
u.rollbackLastGroup();
Engine.regen();
MCP 参考:vjcad/doc/undo/undo-redo.md、vjcad/example/undo/04description.js。
三、命令行 / 快捷键
| 命令 | 快捷键 | 说明 |
|---|---|---|
UNDO |
Ctrl+Z |
撤销(UNDO 命令会按返回值自动 redraw/regen 并在命令行提示) |
REDO |
—(菜单显示 Ctrl+Y,但键盘处理只绑定了 Ctrl+Z) |
重做 |
Engine.editor.executerWithOp('UNDO'); // ⚠️ 不是 'U'——CommandAlias 里没有 U→UNDO 的别名
Engine.editor.executerWithOp('REDO'); // 'MREDO' 也不存在
四、典型 UI 集成
function refreshUndoButton() {
const btnUndo = document.getElementById('btn-undo');
const btnRedo = document.getElementById('btn-redo');
btnUndo.disabled = !Engine.undoManager.canUndo();
btnRedo.disabled = !Engine.undoManager.canRedo();
}
// 监听撤销栈变化(推荐)
import { CadEventManager, CadEvents } from 'vjcad';
CadEventManager.getInstance().on(CadEvents.UndoStackChanged, (args) => {
refreshUndoButton();
console.log('下一步撤销:', args.nextUndoLabel);
});
MCP 参考:vjcad/doc/undo/undo-redo.md、vjcad/example/undo/04description.js。
反例
- 以为
u.undo()/u.undoSteps(n)会自动刷新画布:它们只改数据、返回所需重绘级别,不会 redraw/regen——画面不变,要自己Engine.regen()(UNDO命令才会自动刷新)。批量撤销用u.undoSteps(n)(还支持按名称)。 - 在没有
startUndoRecord的情况下直接move/scale实体后 undo:因为没有撤销标记,看上去什么都没回滚。
参考(官方文档 MCP)
- 文档:
vjcad/doc/undo/index.md、vjcad/doc/undo/undo-redo.md - 示例:
vjcad/example/undo/01basic.js