唯杰地图 logo唯杰地图
VJMAP
EN

basic

vjcad/references/undo/basic.md 3.3 KB86 行
原文

本文回答:基础 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