drawui-core 0.5.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -254,6 +254,11 @@ interface GenerationPreview {
254
254
  to: Vec2;
255
255
  /** 待放置图形的类型;不提供(指向已有图形)时只画线条 */
256
256
  type?: ShapeType;
257
+ /** 待放置图形的尺寸(同型生成时沿用源图形尺寸,虚框必须按它画才与最终一致) */
258
+ size?: {
259
+ width: number;
260
+ height: number;
261
+ };
257
262
  /** 源图形 id 与出线边:预览走与最终创建相同的「出线边同轴接入」路由 */
258
263
  sourceShapeId?: string;
259
264
  sourceEdge?: 'n' | 'e' | 's' | 'w';
@@ -340,6 +345,7 @@ interface DrawShape extends BaseShape {
340
345
  points: Vec2[];
341
346
  }
342
347
  /** 思维导图节点:可带子节点;颜色/图标/属性说明均可手动覆盖,默认取层级色 */
348
+ type MindMapDirection = 'right' | 'left' | 'up' | 'down';
343
349
  interface MindMapNode {
344
350
  id: string;
345
351
  text: string;
@@ -353,6 +359,13 @@ interface MindMapNode {
353
359
  noteColor?: string;
354
360
  collapsed?: boolean;
355
361
  children?: MindMapNode[];
362
+ /** 该节点相对于父节点的生长方向;根节点无方向,子节点继承父方向(缺省为 right) */
363
+ direction?: MindMapDirection;
364
+ /** 手动拖拽产生的偏移(导图局部坐标,相对自动布局位置);拖拽节点时连子树一起平移 */
365
+ offset?: {
366
+ dx: number;
367
+ dy: number;
368
+ };
356
369
  }
357
370
  interface MindMapShape extends BaseShape {
358
371
  type: 'mind-map';
@@ -554,6 +567,17 @@ declare function getTheme(): DrawuiTheme;
554
567
  declare function hexToRgba(hex: string, alpha: number): string;
555
568
  /** 颜色变暗/变亮:percent 负数变暗、正数变亮 */
556
569
  declare function shadeColor(hex: string, percent: number): string;
570
+ /** 页面主题(画布背景 + UI 色调),与 react 层 theme.less 的 data-theme 一一对应 */
571
+ type PageTheme = 'light' | 'warm' | 'gray' | 'purple' | 'green' | 'eye-care';
572
+ /** 页面主题在 core 层需要覆盖的颜色 */
573
+ interface PageThemePreset {
574
+ /** 网格线颜色 */
575
+ grid: string;
576
+ }
577
+ /** 页面主题预设:网格颜色随背景深浅调整,保证可见但不突兀 */
578
+ declare const PAGE_THEMES: Record<PageTheme, PageThemePreset>;
579
+ /** 默认页面主题 */
580
+ declare const DEFAULT_PAGE_THEME: PageTheme;
557
581
 
558
582
  /**
559
583
  * 国际化:框架无关的轻量字典 + 语言切换。
@@ -745,6 +769,10 @@ declare const zhCN: {
745
769
  readonly 'mindmap.expand': "展开";
746
770
  readonly 'mindmap.close': "关闭编辑";
747
771
  readonly 'mindmap.more': "更多设置";
772
+ readonly 'mindmap.level': "层级";
773
+ readonly 'mindmap.promote1': "升一级";
774
+ readonly 'mindmap.promote2': "升两级";
775
+ readonly 'mindmap.promoteDisabled': "已至顶层";
748
776
  readonly 'tool.table': "表格";
749
777
  readonly 'toolbar.table': "表格";
750
778
  readonly 'shape.table': "表格";
@@ -781,6 +809,14 @@ declare const zhCN: {
781
809
  readonly 'ctx.delete': "删除";
782
810
  readonly 'toolbar.icon': "图标";
783
811
  readonly 'toolbar.image': "图片";
812
+ readonly 'toolbar.more': "更多";
813
+ readonly 'toolbar.pageTheme': "页面主题";
814
+ readonly 'pageTheme.light': "默认";
815
+ readonly 'pageTheme.warm': "暖黄";
816
+ readonly 'pageTheme.gray': "浅灰";
817
+ readonly 'pageTheme.purple': "浅紫";
818
+ readonly 'pageTheme.green': "浅绿";
819
+ readonly 'pageTheme.eye-care': "护眼";
784
820
  readonly 'tool.image': "图片";
785
821
  readonly 'image.uploadFailed': "图片上传失败";
786
822
  readonly 'image.insertFailed': "图片插入失败";
@@ -846,6 +882,118 @@ declare function exportToBlob(shapes: Shape[], format: ExportFormat, opts?: Expo
846
882
  /** 浏览器端触发下载 */
847
883
  declare function downloadBlob(blob: Blob, fileName: string): void;
848
884
 
885
+ /** 不同层级节点的默认颜色,超过 6 层后循环复用 */
886
+ declare const MINDMAP_COLORS: string[];
887
+ declare const MINDMAP_FONT_SIZE = 14;
888
+ declare const MINDMAP_NODE_HEIGHT = 40;
889
+ declare const MINDMAP_MIN_WIDTH = 80;
890
+ declare const MINDMAP_MAX_WIDTH = 240;
891
+ /** 节点上「+」快捷按钮的圆钮半径(页面单位,随缩放一起放大,与折叠标记一致) */
892
+ declare const MINDMAP_HANDLE_RADIUS = 9;
893
+ /** 「+」圆钮的命中半径(比视觉半径大一点,好点中) */
894
+ declare const MINDMAP_HANDLE_HIT_RADIUS = 12;
895
+ declare const MINDMAP_DIRECTIONS: MindMapDirection[];
896
+ type MindMapHandleKind = 'child' | 'sibling';
897
+ interface MindMapHandlePos {
898
+ kind: MindMapHandleKind;
899
+ /** 该加号对应的子节点生长方向(根节点 child 加号有效;非根节点 child 与节点自身方向一致) */
900
+ direction: MindMapDirection;
901
+ /** 导图局部坐标(与 layoutMindMap 的 positions 同系,相对导图中心) */
902
+ x: number;
903
+ /** 导图局部坐标 */
904
+ y: number;
905
+ }
906
+ interface MindMapNodePos {
907
+ x: number;
908
+ y: number;
909
+ depth: number;
910
+ width: number;
911
+ height: number;
912
+ /** 该节点在布局中的有效生长方向 */
913
+ direction: MindMapDirection;
914
+ }
915
+ interface MindMapLayoutResult {
916
+ positions: Map<string, MindMapNodePos>;
917
+ width: number;
918
+ height: number;
919
+ }
920
+ declare function isHorizontalDirection(d: MindMapDirection): boolean;
921
+ /** 子节点的有效方向:自己显式设置优先,否则继承父方向 */
922
+ declare function effectiveDirection(node: MindMapNode, parentDir?: MindMapDirection): MindMapDirection;
923
+ /** 节点颜色:手动设置优先,否则按层级取默认色 */
924
+ declare function mindMapNodeColor(node: MindMapNode, depth: number): string;
925
+ /** 节点框尺寸:由文本长度决定(CJK 按全宽估算),图标占位额外加宽 */
926
+ declare function mindMapNodeSize(node: MindMapNode): {
927
+ width: number;
928
+ height: number;
929
+ };
930
+ /** 深拷贝节点树(撤销/重做快照用) */
931
+ declare function cloneMindMapNode(node: MindMapNode): MindMapNode;
932
+ declare function findMindMapNode(root: MindMapNode, nodeId: string): MindMapNode | null;
933
+ declare function getMindMapNodeDepth(root: MindMapNode, nodeId: string): number;
934
+ declare function getMindMapParent(root: MindMapNode, nodeId: string): MindMapNode | null;
935
+ declare function countMindMapNodes(root: MindMapNode): number;
936
+ /**
937
+ * 四方向树布局:根节点在中心,子节点可向 right/left/up/down 四个方向展开。
938
+ * 每个子节点继承所在分支的方向;同方向节点按顺序垂直/水平排列。
939
+ * 返回以内容包围盒中心为原点的局部坐标(shape.x/y 即该中心)。
940
+ */
941
+ declare function layoutMindMap(root: MindMapNode): MindMapLayoutResult;
942
+ /**
943
+ * 活动节点上的「+」快捷按钮位置(导图局部坐标;绘制与命中检测共用这一份规则)。
944
+ *
945
+ * - 根节点:四个方向各一个 child 加号;
946
+ * - 非根节点:一个 child 加号(沿自身生长方向),一个 sibling 加号(水平节点在下方、垂直节点在右方)。
947
+ */
948
+ declare function mindMapNodeHandles(root: MindMapNode, nodeId: string): MindMapHandlePos[];
949
+ /**
950
+ * 在一份**已算好的布局**上找「+」按钮(局部坐标):整棵树只走一遍,
951
+ * 避免「每个节点各算一次布局」的 O(N²)。命中检测走这个,绘制走 mindMapNodeHandles。
952
+ */
953
+ declare function mindMapHandleAtLocalPoint(root: MindMapNode, positions: Map<string, MindMapNodePos>, lx: number, ly: number): {
954
+ nodeId: string;
955
+ kind: MindMapHandleKind;
956
+ direction: MindMapDirection;
957
+ } | null;
958
+ /**
959
+ * 获取节点在父节点同方向兄弟列表中的信息。
960
+ * 根节点的子节点按 direction 分组;普通节点的子节点全部继承父方向。
961
+ */
962
+ declare function getMindMapNodeSiblings(root: MindMapNode, nodeId: string): {
963
+ parent: MindMapNode;
964
+ siblings: MindMapNode[];
965
+ index: number;
966
+ direction: MindMapDirection;
967
+ } | null;
968
+ /**
969
+ * 将指定节点在其同方向兄弟列表中移动到新的索引位置。
970
+ * newIndex 是相对于同 direction siblings 的索引。
971
+ */
972
+ declare function reorderMindMapNodeInTree(root: MindMapNode, nodeId: string, newIndex: number): MindMapNode;
973
+ /**
974
+ * 把节点「升级」levels 层:把 node 重新挂到它第 levels 层祖先之下,并紧挨着
975
+ * 它原来的直接祖先(即第 levels 层祖先的子节点)之后。
976
+ *
977
+ * - 升 1 层:node 成为「父节点的兄弟」(新父 = 祖父);
978
+ * - 升 2 层:node 成为「祖父节点的兄弟」(新父 = 曾祖父);
979
+ * - ……依此类推。
980
+ *
981
+ * 节点自身的子树(children)整体跟着一起上移,不会被拆散。
982
+ * 可行性由调用方判断:node 的 depth 必须 ≥ levels + 1(至少要有一个「新父」)。
983
+ * 不满足条件时原样返回 root(不改动)。
984
+ */
985
+ declare function promoteMindMapNodeInTree(root: MindMapNode, nodeId: string, levels: number): MindMapNode;
986
+ /**
987
+ * 把节点「转移」到另一个父节点下,落在同方向兄弟组的 insertIndex 处。
988
+ * 用于拖拽换层级:把节点拖到某个节点上 → 成为该节点的兄弟。
989
+ *
990
+ * - 子树整体跟随,不被拆散;
991
+ * - 目标父节点落在被移动节点自身子树内(或就是它自己)时,原样返回,避免把树拆坏;
992
+ * - 目标父节点是根节点时,把节点 direction 设为目标兄弟组的方向(否则会被分到错误方向组);
993
+ * 目标是普通节点时清掉显式 direction,改为跟随新父节点的方向。
994
+ */
995
+ declare function moveMindMapNodeInTree(root: MindMapNode, nodeId: string, targetParentId: string, direction: MindMapDirection, insertIndex: number): MindMapNode;
996
+
849
997
  type Listener$1 = () => void;
850
998
  type NotificationListener = (message: string) => void;
851
999
  /** 核心 → React 的 UI 指令事件 */
@@ -861,6 +1009,11 @@ type UiEvent = {
861
1009
  | {
862
1010
  kind: 'imageError';
863
1011
  message: string;
1012
+ }
1013
+ /** 正在拖拽/调整图形(移动/缩放/旋转/拖连线端点或线段/从锚点拉新连线):React 侧据此临时隐藏顶栏工具条 */
1014
+ | {
1015
+ kind: 'drag';
1016
+ active: boolean;
864
1017
  };
865
1018
  /** Editor 构造选项:主题色 / 语言 / 初始数据 / 本地持久化开关 */
866
1019
  interface EditorOptions {
@@ -895,6 +1048,8 @@ declare class Editor {
895
1048
  private isPanning;
896
1049
  private panStart;
897
1050
  private dragStartPositions;
1051
+ /** 是否正处于「拖拽/调整图形」交互中:通过 UiEvent 'drag' 通知 React 临时隐藏顶栏工具条 */
1052
+ private interactionDragging;
898
1053
  private lastClickTime;
899
1054
  private lastClickShapeId;
900
1055
  private editingShapeId;
@@ -915,6 +1070,27 @@ declare class Editor {
915
1070
  private mindMapEditingShapeId;
916
1071
  private mindMapSelectedNode;
917
1072
  private mindMapHoverNode;
1073
+ /** 按下的节点「+」快捷按钮(抬手时若仍在同一按钮上才新建节点) */
1074
+ private pendingMindMapHandle;
1075
+ /**
1076
+ * 按在某个思维导图节点上的拖拽候选:移动超过阈值即开始「同方向重排序」。
1077
+ * 新交互下节点位置由布局决定,拖拽只改变同 direction 兄弟的排列顺序。
1078
+ */
1079
+ private mindMapNodeDragCandidate;
1080
+ /** 是否已进入「拖动节点」状态(超过阈值后才算,避免单击误触发) */
1081
+ private isNodeDragging;
1082
+ /**
1083
+ * 重排序时的目标插入索引(相对于同 direction siblings);null 表示未确定。
1084
+ * siblingIds 已按 cross 坐标排好序,方便 Renderer 直接画插入指示线。
1085
+ */
1086
+ private mindMapReorderTarget;
1087
+ /**
1088
+ * 拖拽「换层级」计划。两种落点:
1089
+ * - `sibling`:拖到目标节点的**外侧**(框外 48px 内)→ 成为该节点的同方向兄弟(targetParent = 目标节点的父节点);
1090
+ * - `child`:拖到目标节点的**框内** → 成为该节点的子节点(targetParent = 目标节点自身)。
1091
+ * 与 mindMapReorderTarget 的区别:那个是「同父级内重排序」,这个是「换父级(换层级)」。
1092
+ */
1093
+ private mindMapReparentPlan;
918
1094
  private tableSelection;
919
1095
  private tableEditing;
920
1096
  private renderScheduled;
@@ -1072,7 +1248,7 @@ declare class Editor {
1072
1248
  /**
1073
1249
  * 创建"新图形 + 连线":在 to 处放置指定类型图形;若提供了 existingArrowId,
1074
1250
  * 则把那条(已存在的浮动)线条末端接到新图形,否则新建一条连线。
1075
- * 新图形样式继承源图形(若有)。
1251
+ * 新图形样式继承源图形(若有),**同型时尺寸也继承**(见 sourceSize)。
1076
1252
  */
1077
1253
  createGeneratedConnection(context: GenerationContext, options: {
1078
1254
  type: ShapeType;
@@ -1082,6 +1258,8 @@ declare class Editor {
1082
1258
  connectToExisting(context: GenerationContext, targetShapeId: string, binding?: ArrowBinding): void;
1083
1259
  subscribeUi(listener: (payload: UiEvent) => void): () => boolean;
1084
1260
  private emitUi;
1261
+ /** 同步「是否正在拖拽图形」状态:仅在实际变化时发出 UiEvent,避免每帧轰炸订阅者 */
1262
+ private setInteractionDragging;
1085
1263
  /** 批量更新选中图形的样式(边框色、填充色等),提交历史记录 */
1086
1264
  updateSelectedShapesStyle(updates: Partial<ShapeStyle>): void;
1087
1265
  /** 批量更新选中图形的文字颜色/高亮背景色/高亮透明度,提交历史记录 */
@@ -1223,6 +1401,19 @@ declare class Editor {
1223
1401
  getSelectedUml(): UmlClassShape | UmlInterfaceShape | null;
1224
1402
  /** 按 id 查找 UML(类图或接口) */
1225
1403
  private getUmlById;
1404
+ /** 页面坐标 → 思维导图局部坐标(逆旋转 + 平移) */
1405
+ private pageToMindMapLocal;
1406
+ /** 计算拖拽节点时,在其同方向兄弟列表中的目标插入索引 */
1407
+ private calcMindMapReorderTarget;
1408
+ /**
1409
+ * 结构变化后补偿导图中心的位移,让**根节点在屏幕上不动**。
1410
+ *
1411
+ * 背景:`layoutMindMap` 末尾会把包围盒中心对齐到导图中心,所以树一变宽/变高,
1412
+ * 所有节点都会整体平移 —— 换层级/增删节点时看起来就是「整张图跳了一下」。
1413
+ * 这里按根节点在旧/新布局中的局部坐标差反向平移导图中心,于是只有受影响的
1414
+ * 子树重排,画面不会整体滑走(XMind 等也是这样,居中主题是视觉锚点)。
1415
+ */
1416
+ private anchorMindMapAtRoot;
1226
1417
  /** 获取选中的思维导图(恰好选中一个时) */
1227
1418
  getSelectedMindMap(): MindMapShape | null;
1228
1419
  /** 页面坐标下的思维导图节点命中:返回所在导图与节点 id */
@@ -1235,7 +1426,28 @@ declare class Editor {
1235
1426
  shapeId: string;
1236
1427
  nodeId: string;
1237
1428
  } | null;
1238
- /** 光标语义命中:仅节点框或折叠/展开标记内才命中(节点间空档不命中,避免空白处误显小手) */
1429
+ /** 精确节点框命中:仅当页面坐标落在某个节点框内才返回该节点,导图空白/间隙返回 null
1430
+ * (区别于 getMindMapNodeAtPoint 的「落在包围盒内就回退根节点」,用于节点拖拽判定) */
1431
+ getMindMapNodeBoxAtPoint(point: Vec2): {
1432
+ shapeId: string;
1433
+ nodeId: string;
1434
+ } | null;
1435
+ /**
1436
+ * 导图局部坐标下命中「某个节点框」的节点 id(拖拽换层级用)。
1437
+ * 排除 excludeNodeId 及其整棵子树 —— 否则会出现「把节点拖进自己的子树」这种非法落点。
1438
+ */
1439
+ private hitMindMapNodeBox;
1440
+ /**
1441
+ * 「成为子节点」落点:目标节点 targetId 的子节点组信息。
1442
+ * - `direction`:该组子节点的生长方向(目标非根 = 布局算出的目标方向;目标是根 = 取 cross 上离指针最近的方向组);
1443
+ * - `childIds`:已有的同方向子节点 id(为空表示新节点会成为第一个孩子)。
1444
+ */
1445
+ private mindMapChildGroup;
1446
+ /** 按 cross 坐标给同方向兄弟排序(Renderer 画落点占位框时要求同源顺序) */
1447
+ private mindMapSortByCross;
1448
+ /** 落点指示只在「真的变了」时更新(避免每帧 scheduleRender 抖动) */
1449
+ private setReorderIndicator;
1450
+ /** 光标语义命中:仅节点框(含「+」快捷按钮、折叠/展开标记)内才命中,节点间空档不命中 */
1239
1451
  getMindMapCursorHitAtPoint(point: Vec2): {
1240
1452
  shapeId: string;
1241
1453
  nodeId: string;
@@ -1263,21 +1475,61 @@ declare class Editor {
1263
1475
  shapeId: string;
1264
1476
  nodeId: string;
1265
1477
  } | null;
1478
+ /** 页面坐标下「+」快捷新建按钮的命中检测(子节点 / 同级节点) */
1479
+ getMindMapHandleAtPoint(point: Vec2): {
1480
+ shapeId: string;
1481
+ nodeId: string;
1482
+ kind: MindMapHandleKind;
1483
+ direction: MindMapDirection;
1484
+ } | null;
1485
+ /**
1486
+ * 点「+」快捷按钮:新建子/同级节点并把新节点作为活动节点。
1487
+ * 新需求:点击加号**不进入就地文本编辑**,只添加节点。
1488
+ */
1489
+ private addMindMapNodeFromHandle;
1266
1490
  /** 进入思维导图编辑态(双击节点触发):选中导图并定位到节点 */
1267
1491
  beginMindMapEdit(shapeId: string, nodeId: string | null): void;
1268
- /** 退出思维导图编辑态 */
1492
+ /**
1493
+ * 退出思维导图就地文本编辑(输入框收起)。
1494
+ * **活动节点保留**:导图仍被选中时,「+」快捷按钮继续挂在那个节点上,
1495
+ * 方便连续加节点;导图取消选中时由 render 里的钩子把活动节点一并清掉。
1496
+ */
1269
1497
  exitMindMapEdit(): void;
1270
1498
  /** 更新思维导图某节点(文本/颜色/图标/说明等),自动重算布局尺寸。
1271
1499
  * commit=false 时仅应用变更、不写历史(就地文本编辑逐键调用用);首个变更传入 commit=true 形成单个撤销点。 */
1272
1500
  updateMindMapNode(shapeId: string, nodeId: string, patch: Partial<MindMapNode>, commit?: boolean): void;
1273
- /** 给指定节点添加一个子节点 */
1274
- addMindMapChild(shapeId: string, nodeId: string): void;
1275
- /** 给指定节点添加一个兄弟节点(根节点无兄弟) */
1501
+ /** 设置思维导图某节点的手动偏移(拖拽用):连子树一起平移;不写历史(调用方在拖拽开始时 commitHistory 一次) */
1502
+ setMindMapNodeOffset(shapeId: string, nodeId: string, offset: {
1503
+ dx: number;
1504
+ dy: number;
1505
+ }): void;
1506
+ /**
1507
+ * 给指定节点添加一个子节点。
1508
+ * - 根节点:必须传入 direction,决定新子节点生长在哪个方向;
1509
+ * - 非根节点:direction 缺省则继承该节点自身方向。
1510
+ */
1511
+ addMindMapChild(shapeId: string, nodeId: string, direction?: MindMapDirection): void;
1512
+ /** 给指定节点添加一个兄弟节点(根节点无兄弟);兄弟继承该节点方向 */
1276
1513
  addMindMapSibling(shapeId: string, nodeId: string): void;
1514
+ /** 将节点在其同方向兄弟列表中移动到目标索引 */
1515
+ reorderMindMapNode(shapeId: string, nodeId: string, targetIndex: number): void;
1516
+ /**
1517
+ * 拖拽换层级:把节点移到目标父节点下、同方向兄弟组的 insertIndex 处。
1518
+ * 「拖到某个节点框上」= 成为该节点的同方向兄弟(即 targetParent = 该节点的父节点)。
1519
+ * 非法落点(目标是自己或自己的后代替)不修改文档。
1520
+ */
1521
+ moveMindMapNodeToParent(shapeId: string, nodeId: string, targetParentId: string, direction: MindMapDirection, insertIndex: number): void;
1277
1522
  /** 删除指定节点(含子树);删除根节点则移除整个思维导图 */
1278
1523
  deleteMindMapNode(shapeId: string, nodeId: string): void;
1279
1524
  /** 折叠/展开指定节点 */
1280
1525
  toggleMindMapCollapse(shapeId: string, nodeId: string): void;
1526
+ /** 节点能否「升级」levels 层:depth 必须 ≥ levels + 1(至少得有个新父节点)。根节点不可升级。 */
1527
+ canPromoteMindMapNode(shapeId: string, nodeId: string, levels: number): boolean;
1528
+ /**
1529
+ * 把节点升级 levels 层(升 1 层 = 成为父节点的兄弟;升 2 层 = 成为祖父节点的兄弟)。
1530
+ * 节点自身子树整体上移,不被拆散。不可升级时(已到顶层)直接返回,不改动文档。
1531
+ */
1532
+ promoteMindMapNode(shapeId: string, nodeId: string, levels: number): void;
1281
1533
  /** 获取选中的表格(恰好选中一个时) */
1282
1534
  getSelectedTable(): TableShape | null;
1283
1535
  private getTableById;
@@ -1664,6 +1916,14 @@ declare class Renderer {
1664
1916
  } | null, mindMapHover?: {
1665
1917
  shapeId: string;
1666
1918
  nodeId: string;
1919
+ } | null, mindMapReorderTarget?: {
1920
+ shapeId: string;
1921
+ nodeId: string;
1922
+ targetIndex: number;
1923
+ direction: MindMapDirection;
1924
+ siblingIds: string[];
1925
+ /** 「成为子节点」模式:目标节点 id(高亮它 + 子组为空时定位占位框) */
1926
+ childParentId?: string;
1667
1927
  } | null,
1668
1928
  /** 导出用:非 null 时先以该颜色铺满整块画布(白底等),默认不铺(透明) */
1669
1929
  background?: string | null,
@@ -1747,6 +2007,17 @@ declare class Renderer {
1747
2007
  private drawMindMap;
1748
2008
  private drawMindMapConnections;
1749
2009
  private drawMindMapNodes;
2010
+ /**
2011
+ * 节点拖拽重排序时的「落点占位」预览。
2012
+ * 不再只画一条小线,而是在松手后会插入的位置画一个与节点等大的虚线圆角框:
2013
+ * 内边与同方向兄弟对齐、按 CROSS_GAP 让出缝隙,一眼能看出节点会落到哪里。
2014
+ */
2015
+ private drawMindMapReorderIndicator;
2016
+ /**
2017
+ * 节点上的「+」快捷按钮:实心主色圆 + 白色加号,外圈再套一圈白环,
2018
+ * 让它压在连线上也能被看清楚。位置来自 mindMapNodeHandles(与命中检测同源)。
2019
+ */
2020
+ private drawMindMapHandles;
1750
2021
  /** 按像素宽度截断文本并加省略号 */
1751
2022
  private ellipsizeText;
1752
2023
  /**
@@ -2246,6 +2517,11 @@ declare abstract class Tool {
2246
2517
  * @returns 是否确实清理了状态(false = 本来就是空闲态,调用方可跳过重绘)
2247
2518
  */
2248
2519
  cancelTransient(): boolean;
2520
+ /**
2521
+ * 是否正处于「拖拽/调整图形」中(移动/缩放/旋转图形、拖连线端点或线段、从锚点拉新连线)。
2522
+ * 默认 false;选择工具等会覆盖,供编辑器据此临时隐藏顶栏工具条。
2523
+ */
2524
+ isDragging(): boolean;
2249
2525
  dispose(): void;
2250
2526
  }
2251
2527
 
@@ -2340,6 +2616,11 @@ declare class SelectTool extends Tool {
2340
2616
  */
2341
2617
  private finishSegmentDrag;
2342
2618
  hasTransientState(): boolean;
2619
+ /**
2620
+ * 拖拽/调整图形中:移动、缩放、旋转、拖连线端点、拖线段、从锚点拉新连线。
2621
+ * (框选空白、表格内框选单元格不算「拖图形」,不触发顶栏隐藏。)
2622
+ */
2623
+ isDragging(): boolean;
2343
2624
  /**
2344
2625
  * 取消一切瞬态交互(拖拽/生成/框选/旋转/连线端点拖拽)并清掉画布上的瞬态预览。
2345
2626
  * 触发场景:指针在窗口外松手丢失 pointerup、窗口失焦、点击画布外、无按压的移动、
@@ -2378,6 +2659,12 @@ declare class SelectTool extends Tool {
2378
2659
  /** 生成点位命中阈值 / 单击 vs 拖动判定阈值 */
2379
2660
  private static readonly GEN_HIT_THRESHOLD;
2380
2661
  private static readonly CLICK_MOVE_THRESHOLD;
2662
+ /**
2663
+ * 「点击锚点生成图形」时源图形与新图形之间的默认间距(页面单位,**边到边**)。
2664
+ * 旧实现是「中心沿法线外移 96」:对默认矩形(120×60)实际边距只有 36,看着太挤;
2665
+ * 现在直接按边距算,取 36 + 40 = 76(用户要求 +40px),且不再随图形大小变化。
2666
+ */
2667
+ private static readonly GEN_GAP;
2381
2668
  /** 支持四边连接锚点的图形类型(矩形类、流程图形、UML 等) */
2382
2669
  private static readonly GEN_SUPPORTED_TYPES;
2383
2670
  /**
@@ -2389,8 +2676,18 @@ declare class SelectTool extends Tool {
2389
2676
  private hitGenPoint;
2390
2677
  /** 悬停(未按下)时指针所在的、支持连线锚点的图形 id(已选中的交给选择手柄,返回 null) */
2391
2678
  private findHoverAnchorShape;
2392
- /** 生成点位预览的落点:拖动时跟随光标;静止/悬浮时向外延伸一个默认位置的框 */
2679
+ /**
2680
+ * 生成点位预览的落点:拖动时跟随光标;静止/悬浮时沿出线方向外移
2681
+ * 「默认间距 GEN_GAP + 新图形在该方向上的半个尺寸」,即**两个图形边到边**留出 GEN_GAP。
2682
+ */
2393
2683
  private genPreviewTarget;
2684
+ /**
2685
+ * 「将要新建的图形」本体(预览虚框 / 避让 / 接入点计算共用):
2686
+ * 尺寸与最终 createGeneratedConnection 创建出来的完全一致(同型时沿用源图形尺寸)。
2687
+ */
2688
+ private genGhostShape;
2689
+ /** 「将要新建的图形」的尺寸(页面单位) */
2690
+ private genGhostSize;
2394
2691
  /** 生成拖动:更新预览(真实样式的连线 + 待放置图形虚框)与目标高亮 */
2395
2692
  private handleGenerating;
2396
2693
  private handleRotating;
@@ -2595,44 +2892,6 @@ declare class ArrowTool extends Tool {
2595
2892
  private getCircleBindingPosition;
2596
2893
  }
2597
2894
 
2598
- /** 不同层级节点的默认颜色,超过 6 层后循环复用 */
2599
- declare const MINDMAP_COLORS: string[];
2600
- declare const MINDMAP_FONT_SIZE = 14;
2601
- declare const MINDMAP_NODE_HEIGHT = 40;
2602
- declare const MINDMAP_MIN_WIDTH = 80;
2603
- declare const MINDMAP_MAX_WIDTH = 240;
2604
- interface MindMapNodePos {
2605
- x: number;
2606
- y: number;
2607
- depth: number;
2608
- width: number;
2609
- height: number;
2610
- }
2611
- interface MindMapLayoutResult {
2612
- positions: Map<string, MindMapNodePos>;
2613
- width: number;
2614
- height: number;
2615
- }
2616
- /** 节点颜色:手动设置优先,否则按层级取默认色 */
2617
- declare function mindMapNodeColor(node: MindMapNode, depth: number): string;
2618
- /** 节点框尺寸:由文本长度决定(CJK 按全宽估算),图标占位额外加宽 */
2619
- declare function mindMapNodeSize(node: MindMapNode): {
2620
- width: number;
2621
- height: number;
2622
- };
2623
- /** 深拷贝节点树(撤销/重做快照用) */
2624
- declare function cloneMindMapNode(node: MindMapNode): MindMapNode;
2625
- declare function findMindMapNode(root: MindMapNode, nodeId: string): MindMapNode | null;
2626
- declare function getMindMapNodeDepth(root: MindMapNode, nodeId: string): number;
2627
- declare function getMindMapParent(root: MindMapNode, nodeId: string): MindMapNode | null;
2628
- declare function countMindMapNodes(root: MindMapNode): number;
2629
- /**
2630
- * 横向树布局:根在左,子节点向右展开,每个节点垂直居中于其子树。
2631
- * 返回以内容包围盒中心为原点的局部坐标(shape.x/y 即该中心),
2632
- * 便于复用现有选中框/旋转/命中检测逻辑。
2633
- */
2634
- declare function layoutMindMap(root: MindMapNode): MindMapLayoutResult;
2635
-
2636
2895
  /**
2637
2896
  * 表格的纯数据操作(唯一实现):行列增删、合并/拆分、命中定位。
2638
2897
  *
@@ -2839,4 +3098,4 @@ declare function imageDataUrl(src: string): string | null;
2839
3098
  /** 清空缓存(测试/卸载时用;会释放自己创建的 blob 地址) */
2840
3099
  declare function clearImageCache(): void;
2841
3100
 
2842
- export { type ArrowBinding, type ArrowHeadType, type ArrowShape, type ArrowStyle, ArrowTool, BoardExtentKeeper, type BoardExtentResult, type BoardExtentUpdate, Camera, type CameraState, type CircleShape, type ConnectionType, DEFAULT_HIGHLIGHTER_COLOR, DEFAULT_IMAGE_MAX_SIZE_BYTES, type DiamondShape, type DrawShape, type DrawuiTheme, type DrawuiThemeSelection, Editor, type EditorData, type EditorOptions, type EditorState, type EllipseShape, type ExportFormat, type ExportOptions, type FreehandMode, FreehandTool, type GenerationContext, HandTool, type HexagonShape, ICONS, ICON_CATEGORIES, ICON_CATEGORY_INK, ICON_DEFAULT_INK, ICON_DEFAULT_SIZE, ICON_GRID, type IconCategoryId, type IconDef, type IconLayer, type IconShape, type ImageShape, type ImageUploadConfig, type ImageUploadOption, type ImageUploader, LANGUAGES, type Language, type LineShape, LineTool, MINDMAP_COLORS, MINDMAP_FONT_SIZE, MINDMAP_MAX_WIDTH, MINDMAP_MIN_WIDTH, MINDMAP_NODE_HEIGHT, MIN_HANDLE_SEGMENT, MIN_JOG, Mat2d, type MessageKey, type MindMapLayoutResult, type MindMapNode, type MindMapNodePos, type MindMapShape, type OctagonShape, type ParallelogramShape, type PentagonShape, type Rect, type RectangleShape, Renderer, type RoundedRectangleShape, STICKY_FOLD_RATIO, STICKY_NOTE_COLORS, STICKY_NOTE_DEFAULT_COLOR, STICKY_TEXT_SCALE, type SegmentHandle, SelectTool, type Shape, type ShapeStyle, ShapeTool, type ShapeType, type SnapGuide, type StarShape, type StickyNoteShape, TABLE_CELL_PADDING_X, TABLE_CELL_PADDING_Y, TABLE_DEFAULT_COL_WIDTH, TABLE_DEFAULT_ROW_HEIGHT, TABLE_FONT_SIZE, TABLE_HEADER_FILL, TABLE_LINE_HEIGHT_RATIO, TABLE_MAX_AUTO_LINES, TABLE_MIN_COL_WIDTH, TABLE_MIN_ROW_HEIGHT, TABLE_MOVE_HANDLE_GAP, TABLE_MOVE_HANDLE_HEIGHT, TABLE_MOVE_HANDLE_WIDTH, THEME, type TableCell, type TableShape, type TextShape, type ToolType, type TrapezoidShape, type TriangleShape, UML_FONT_SIZE, UML_HEADER_HEIGHT, UML_LINE_HEIGHT, UML_MIN_WIDTH, UML_PADDING_X, UML_PADDING_Y, type UiEvent, type UmlAttribute, type UmlClassShape, type UmlInterfaceShape, type UmlMethod, type UmlVisibility, Vec, type Vec2 as Vec2Type, addImageReadyListener, calcUmlClassSize, clearImageCache, cloneMindMapNode, cloneTable, cloneTableCells, collapseRoute, collectTemporaryImageSrcs, connectorSegmentHandles, countMindMapNodes, createTableCells, downloadBlob, ensureImagesLoaded, exportToBlob, findMindMapNode, getContentBounds, getIcon, getLanguage, getMindMapNodeDepth, getMindMapParent, getTheme, hasIcon, hexToRgba, hitTableBody, hitTableMoveHandle, iconInk, iconsByCategory, imageDataUrl, isEmptyRect, isFlippableShapeType, isImageFailed, isImageLoading, isStubCorner, isUploaderFunction, layoutMindMap, loadImage, mindMapNodeColor, mindMapNodeSize, offsetConnectorSegment, parseUploadResponse, peekImage, pickSegmentHandle, pointToSegmentDistance, pruneStubBends, rectsIntersect, renderSVGString, renderToCanvas, routeToUserPoints, sameRoute, searchIcons, setImageCrossOrigin, setLanguage, setTheme, shadeColor, subscribeLanguage, subscribeTheme, subtractUnion, t, tableAnchorAt, tableCellAtLocalClamped, tableCellLineCount, tableCellLocalRect, tableCellTextStartOffset, tableCoveredMap, tableDeleteColumn, tableDeleteRow, tableExpandRangeToMerges, tableGrowRowHeights, tableInsertColumn, tableInsertRow, tableLocalPoint, tableMerge, tableMoveHandleLocalRect, tablePagePoint, tableRangeHasMerge, tableRangeLocalRect, tableRowAtPoint, tableSplit, tableSplitRange, tableTotalHeight, tableTotalWidth, umlAttrRowText, umlMethodRowText, unionRect, uploadImageViaConfig };
3101
+ export { type ArrowBinding, type ArrowHeadType, type ArrowShape, type ArrowStyle, ArrowTool, BoardExtentKeeper, type BoardExtentResult, type BoardExtentUpdate, Camera, type CameraState, type CircleShape, type ConnectionType, DEFAULT_HIGHLIGHTER_COLOR, DEFAULT_IMAGE_MAX_SIZE_BYTES, DEFAULT_PAGE_THEME, type DiamondShape, type DrawShape, type DrawuiTheme, type DrawuiThemeSelection, Editor, type EditorData, type EditorOptions, type EditorState, type EllipseShape, type ExportFormat, type ExportOptions, type FreehandMode, FreehandTool, type GenerationContext, HandTool, type HexagonShape, ICONS, ICON_CATEGORIES, ICON_CATEGORY_INK, ICON_DEFAULT_INK, ICON_DEFAULT_SIZE, ICON_GRID, type IconCategoryId, type IconDef, type IconLayer, type IconShape, type ImageShape, type ImageUploadConfig, type ImageUploadOption, type ImageUploader, LANGUAGES, type Language, type LineShape, LineTool, MINDMAP_COLORS, MINDMAP_DIRECTIONS, MINDMAP_FONT_SIZE, MINDMAP_HANDLE_HIT_RADIUS, MINDMAP_HANDLE_RADIUS, MINDMAP_MAX_WIDTH, MINDMAP_MIN_WIDTH, MINDMAP_NODE_HEIGHT, MIN_HANDLE_SEGMENT, MIN_JOG, Mat2d, type MessageKey, type MindMapDirection, type MindMapHandleKind, type MindMapHandlePos, type MindMapLayoutResult, type MindMapNode, type MindMapNodePos, type MindMapShape, type OctagonShape, PAGE_THEMES, type PageTheme, type PageThemePreset, type ParallelogramShape, type PentagonShape, type Rect, type RectangleShape, Renderer, type RoundedRectangleShape, STICKY_FOLD_RATIO, STICKY_NOTE_COLORS, STICKY_NOTE_DEFAULT_COLOR, STICKY_TEXT_SCALE, type SegmentHandle, SelectTool, type Shape, type ShapeStyle, ShapeTool, type ShapeType, type SnapGuide, type StarShape, type StickyNoteShape, TABLE_CELL_PADDING_X, TABLE_CELL_PADDING_Y, TABLE_DEFAULT_COL_WIDTH, TABLE_DEFAULT_ROW_HEIGHT, TABLE_FONT_SIZE, TABLE_HEADER_FILL, TABLE_LINE_HEIGHT_RATIO, TABLE_MAX_AUTO_LINES, TABLE_MIN_COL_WIDTH, TABLE_MIN_ROW_HEIGHT, TABLE_MOVE_HANDLE_GAP, TABLE_MOVE_HANDLE_HEIGHT, TABLE_MOVE_HANDLE_WIDTH, THEME, type TableCell, type TableShape, type TextShape, type ToolType, type TrapezoidShape, type TriangleShape, UML_FONT_SIZE, UML_HEADER_HEIGHT, UML_LINE_HEIGHT, UML_MIN_WIDTH, UML_PADDING_X, UML_PADDING_Y, type UiEvent, type UmlAttribute, type UmlClassShape, type UmlInterfaceShape, type UmlMethod, type UmlVisibility, Vec, type Vec2 as Vec2Type, addImageReadyListener, calcUmlClassSize, clearImageCache, cloneMindMapNode, cloneTable, cloneTableCells, collapseRoute, collectTemporaryImageSrcs, connectorSegmentHandles, countMindMapNodes, createTableCells, downloadBlob, effectiveDirection, ensureImagesLoaded, exportToBlob, findMindMapNode, getContentBounds, getIcon, getLanguage, getMindMapNodeDepth, getMindMapNodeSiblings, getMindMapParent, getTheme, hasIcon, hexToRgba, hitTableBody, hitTableMoveHandle, iconInk, iconsByCategory, imageDataUrl, isEmptyRect, isFlippableShapeType, isHorizontalDirection, isImageFailed, isImageLoading, isStubCorner, isUploaderFunction, layoutMindMap, loadImage, mindMapHandleAtLocalPoint, mindMapNodeColor, mindMapNodeHandles, mindMapNodeSize, moveMindMapNodeInTree, offsetConnectorSegment, parseUploadResponse, peekImage, pickSegmentHandle, pointToSegmentDistance, promoteMindMapNodeInTree, pruneStubBends, rectsIntersect, renderSVGString, renderToCanvas, reorderMindMapNodeInTree, routeToUserPoints, sameRoute, searchIcons, setImageCrossOrigin, setLanguage, setTheme, shadeColor, subscribeLanguage, subscribeTheme, subtractUnion, t, tableAnchorAt, tableCellAtLocalClamped, tableCellLineCount, tableCellLocalRect, tableCellTextStartOffset, tableCoveredMap, tableDeleteColumn, tableDeleteRow, tableExpandRangeToMerges, tableGrowRowHeights, tableInsertColumn, tableInsertRow, tableLocalPoint, tableMerge, tableMoveHandleLocalRect, tablePagePoint, tableRangeHasMerge, tableRangeLocalRect, tableRowAtPoint, tableSplit, tableSplitRange, tableTotalHeight, tableTotalWidth, umlAttrRowText, umlMethodRowText, unionRect, uploadImageViaConfig };