drawui-core 0.1.0 → 0.2.0

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.ts CHANGED
@@ -14,7 +14,7 @@ interface ShapeStyle {
14
14
  strokeWidth: number;
15
15
  strokeDash: number[] | null;
16
16
  }
17
- type ShapeType = 'rectangle' | 'rounded-rectangle' | 'circle' | 'ellipse' | 'diamond' | 'triangle' | 'hexagon' | 'parallelogram' | 'trapezoid' | 'pentagon' | 'octagon' | 'star' | 'uml-class' | 'uml-interface' | 'line' | 'arrow' | 'text' | 'draw';
17
+ type ShapeType = 'rectangle' | 'rounded-rectangle' | 'circle' | 'ellipse' | 'diamond' | 'triangle' | 'hexagon' | 'parallelogram' | 'trapezoid' | 'pentagon' | 'octagon' | 'star' | 'uml-class' | 'uml-interface' | 'mind-map' | 'line' | 'arrow' | 'text' | 'draw';
18
18
  interface BaseShape {
19
19
  id: string;
20
20
  type: ShapeType;
@@ -181,8 +181,29 @@ interface DrawShape extends BaseShape {
181
181
  type: 'draw';
182
182
  points: Vec2[];
183
183
  }
184
- type Shape = RectangleShape | RoundedRectangleShape | CircleShape | EllipseShape | DiamondShape | TriangleShape | HexagonShape | ParallelogramShape | TrapezoidShape | PentagonShape | OctagonShape | StarShape | UmlClassShape | UmlInterfaceShape | LineShape | ArrowShape | TextShape | DrawShape;
185
- type ToolType = 'select' | 'hand' | 'rectangle' | 'rounded-rectangle' | 'circle' | 'ellipse' | 'diamond' | 'triangle' | 'hexagon' | 'parallelogram' | 'trapezoid' | 'pentagon' | 'octagon' | 'star' | 'uml-class' | 'uml-interface' | 'line' | 'arrow' | 'text' | 'draw' | 'pen' | 'highlighter';
184
+ /** 思维导图节点:可带子节点;颜色/图标/属性说明均可手动覆盖,默认取层级色 */
185
+ interface MindMapNode {
186
+ id: string;
187
+ text: string;
188
+ /** 手动覆盖的节点颜色;不设置时按层级取默认色 */
189
+ color?: string;
190
+ /** 左侧图标(任意短文本/emoji),默认无 */
191
+ icon?: string;
192
+ /** 左上角属性说明,默认无 */
193
+ note?: string;
194
+ /** 说明标签颜色,默认与节点颜色一致 */
195
+ noteColor?: string;
196
+ collapsed?: boolean;
197
+ children?: MindMapNode[];
198
+ }
199
+ interface MindMapShape extends BaseShape {
200
+ type: 'mind-map';
201
+ width: number;
202
+ height: number;
203
+ root: MindMapNode;
204
+ }
205
+ type Shape = RectangleShape | RoundedRectangleShape | CircleShape | EllipseShape | DiamondShape | TriangleShape | HexagonShape | ParallelogramShape | TrapezoidShape | PentagonShape | OctagonShape | StarShape | UmlClassShape | UmlInterfaceShape | LineShape | ArrowShape | TextShape | DrawShape | MindMapShape;
206
+ type ToolType = 'select' | 'hand' | 'rectangle' | 'rounded-rectangle' | 'circle' | 'ellipse' | 'diamond' | 'triangle' | 'hexagon' | 'parallelogram' | 'trapezoid' | 'pentagon' | 'octagon' | 'star' | 'uml-class' | 'uml-interface' | 'line' | 'arrow' | 'text' | 'draw' | 'pen' | 'highlighter' | 'eraser' | 'mind-map';
186
207
  interface CameraState {
187
208
  x: number;
188
209
  y: number;
@@ -194,6 +215,11 @@ interface EditorState {
194
215
  activeTool: ToolType;
195
216
  camera: CameraState;
196
217
  }
218
+ /** 对外对接数据:图形 + 相机(用于 data 初始化 / onChange 回调 / getData) */
219
+ interface EditorData {
220
+ shapes: Shape[];
221
+ camera: CameraState;
222
+ }
197
223
 
198
224
  interface Mat2d {
199
225
  a: number;
@@ -240,6 +266,301 @@ declare class Camera {
240
266
  }, padding?: number): void;
241
267
  }
242
268
 
269
+ /**
270
+ * 主题颜色常量 - 统一管理画布内渲染颜色
271
+ * 默认值在此定义;运行时通过 setTheme() 局部覆盖,修改后全局生效。
272
+ * React 侧主题色(CSS 变量 --dw-*)由 packages/react/src/theme.less 管理,
273
+ * CanvasBoard 的 themeColor 参数会同时写入两套主题源。
274
+ */
275
+ interface DrawuiThemeSelection {
276
+ /** 选中边框颜色 */
277
+ outline: string;
278
+ /** 选中控制点边框颜色 */
279
+ handleStroke: string;
280
+ /** 选中控制点填充颜色 */
281
+ handleFill: string;
282
+ /** 选中区域填充颜色 (半透明) */
283
+ outlineFill: string;
284
+ /** 选中阴影颜色 */
285
+ shadow: string;
286
+ }
287
+ interface DrawuiTheme {
288
+ /** 主题主色(手柄/生成点等强调色) */
289
+ primary: string;
290
+ /** 选中态 */
291
+ selection: DrawuiThemeSelection;
292
+ /** 网格颜色 */
293
+ grid: string;
294
+ /** 默认文字颜色 */
295
+ text: string;
296
+ /** 文本编辑框边框 */
297
+ editBorder: string;
298
+ /** 框选矩形填充/描边 */
299
+ brushFill: string;
300
+ brushStroke: string;
301
+ /** 对齐参考线(浅色虚线) */
302
+ guide: string;
303
+ /** 连线选中高亮辅助线 */
304
+ lineHighlight: string;
305
+ /** 生成点位预览:源点圆点/虚线线条 */
306
+ genDot: string;
307
+ genLine: string;
308
+ }
309
+ /** 主题对象(同一引用,渲染器直接读取;setTheme 就地覆盖字段) */
310
+ declare const THEME: DrawuiTheme;
311
+ type ThemeListener = () => void;
312
+ /** 订阅主题变化(如小地图等 canvas 组件需要据此重绘) */
313
+ declare function subscribeTheme(listener: ThemeListener): () => void;
314
+ /** 局部覆盖主题字段(selection 内字段单独合并) */
315
+ declare function setTheme(theme: Partial<DrawuiTheme>): void;
316
+ /** 获取当前主题(方便未来扩展为动态主题切换) */
317
+ declare function getTheme(): DrawuiTheme;
318
+ /** #rrggbb / #rgb → rgba(r, g, b, a);解析失败原样返回 */
319
+ declare function hexToRgba(hex: string, alpha: number): string;
320
+ /** 颜色变暗/变亮:percent 负数变暗、正数变亮 */
321
+ declare function shadeColor(hex: string, percent: number): string;
322
+
323
+ /**
324
+ * 国际化:框架无关的轻量字典 + 语言切换。
325
+ * React 侧通过 useLanguage() 订阅语言变化自动重渲染。
326
+ */
327
+ type Language = 'zh-CN' | 'en-US';
328
+ declare const dictionaries: {
329
+ readonly 'zh-CN': {
330
+ readonly 'save.success': "已保存";
331
+ readonly 'save.fail': "保存失败";
332
+ readonly 'tool.select': "选择工具";
333
+ readonly 'tool.hand': "拖拽视口";
334
+ readonly 'tool.rectangle': "矩形";
335
+ readonly 'tool.rounded-rectangle': "圆角矩形";
336
+ readonly 'tool.circle': "圆形";
337
+ readonly 'tool.ellipse': "椭圆";
338
+ readonly 'tool.diamond': "菱形";
339
+ readonly 'tool.triangle': "三角形";
340
+ readonly 'tool.hexagon': "六边形";
341
+ readonly 'tool.parallelogram': "平行四边形";
342
+ readonly 'tool.trapezoid': "梯形";
343
+ readonly 'tool.pentagon': "五边形";
344
+ readonly 'tool.octagon': "八边形";
345
+ readonly 'tool.star': "星形";
346
+ readonly 'tool.uml-class': "UML 类图";
347
+ readonly 'tool.uml-interface': "UML 接口";
348
+ readonly 'tool.line': "直线";
349
+ readonly 'tool.arrow': "线条";
350
+ readonly 'tool.text': "文本";
351
+ readonly 'tool.draw': "画笔";
352
+ readonly 'tool.pen': "画笔";
353
+ readonly 'tool.highlighter': "荧光笔";
354
+ readonly 'tool.eraser': "橡皮擦";
355
+ readonly 'status.none': "未选择";
356
+ readonly 'status.selected': "已选择 {n} 个图形";
357
+ readonly 'toolbar.select': "选择 (V)";
358
+ readonly 'toolbar.hand': "拖拽视口 (H)";
359
+ readonly 'toolbar.shapes': "形状";
360
+ readonly 'toolbar.grid': "网格";
361
+ readonly 'toolbar.undo': "撤销 (Ctrl+Z)";
362
+ readonly 'toolbar.redo': "重做 (Ctrl+Shift+Z)";
363
+ readonly 'toolbar.arrow': "箭头";
364
+ readonly 'toolbar.text': "文本";
365
+ readonly 'toolbar.pen': "画笔";
366
+ readonly 'toolbar.highlighter': "荧光笔";
367
+ readonly 'toolbar.eraser': "橡皮擦";
368
+ readonly 'toolbar.uml-class': "UML 类图";
369
+ readonly 'toolbar.uml-interface': "UML 接口";
370
+ readonly 'zoom.in': "放大";
371
+ readonly 'zoom.out': "缩小";
372
+ readonly 'zoom.reset': "重置";
373
+ readonly 'style.stroke': "边框";
374
+ readonly 'style.fill': "填充";
375
+ readonly 'style.text': "文字";
376
+ readonly 'style.highlight': "高亮";
377
+ readonly 'style.none': "无";
378
+ readonly 'style.connection': "连线";
379
+ readonly 'style.arrow': "箭头";
380
+ readonly 'style.dashed': "虚线";
381
+ readonly 'style.solid': "实线";
382
+ readonly 'style.connection.straight': "直线";
383
+ readonly 'style.connection.polyline': "折线";
384
+ readonly 'style.connection.orthogonal': "直角折线";
385
+ readonly 'style.connection.curve': "曲线";
386
+ readonly 'style.arrowhead.none': "无箭头";
387
+ readonly 'style.arrowhead.end': "终点箭头";
388
+ readonly 'style.arrowhead.start': "起点箭头";
389
+ readonly 'style.arrowhead.both': "双箭头";
390
+ readonly 'style.arrowhead.inheritance': "继承";
391
+ readonly 'style.arrowhead.composition': "组合";
392
+ readonly 'style.arrowhead.aggregation': "聚合";
393
+ readonly 'menu.title': "选择新图形";
394
+ readonly 'menu.cancel': "点击空白处取消";
395
+ readonly 'shape.rectangle': "矩形";
396
+ readonly 'shape.rounded-rectangle': "圆角";
397
+ readonly 'shape.circle': "圆形";
398
+ readonly 'shape.ellipse': "椭圆";
399
+ readonly 'shape.diamond': "菱形";
400
+ readonly 'shape.triangle': "三角";
401
+ readonly 'shape.hexagon': "六边形";
402
+ readonly 'shape.parallelogram': "平行";
403
+ readonly 'shape.trapezoid': "梯形";
404
+ readonly 'shape.pentagon': "五边形";
405
+ readonly 'shape.octagon': "八边形";
406
+ readonly 'shape.star': "星形";
407
+ readonly 'shape.uml-class': "类图";
408
+ readonly 'shape.uml-interface': "接口";
409
+ readonly 'uml.drag': "拖拽排序";
410
+ readonly 'uml.delete': "删除该行";
411
+ readonly 'uml.textColor': "文字颜色";
412
+ readonly 'uml.defaultColor': "默认颜色";
413
+ readonly 'uml.fontSize': "字号";
414
+ readonly 'uml.strikethrough': "删除线";
415
+ readonly 'uml.attribute': "属性";
416
+ readonly 'uml.method': "方法";
417
+ readonly 'minimap.title': "小地图";
418
+ readonly 'minimap.expand': "展开小地图";
419
+ readonly 'minimap.collapse': "收起小地图";
420
+ readonly 'tool.mind-map': "思维导图";
421
+ readonly 'toolbar.mind-map': "思维导图";
422
+ readonly 'shape.mind-map': "思维导图";
423
+ readonly 'mindmap.defaultRoot': "中心主题";
424
+ readonly 'mindmap.defaultBranch': "分支主题";
425
+ readonly 'mindmap.nodeText': "节点文本";
426
+ readonly 'mindmap.addChild': "子节点";
427
+ readonly 'mindmap.addSibling': "兄弟节点";
428
+ readonly 'mindmap.deleteNode': "删除节点";
429
+ readonly 'mindmap.color': "颜色";
430
+ readonly 'mindmap.levelColor': "默认层级色";
431
+ readonly 'mindmap.icon': "图标";
432
+ readonly 'mindmap.noIcon': "无图标";
433
+ readonly 'mindmap.note': "属性说明";
434
+ readonly 'mindmap.notePlaceholder': "说明内容(可选)";
435
+ readonly 'mindmap.noteColor': "说明颜色";
436
+ readonly 'mindmap.noteColorDefault': "同节点色";
437
+ readonly 'mindmap.collapse': "折叠";
438
+ readonly 'mindmap.expand': "展开";
439
+ readonly 'mindmap.close': "关闭编辑";
440
+ readonly 'mindmap.more': "更多设置";
441
+ };
442
+ readonly 'en-US': {
443
+ readonly 'save.success': "Saved";
444
+ readonly 'save.fail': "Save failed";
445
+ readonly 'tool.select': "Select tool";
446
+ readonly 'tool.hand': "Pan view";
447
+ readonly 'tool.rectangle': "Rectangle";
448
+ readonly 'tool.rounded-rectangle': "Rounded rectangle";
449
+ readonly 'tool.circle': "Circle";
450
+ readonly 'tool.ellipse': "Ellipse";
451
+ readonly 'tool.diamond': "Diamond";
452
+ readonly 'tool.triangle': "Triangle";
453
+ readonly 'tool.hexagon': "Hexagon";
454
+ readonly 'tool.parallelogram': "Parallelogram";
455
+ readonly 'tool.trapezoid': "Trapezoid";
456
+ readonly 'tool.pentagon': "Pentagon";
457
+ readonly 'tool.octagon': "Octagon";
458
+ readonly 'tool.star': "Star";
459
+ readonly 'tool.uml-class': "UML class";
460
+ readonly 'tool.uml-interface': "UML interface";
461
+ readonly 'tool.line': "Line";
462
+ readonly 'tool.arrow': "Line";
463
+ readonly 'tool.text': "Text";
464
+ readonly 'tool.draw': "Pen";
465
+ readonly 'tool.pen': "Pen";
466
+ readonly 'tool.highlighter': "Highlighter";
467
+ readonly 'tool.eraser': "Eraser";
468
+ readonly 'status.none': "Nothing selected";
469
+ readonly 'status.selected': "{n} shapes selected";
470
+ readonly 'toolbar.select': "Select (V)";
471
+ readonly 'toolbar.hand': "Pan view (H)";
472
+ readonly 'toolbar.shapes': "Shapes";
473
+ readonly 'toolbar.grid': "Grid";
474
+ readonly 'toolbar.undo': "Undo (Ctrl+Z)";
475
+ readonly 'toolbar.redo': "Redo (Ctrl+Shift+Z)";
476
+ readonly 'toolbar.arrow': "Arrow";
477
+ readonly 'toolbar.text': "Text";
478
+ readonly 'toolbar.pen': "Pen";
479
+ readonly 'toolbar.highlighter': "Highlighter";
480
+ readonly 'toolbar.eraser': "Eraser";
481
+ readonly 'toolbar.uml-class': "UML class";
482
+ readonly 'toolbar.uml-interface': "UML interface";
483
+ readonly 'zoom.in': "Zoom in";
484
+ readonly 'zoom.out': "Zoom out";
485
+ readonly 'zoom.reset': "Reset";
486
+ readonly 'style.stroke': "Border";
487
+ readonly 'style.fill': "Fill";
488
+ readonly 'style.text': "Text";
489
+ readonly 'style.highlight': "Highlight";
490
+ readonly 'style.none': "None";
491
+ readonly 'style.connection': "Connection";
492
+ readonly 'style.arrow': "Arrow head";
493
+ readonly 'style.dashed': "Dashed";
494
+ readonly 'style.solid': "Solid";
495
+ readonly 'style.connection.straight': "Straight";
496
+ readonly 'style.connection.polyline': "Polyline";
497
+ readonly 'style.connection.orthogonal': "Orthogonal";
498
+ readonly 'style.connection.curve': "Curve";
499
+ readonly 'style.arrowhead.none': "None";
500
+ readonly 'style.arrowhead.end': "End";
501
+ readonly 'style.arrowhead.start': "Start";
502
+ readonly 'style.arrowhead.both': "Both";
503
+ readonly 'style.arrowhead.inheritance': "Inheritance";
504
+ readonly 'style.arrowhead.composition': "Composition";
505
+ readonly 'style.arrowhead.aggregation': "Aggregation";
506
+ readonly 'menu.title': "Create shape";
507
+ readonly 'menu.cancel': "Click empty space to cancel";
508
+ readonly 'shape.rectangle': "Rectangle";
509
+ readonly 'shape.rounded-rectangle': "Rounded";
510
+ readonly 'shape.circle': "Circle";
511
+ readonly 'shape.ellipse': "Ellipse";
512
+ readonly 'shape.diamond': "Diamond";
513
+ readonly 'shape.triangle': "Triangle";
514
+ readonly 'shape.hexagon': "Hexagon";
515
+ readonly 'shape.parallelogram': "Parallelogram";
516
+ readonly 'shape.trapezoid': "Trapezoid";
517
+ readonly 'shape.pentagon': "Pentagon";
518
+ readonly 'shape.octagon': "Octagon";
519
+ readonly 'shape.star': "Star";
520
+ readonly 'shape.uml-class': "Class";
521
+ readonly 'shape.uml-interface': "Interface";
522
+ readonly 'uml.drag': "Drag to reorder";
523
+ readonly 'uml.delete': "Delete row";
524
+ readonly 'uml.textColor': "Text color";
525
+ readonly 'uml.defaultColor': "Default color";
526
+ readonly 'uml.fontSize': "Font size";
527
+ readonly 'uml.strikethrough': "Strikethrough";
528
+ readonly 'uml.attribute': "Attributes";
529
+ readonly 'uml.method': "Methods";
530
+ readonly 'minimap.title': "Minimap";
531
+ readonly 'minimap.expand': "Expand minimap";
532
+ readonly 'minimap.collapse': "Collapse minimap";
533
+ readonly 'tool.mind-map': "Mind map";
534
+ readonly 'toolbar.mind-map': "Mind map";
535
+ readonly 'shape.mind-map': "Mind map";
536
+ readonly 'mindmap.defaultRoot': "Central topic";
537
+ readonly 'mindmap.defaultBranch': "Branch topic";
538
+ readonly 'mindmap.nodeText': "Node text";
539
+ readonly 'mindmap.addChild': "Child";
540
+ readonly 'mindmap.addSibling': "Sibling";
541
+ readonly 'mindmap.deleteNode': "Delete node";
542
+ readonly 'mindmap.color': "Color";
543
+ readonly 'mindmap.levelColor': "Default level color";
544
+ readonly 'mindmap.icon': "Icon";
545
+ readonly 'mindmap.noIcon': "No icon";
546
+ readonly 'mindmap.note': "Note";
547
+ readonly 'mindmap.notePlaceholder': "Note content (optional)";
548
+ readonly 'mindmap.noteColor': "Note color";
549
+ readonly 'mindmap.noteColorDefault': "Same as node";
550
+ readonly 'mindmap.collapse': "Collapse";
551
+ readonly 'mindmap.expand': "Expand";
552
+ readonly 'mindmap.close': "Close editor";
553
+ readonly 'mindmap.more': "More settings";
554
+ };
555
+ };
556
+ type MessageKey = keyof typeof dictionaries['zh-CN'];
557
+ type LanguageListener = () => void;
558
+ declare function setLanguage(language: Language): void;
559
+ declare function getLanguage(): Language;
560
+ declare function subscribeLanguage(listener: LanguageListener): () => void;
561
+ /** 取文案;{n} 等占位符由 params 替换 */
562
+ declare function t(key: MessageKey, params?: Record<string, string | number>): string;
563
+
243
564
  type Listener = () => void;
244
565
  type NotificationListener = (message: string) => void;
245
566
  /** 核心 → React 的 UI 指令事件 */
@@ -251,6 +572,17 @@ type UiEvent = {
251
572
  existingArrowId?: string;
252
573
  defaultShapeType: ShapeType;
253
574
  };
575
+ /** Editor 构造选项:主题色 / 语言 / 初始数据 / 本地持久化开关 */
576
+ interface EditorOptions {
577
+ /** 画布渲染主题色等颜色,见 setTheme */
578
+ theme?: Partial<DrawuiTheme>;
579
+ /** 界面语言(默认 'zh-CN') */
580
+ language?: Language;
581
+ /** 初始图形数据;提供后不再从 localStorage 加载 */
582
+ shapes?: Shape[];
583
+ /** 是否启用 localStorage 持久化(默认 true;提供 shapes 时自动关闭) */
584
+ persist?: boolean;
585
+ }
254
586
  declare class Editor {
255
587
  private canvas;
256
588
  private renderer;
@@ -279,18 +611,26 @@ declare class Editor {
279
611
  private snapGuides;
280
612
  private connectingTargetId;
281
613
  private genPreview;
282
- /** 拖动松开后待确认图形的上下文(配合"选择新图形"菜单) */
283
- private pendingGen;
614
+ private eraserPoint;
615
+ private mindMapEditingShapeId;
616
+ private mindMapSelectedNode;
617
+ private mindMapHoverNode;
284
618
  private renderScheduled;
285
619
  private pointerIsDown;
286
620
  private notifyScheduled;
287
- constructor(canvas: HTMLCanvasElement);
621
+ /** 是否启用 localStorage 持久化 */
622
+ private persist;
623
+ constructor(canvas: HTMLCanvasElement, options?: EditorOptions);
288
624
  private setupEventListeners;
289
625
  private handlePointerDown;
290
626
  private handlePointerMove;
291
627
  private handlePointerUp;
292
628
  /** 根据当前工具的命中结果更新鼠标样式(伸缩手柄↔/↕、拖拽 grabbing 等) */
293
629
  private updateCursor;
630
+ /**
631
+ * 滚轮:普通滚动平移视口(内容跟随常规滚动方向),
632
+ * Ctrl/Cmd + 滚轮以光标为中心缩放,Shift + 滚轮水平平移。
633
+ */
294
634
  private handleWheel;
295
635
  private handleKeyDown;
296
636
  private handleKeyUp;
@@ -359,6 +699,61 @@ declare class Editor {
359
699
  getSelectedUml(): UmlClassShape | UmlInterfaceShape | null;
360
700
  /** 按 id 查找 UML(类图或接口) */
361
701
  private getUmlById;
702
+ /** 获取选中的思维导图(恰好选中一个时) */
703
+ getSelectedMindMap(): MindMapShape | null;
704
+ /** 页面坐标下的思维导图节点命中:返回所在导图与节点 id */
705
+ getMindMapNodeAtPoint(point: Vec2): {
706
+ shapeId: string;
707
+ nodeId: string;
708
+ } | null;
709
+ /** 屏幕坐标(画布左上角为原点)下的思维导图节点命中 */
710
+ getMindMapNodeAtScreenPoint(screenPoint: Vec2): {
711
+ shapeId: string;
712
+ nodeId: string;
713
+ } | null;
714
+ /** 光标语义命中:仅节点框或折叠/展开标记内才命中(节点间空档不命中,避免空白处误显小手) */
715
+ getMindMapCursorHitAtPoint(point: Vec2): {
716
+ shapeId: string;
717
+ nodeId: string;
718
+ } | null;
719
+ /** 选中思维导图节点(不进入编辑态):选中导图并定位节点高亮 */
720
+ selectMindMapNode(shapeId: string, nodeId: string): void;
721
+ /** 当前思维导图编辑态 id(null 表示未在编辑) */
722
+ getMindMapEditingShapeId(): string | null;
723
+ /** 当前选中的思维导图节点 */
724
+ getMindMapSelectedNode(): {
725
+ shapeId: string;
726
+ nodeId: string;
727
+ } | null;
728
+ /** 读取思维导图指定节点(只读引用,勿修改) */
729
+ getMindMapNode(shapeId: string, nodeId: string): MindMapNode | null;
730
+ /** 思维导图某节点在屏幕上的外框矩形(左上角坐标 + 尺寸),用于就地编辑定位 */
731
+ getMindMapNodeScreenRect(shapeId: string, nodeId: string): {
732
+ x: number;
733
+ y: number;
734
+ width: number;
735
+ height: number;
736
+ } | null;
737
+ /** 页面坐标下折叠/展开标记的命中检测(返回所在导图与节点 id) */
738
+ getMindMapCollapseHitAtPoint(point: Vec2): {
739
+ shapeId: string;
740
+ nodeId: string;
741
+ } | null;
742
+ /** 进入思维导图编辑态(双击节点触发):选中导图并定位到节点 */
743
+ beginMindMapEdit(shapeId: string, nodeId: string | null): void;
744
+ /** 退出思维导图编辑态 */
745
+ exitMindMapEdit(): void;
746
+ /** 更新思维导图某节点(文本/颜色/图标/说明等),自动重算布局尺寸。
747
+ * commit=false 时仅应用变更、不写历史(就地文本编辑逐键调用用);首个变更传入 commit=true 形成单个撤销点。 */
748
+ updateMindMapNode(shapeId: string, nodeId: string, patch: Partial<MindMapNode>, commit?: boolean): void;
749
+ /** 给指定节点添加一个子节点 */
750
+ addMindMapChild(shapeId: string, nodeId: string): void;
751
+ /** 给指定节点添加一个兄弟节点(根节点无兄弟) */
752
+ addMindMapSibling(shapeId: string, nodeId: string): void;
753
+ /** 删除指定节点(含子树);删除根节点则移除整个思维导图 */
754
+ deleteMindMapNode(shapeId: string, nodeId: string): void;
755
+ /** 折叠/展开指定节点 */
756
+ toggleMindMapCollapse(shapeId: string, nodeId: string): void;
362
757
  /** 给指定 UML 类追加一条属性 */
363
758
  addUmlAttribute(shapeId: string): void;
364
759
  /** 给指定 UML(类图或接口)追加一条方法 */
@@ -393,6 +788,14 @@ declare class Editor {
393
788
  setActiveTool(tool: ToolType): void;
394
789
  getActiveTool(): ToolType;
395
790
  getShapes(): Shape[];
791
+ /** 导出当前数据(图形 + 相机),供外部保存/对接 */
792
+ getData(): EditorData;
793
+ /** 用外部数据整体替换画布内容(清空选择与历史),返回是否成功 */
794
+ setShapes(shapes: Shape[]): boolean;
795
+ /** 更新画布渲染主题色(选中态/手柄/网格等),立即重绘 */
796
+ setTheme(theme: Partial<DrawuiTheme>): void;
797
+ /** 切换界面语言(核心通知等文案;React 组件通过 useLanguage 自动刷新) */
798
+ setLanguage(language: Language): void;
396
799
  getSelectedIds(): string[];
397
800
  getCamera(): Camera;
398
801
  /** 指针是否处于按下状态(拖拽/画线/框选中) */
@@ -449,6 +852,12 @@ declare class Editor {
449
852
  private getShapeScreenBounds;
450
853
  getShapeAtScreenPoint(screenPoint: Vec2): Shape | null;
451
854
  getShapeAtPoint(point: Vec2, excludeId?: string): Shape | null;
855
+ /** 橡皮擦:返回与圆形笔刷相交的所有图形(不含线条的命中由其线段距离判定) */
856
+ getShapesInBrushRadius(point: Vec2, radius: number): Shape[];
857
+ private shapeIntersectsBrush;
858
+ /** 点到线段的最短距离 */
859
+ private pointToSegmentDist;
860
+ setEraserPoint(point: Vec2 | null): void;
452
861
  private isPointInShape;
453
862
  updateArrowBinding(arrowId: string, terminal: 'start' | 'end', targetShapeId: string | null, binding?: ArrowBinding): void;
454
863
  private getClosestHandle;
@@ -478,7 +887,15 @@ declare class Renderer {
478
887
  y: number;
479
888
  width: number;
480
889
  height: number;
481
- } | null, snapGuides?: SnapGuide[], connectingTarget?: string | null, generationPreview?: GenerationPreview | null): void;
890
+ } | null, snapGuides?: SnapGuide[], connectingTarget?: string | null, generationPreview?: GenerationPreview | null, eraserPoint?: Vec2 | null, mindMapSelection?: {
891
+ shapeId: string;
892
+ nodeId: string;
893
+ } | null, mindMapHover?: {
894
+ shapeId: string;
895
+ nodeId: string;
896
+ } | null): void;
897
+ /** 橡皮擦:半透明主色圆 + 主色描边,半径与笔刷命中范围一致(屏幕像素恒定) */
898
+ private drawEraserBrush;
482
899
  /** 连接进行中,高亮目标图形四边中点的可连锚点 */
483
900
  private drawConnectingTargetHighlight;
484
901
  /** 世界坐标下的轴对齐包围盒(未考虑旋转) */
@@ -516,6 +933,15 @@ declare class Renderer {
516
933
  private static readonly CONNECTION_LEAD;
517
934
  /** 连接的源/目标图形作为障碍时使用的避让间距(足够阻挡中段折回穿过,又允许紧邻节点直连) */
518
935
  private static readonly CONNECTED_PAD;
936
+ /**
937
+ * 思维导图:先画连线(父右缘 → 子左缘的平滑曲线),再画节点
938
+ * (白底圆角矩形 + 层级色描边 + 图标/文本/左上角属性说明/折叠标记)。
939
+ */
940
+ private drawMindMap;
941
+ private drawMindMapConnections;
942
+ private drawMindMapNodes;
943
+ /** 按像素宽度截断文本并加省略号 */
944
+ private ellipsizeText;
519
945
  private drawLine;
520
946
  private drawArrow;
521
947
  /** 选中连线 → 在线条上叠加一条高亮辅助线 */
@@ -651,6 +1077,10 @@ interface ToolContext {
651
1077
  panBy(dx: number, dy: number): void;
652
1078
  setCameraPosition(x: number, y: number): void;
653
1079
  getShapeAtPoint(point: Vec2, excludeId?: string): Shape | null;
1080
+ /** 返回与圆形笔刷(圆心 point、半径 radius,世界单位)相交的所有图形,橡皮擦用 */
1081
+ getShapesInBrushRadius(point: Vec2, radius: number): Shape[];
1082
+ /** 设置橡皮擦笔刷位置(画布绘制指示圈;null 清除) */
1083
+ setEraserPoint(point: Vec2 | null): void;
654
1084
  updateArrowBinding(arrowId: string, terminal: 'start' | 'end', targetShapeId: string | null, binding?: ArrowBinding): void;
655
1085
  enterEditing(shapeId: string): void;
656
1086
  exitEditing(): void;
@@ -681,6 +1111,13 @@ interface ToolContext {
681
1111
  highlightColor?: string;
682
1112
  }): void;
683
1113
  updateConnectionType(connectionType: ConnectionType): void;
1114
+ /** 光标语义命中:思维导图节点框或折叠标记内才命中(节点间空档不命中) */
1115
+ getMindMapCursorHitAtPoint(point: Vec2): {
1116
+ shapeId: string;
1117
+ nodeId: string;
1118
+ } | null;
1119
+ /** 选中思维导图节点(不进入编辑态) */
1120
+ selectMindMapNode(shapeId: string, nodeId: string): void;
684
1121
  }
685
1122
  declare abstract class Tool {
686
1123
  abstract type: ToolType;
@@ -758,7 +1195,6 @@ declare class SelectTool extends Tool {
758
1195
  /** 生成拖动:更新预览(线条 + 框)与目标高亮 */
759
1196
  private handleGenerating;
760
1197
  private handleRotating;
761
- private edgeMidpointWorld;
762
1198
  /** 根据绑定信息返回目标图形的实际吸附点 */
763
1199
  private bindingPosition;
764
1200
  private isPointInShape;
@@ -840,7 +1276,7 @@ declare class ShapeTool extends Tool {
840
1276
  onPointerUp(_point: Vec2, _event: PointerEvent): void;
841
1277
  onKeyDown(_event: KeyboardEvent): void;
842
1278
  onKeyUp(_event: KeyboardEvent): void;
843
- getCursor(): string | null;
1279
+ getCursor(point: Vec2): string | null;
844
1280
  }
845
1281
 
846
1282
  declare class LineTool extends Tool {
@@ -905,44 +1341,42 @@ declare class ArrowTool extends Tool {
905
1341
  private getCircleBindingPosition;
906
1342
  }
907
1343
 
1344
+ /** 不同层级节点的默认颜色,超过 6 层后循环复用 */
1345
+ declare const MINDMAP_COLORS: string[];
1346
+ declare const MINDMAP_FONT_SIZE = 14;
1347
+ declare const MINDMAP_NODE_HEIGHT = 40;
1348
+ declare const MINDMAP_MIN_WIDTH = 80;
1349
+ declare const MINDMAP_MAX_WIDTH = 240;
1350
+ interface MindMapNodePos {
1351
+ x: number;
1352
+ y: number;
1353
+ depth: number;
1354
+ width: number;
1355
+ height: number;
1356
+ }
1357
+ interface MindMapLayoutResult {
1358
+ positions: Map<string, MindMapNodePos>;
1359
+ width: number;
1360
+ height: number;
1361
+ }
1362
+ /** 节点颜色:手动设置优先,否则按层级取默认色 */
1363
+ declare function mindMapNodeColor(node: MindMapNode, depth: number): string;
1364
+ /** 节点框尺寸:由文本长度决定(CJK 按全宽估算),图标占位额外加宽 */
1365
+ declare function mindMapNodeSize(node: MindMapNode): {
1366
+ width: number;
1367
+ height: number;
1368
+ };
1369
+ /** 深拷贝节点树(撤销/重做快照用) */
1370
+ declare function cloneMindMapNode(node: MindMapNode): MindMapNode;
1371
+ declare function findMindMapNode(root: MindMapNode, nodeId: string): MindMapNode | null;
1372
+ declare function getMindMapNodeDepth(root: MindMapNode, nodeId: string): number;
1373
+ declare function getMindMapParent(root: MindMapNode, nodeId: string): MindMapNode | null;
1374
+ declare function countMindMapNodes(root: MindMapNode): number;
908
1375
  /**
909
- * 主题颜色常量 - 统一管理所有 UI 颜色
910
- * 修改此处即可全局生效
1376
+ * 横向树布局:根在左,子节点向右展开,每个节点垂直居中于其子树。
1377
+ * 返回以内容包围盒中心为原点的局部坐标(shape.x/y 即该中心),
1378
+ * 便于复用现有选中框/旋转/命中检测逻辑。
911
1379
  */
912
- declare const THEME: {
913
- readonly selection: {
914
- /** 选中边框颜色 */
915
- readonly outline: "#3b82f6";
916
- /** 选中控制点边框颜色 */
917
- readonly handleStroke: "#3b82f6";
918
- /** 选中控制点填充颜色 */
919
- readonly handleFill: "#ffffff";
920
- /** 选中区域填充颜色 (半透明) */
921
- readonly outlineFill: "rgba(59, 130, 246, 0.1)";
922
- /** 选中阴影颜色 */
923
- readonly shadow: "#3b82f6";
924
- };
925
- readonly grid: "#e5e7eb";
926
- readonly text: "#1f2937";
927
- readonly editBorder: "#3b82f6";
928
- };
929
- /** 获取当前主题(方便未来扩展为动态主题切换) */
930
- declare function getTheme(): {
931
- readonly selection: {
932
- /** 选中边框颜色 */
933
- readonly outline: "#3b82f6";
934
- /** 选中控制点边框颜色 */
935
- readonly handleStroke: "#3b82f6";
936
- /** 选中控制点填充颜色 */
937
- readonly handleFill: "#ffffff";
938
- /** 选中区域填充颜色 (半透明) */
939
- readonly outlineFill: "rgba(59, 130, 246, 0.1)";
940
- /** 选中阴影颜色 */
941
- readonly shadow: "#3b82f6";
942
- };
943
- readonly grid: "#e5e7eb";
944
- readonly text: "#1f2937";
945
- readonly editBorder: "#3b82f6";
946
- };
1380
+ declare function layoutMindMap(root: MindMapNode): MindMapLayoutResult;
947
1381
 
948
- export { type ArrowBinding, type ArrowHeadType, type ArrowShape, ArrowTool, Camera, type CameraState, type CircleShape, type ConnectionType, type DiamondShape, type DrawShape, Editor, type EditorState, type EllipseShape, type FreehandMode, FreehandTool, type GenerationContext, HandTool, type HexagonShape, type LineShape, LineTool, Mat2d, type OctagonShape, type ParallelogramShape, type PentagonShape, type Rect, type RectangleShape, Renderer, type RoundedRectangleShape, SelectTool, type Shape, type ShapeStyle, ShapeTool, type ShapeType, type SnapGuide, type StarShape, THEME, 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 UmlAttribute, type UmlClassShape, type UmlInterfaceShape, type UmlMethod, type UmlVisibility, Vec, type Vec2 as Vec2Type, calcUmlClassSize, getTheme };
1382
+ export { type ArrowBinding, type ArrowHeadType, type ArrowShape, ArrowTool, Camera, type CameraState, type CircleShape, type ConnectionType, type DiamondShape, type DrawShape, type DrawuiTheme, type DrawuiThemeSelection, Editor, type EditorData, type EditorOptions, type EditorState, type EllipseShape, type FreehandMode, FreehandTool, type GenerationContext, HandTool, type HexagonShape, type Language, type LineShape, LineTool, MINDMAP_COLORS, MINDMAP_FONT_SIZE, MINDMAP_MAX_WIDTH, MINDMAP_MIN_WIDTH, MINDMAP_NODE_HEIGHT, Mat2d, type MessageKey, type MindMapLayoutResult, type MindMapNode, type MindMapNodePos, type MindMapShape, type OctagonShape, type ParallelogramShape, type PentagonShape, type Rect, type RectangleShape, Renderer, type RoundedRectangleShape, SelectTool, type Shape, type ShapeStyle, ShapeTool, type ShapeType, type SnapGuide, type StarShape, THEME, 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, calcUmlClassSize, cloneMindMapNode, countMindMapNodes, findMindMapNode, getLanguage, getMindMapNodeDepth, getMindMapParent, getTheme, hexToRgba, layoutMindMap, mindMapNodeColor, mindMapNodeSize, setLanguage, setTheme, shadeColor, subscribeLanguage, subscribeTheme, t };