aldehyde 0.2.473 → 0.2.475

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.
Files changed (203) hide show
  1. package/lib/controls/action/utils.d.ts +1 -1
  2. package/lib/controls/entity-select/entity-select.d.ts +2 -2
  3. package/lib/controls/entity-select/entity-select.d.ts.map +1 -1
  4. package/lib/controls/entity-select/entity-select.js +16 -7
  5. package/lib/controls/entity-select/entity-select.js.map +1 -1
  6. package/lib/controls/entry-control.d.ts.map +1 -1
  7. package/lib/controls/entry-control.js +3 -2
  8. package/lib/controls/entry-control.js.map +1 -1
  9. package/lib/controls/icon-selector/icon/phonenode-menu-icon/iconfont.css +47 -3
  10. package/lib/controls/icon-selector/icon/phonenode-menu-icon/iconfont.js +12 -12
  11. package/lib/controls/icon-selector/icon/phonenode-menu-icon/iconfont.js.map +1 -1
  12. package/lib/controls/icon-selector/icon/phonenode-menu-icon/iconfont.json +77 -0
  13. package/lib/controls/icon-selector/icon/phonenode-menu-icon/iconfont.ttf +0 -0
  14. package/lib/controls/icon-selector/icon/phonenode-menu-icon/iconfont.woff +0 -0
  15. package/lib/controls/icon-selector/icon/phonenode-menu-icon/iconfont.woff2 +0 -0
  16. package/lib/controls/select/index.d.ts.map +1 -1
  17. package/lib/controls/select/index.js +13 -7
  18. package/lib/controls/select/index.js.map +1 -1
  19. package/lib/controls/text/index.less +1 -0
  20. package/lib/controls/view-control.d.ts.map +1 -1
  21. package/lib/controls/view-control.js +1 -0
  22. package/lib/controls/view-control.js.map +1 -1
  23. package/lib/detail/button/edit-button.d.ts.map +1 -1
  24. package/lib/detail/button/edit-button.js +23 -11
  25. package/lib/detail/button/edit-button.js.map +1 -1
  26. package/lib/detail/button/view-button.d.ts.map +1 -1
  27. package/lib/detail/button/view-button.js +21 -10
  28. package/lib/detail/button/view-button.js.map +1 -1
  29. package/lib/draw-canvas/edit/components/asset-bar/index.d.ts +5 -0
  30. package/lib/draw-canvas/edit/components/asset-bar/index.d.ts.map +1 -0
  31. package/lib/draw-canvas/edit/components/asset-bar/index.js +79 -0
  32. package/lib/draw-canvas/edit/components/asset-bar/index.js.map +1 -0
  33. package/lib/draw-canvas/edit/components/asset-bar/index.less +36 -0
  34. package/lib/draw-canvas/edit/components/main-header/index.d.ts +19 -0
  35. package/lib/draw-canvas/edit/components/main-header/index.d.ts.map +1 -0
  36. package/lib/draw-canvas/edit/components/main-header/index.js +203 -0
  37. package/lib/draw-canvas/edit/components/main-header/index.js.map +1 -0
  38. package/lib/draw-canvas/edit/components/main-header/index.less +21 -0
  39. package/lib/draw-canvas/edit/components/render/index.d.ts +90 -0
  40. package/lib/draw-canvas/edit/components/render/index.d.ts.map +1 -0
  41. package/lib/draw-canvas/edit/components/render/index.js +692 -0
  42. package/lib/draw-canvas/edit/components/render/index.js.map +1 -0
  43. package/lib/draw-canvas/edit/components/render/types.d.ts +247 -0
  44. package/lib/draw-canvas/edit/components/render/types.d.ts.map +1 -0
  45. package/lib/draw-canvas/edit/components/render/types.js +66 -0
  46. package/lib/draw-canvas/edit/components/render/types.js.map +1 -0
  47. package/lib/draw-canvas/edit/components/setting-form/imag-upload.d.ts +26 -0
  48. package/lib/draw-canvas/edit/components/setting-form/imag-upload.d.ts.map +1 -0
  49. package/lib/draw-canvas/edit/components/setting-form/imag-upload.js +83 -0
  50. package/lib/draw-canvas/edit/components/setting-form/imag-upload.js.map +1 -0
  51. package/lib/draw-canvas/edit/components/setting-form/index.d.ts +17 -0
  52. package/lib/draw-canvas/edit/components/setting-form/index.d.ts.map +1 -0
  53. package/lib/draw-canvas/edit/components/setting-form/index.js +243 -0
  54. package/lib/draw-canvas/edit/components/setting-form/index.js.map +1 -0
  55. package/lib/draw-canvas/edit/constant.d.ts +7 -0
  56. package/lib/draw-canvas/edit/constant.d.ts.map +1 -0
  57. package/lib/draw-canvas/edit/constant.js +7 -0
  58. package/lib/draw-canvas/edit/constant.js.map +1 -0
  59. package/lib/draw-canvas/edit/index.d.ts +8 -0
  60. package/lib/draw-canvas/edit/index.d.ts.map +1 -0
  61. package/lib/draw-canvas/edit/index.js +165 -0
  62. package/lib/draw-canvas/edit/index.js.map +1 -0
  63. package/lib/draw-canvas/edit/index.less +49 -0
  64. package/lib/draw-canvas/view/index.d.ts +8 -0
  65. package/lib/draw-canvas/view/index.d.ts.map +1 -0
  66. package/lib/draw-canvas/view/index.js +50 -0
  67. package/lib/draw-canvas/view/index.js.map +1 -0
  68. package/lib/draw-canvas/view/index.less +60 -0
  69. package/lib/draw-canvas/view/view.d.ts +10 -0
  70. package/lib/draw-canvas/view/view.d.ts.map +1 -0
  71. package/lib/draw-canvas/view/view.js +104 -0
  72. package/lib/draw-canvas/view/view.js.map +1 -0
  73. package/lib/form/form-Item-group.d.ts.map +1 -1
  74. package/lib/form/form-Item-group.js +4 -4
  75. package/lib/form/form-Item-group.js.map +1 -1
  76. package/lib/icon/local-aliIcon/iconfont.js +5 -5
  77. package/lib/icon/local-aliIcon/iconfont.js.map +1 -1
  78. package/lib/lowcode-components/index.d.ts +2 -0
  79. package/lib/lowcode-components/index.d.ts.map +1 -1
  80. package/lib/lowcode-components/index.js +2 -1
  81. package/lib/lowcode-components/index.js.map +1 -1
  82. package/lib/lowcode-components/lowcode-view/component/assets.d.ts.map +1 -1
  83. package/lib/lowcode-components/lowcode-view/component/assets.js +8 -0
  84. package/lib/lowcode-components/lowcode-view/component/assets.js.map +1 -1
  85. package/lib/lowcode-components/radar-chart/index.d.ts +51 -0
  86. package/lib/lowcode-components/radar-chart/index.d.ts.map +1 -0
  87. package/lib/lowcode-components/radar-chart/index.js +276 -0
  88. package/lib/lowcode-components/radar-chart/index.js.map +1 -0
  89. package/lib/module/dtmpl-edit-card.d.ts.map +1 -1
  90. package/lib/module/dtmpl-edit-card.js +18 -1
  91. package/lib/module/dtmpl-edit-card.js.map +1 -1
  92. package/lib/module/dtmpl-edit-page.d.ts.map +1 -1
  93. package/lib/module/dtmpl-edit-page.js +19 -2
  94. package/lib/module/dtmpl-edit-page.js.map +1 -1
  95. package/lib/routable/ltmpl-route.d.ts +2 -0
  96. package/lib/routable/ltmpl-route.d.ts.map +1 -1
  97. package/lib/routable/ltmpl-route.js +20 -4
  98. package/lib/routable/ltmpl-route.js.map +1 -1
  99. package/lib/table/act-table.d.ts +2 -0
  100. package/lib/table/act-table.d.ts.map +1 -1
  101. package/lib/table/act-table.js +4 -4
  102. package/lib/table/act-table.js.map +1 -1
  103. package/lib/table/column/column-builder.d.ts.map +1 -1
  104. package/lib/table/column/column-builder.js +23 -8
  105. package/lib/table/column/column-builder.js.map +1 -1
  106. package/lib/table/relation-table.d.ts +7 -0
  107. package/lib/table/relation-table.d.ts.map +1 -1
  108. package/lib/tmpl/control-type-supportor.d.ts.map +1 -1
  109. package/lib/tmpl/control-type-supportor.js +1 -0
  110. package/lib/tmpl/control-type-supportor.js.map +1 -1
  111. package/lib/tmpl/hcservice-v3.d.ts +3 -0
  112. package/lib/tmpl/hcservice-v3.d.ts.map +1 -1
  113. package/lib/tmpl/hcservice-v3.js +61 -0
  114. package/lib/tmpl/hcservice-v3.js.map +1 -1
  115. package/lib/tmpl/interface.d.ts +17 -1
  116. package/lib/tmpl/interface.d.ts.map +1 -1
  117. package/lib/tmpl/interface.js.map +1 -1
  118. package/lib/tmpl/tmpl-config-analysis.js +1 -1
  119. package/lib/tmpl/tmpl-config-analysis.js.map +1 -1
  120. package/lib/units/index.d.ts +3 -1
  121. package/lib/units/index.d.ts.map +1 -1
  122. package/lib/units/index.js +33 -3
  123. package/lib/units/index.js.map +1 -1
  124. package/package.json +4 -1
  125. package/src/aldehyde/controls/entity-select/entity-select.tsx +18 -8
  126. package/src/aldehyde/controls/entry-control.tsx +3 -2
  127. package/src/aldehyde/controls/icon-selector/icon/phonenode-menu-icon/iconfont.css +47 -3
  128. package/src/aldehyde/controls/icon-selector/icon/phonenode-menu-icon/iconfont.js +1 -1
  129. package/src/aldehyde/controls/icon-selector/icon/phonenode-menu-icon/iconfont.json +77 -0
  130. package/src/aldehyde/controls/icon-selector/icon/phonenode-menu-icon/iconfont.ttf +0 -0
  131. package/src/aldehyde/controls/icon-selector/icon/phonenode-menu-icon/iconfont.woff +0 -0
  132. package/src/aldehyde/controls/icon-selector/icon/phonenode-menu-icon/iconfont.woff2 +0 -0
  133. package/src/aldehyde/controls/select/index.tsx +7 -6
  134. package/src/aldehyde/controls/text/index.less +1 -0
  135. package/src/aldehyde/controls/view-control.tsx +1 -0
  136. package/src/aldehyde/detail/button/edit-button.tsx +21 -22
  137. package/src/aldehyde/detail/button/view-button.tsx +23 -21
  138. package/src/aldehyde/draw-canvas/edit/components/asset-bar/index.less +36 -0
  139. package/src/aldehyde/draw-canvas/edit/components/asset-bar/index.tsx +95 -0
  140. package/src/aldehyde/draw-canvas/edit/components/main-header/index.less +21 -0
  141. package/src/aldehyde/draw-canvas/edit/components/main-header/index.tsx +233 -0
  142. package/src/aldehyde/draw-canvas/edit/components/render/draws/bg-draw.ts +163 -0
  143. package/src/aldehyde/draw-canvas/edit/components/render/draws/contextmenu-draw.ts +307 -0
  144. package/src/aldehyde/draw-canvas/edit/components/render/draws/graph-draw.ts +251 -0
  145. package/src/aldehyde/draw-canvas/edit/components/render/draws/index.ts +7 -0
  146. package/src/aldehyde/draw-canvas/edit/components/render/draws/link-draw.ts +1416 -0
  147. package/src/aldehyde/draw-canvas/edit/components/render/draws/preview-draw.ts +275 -0
  148. package/src/aldehyde/draw-canvas/edit/components/render/draws/ref-line-draw.ts +72 -0
  149. package/src/aldehyde/draw-canvas/edit/components/render/draws/ruler-draw.ts +167 -0
  150. package/src/aldehyde/draw-canvas/edit/components/render/graphs/base-graph.ts +241 -0
  151. package/src/aldehyde/draw-canvas/edit/components/render/graphs/bezier.ts +542 -0
  152. package/src/aldehyde/draw-canvas/edit/components/render/graphs/circle.ts +700 -0
  153. package/src/aldehyde/draw-canvas/edit/components/render/graphs/curve.ts +501 -0
  154. package/src/aldehyde/draw-canvas/edit/components/render/graphs/index.ts +6 -0
  155. package/src/aldehyde/draw-canvas/edit/components/render/graphs/line.ts +494 -0
  156. package/src/aldehyde/draw-canvas/edit/components/render/graphs/rect.ts +681 -0
  157. package/src/aldehyde/draw-canvas/edit/components/render/handlers/drag-handlers.ts +69 -0
  158. package/src/aldehyde/draw-canvas/edit/components/render/handlers/drag-outside-handlers.ts +159 -0
  159. package/src/aldehyde/draw-canvas/edit/components/render/handlers/graph-handlers.ts +108 -0
  160. package/src/aldehyde/draw-canvas/edit/components/render/handlers/index.ts +9 -0
  161. package/src/aldehyde/draw-canvas/edit/components/render/handlers/key-move-handlers.ts +50 -0
  162. package/src/aldehyde/draw-canvas/edit/components/render/handlers/link-handlers.ts +46 -0
  163. package/src/aldehyde/draw-canvas/edit/components/render/handlers/selection-handlers.ts +393 -0
  164. package/src/aldehyde/draw-canvas/edit/components/render/handlers/shutcut-handlers.ts +46 -0
  165. package/src/aldehyde/draw-canvas/edit/components/render/handlers/text-handlers.ts +82 -0
  166. package/src/aldehyde/draw-canvas/edit/components/render/handlers/zoom-handlers.ts +60 -0
  167. package/src/aldehyde/draw-canvas/edit/components/render/index.ts +776 -0
  168. package/src/aldehyde/draw-canvas/edit/components/render/tools/align-tool.ts +91 -0
  169. package/src/aldehyde/draw-canvas/edit/components/render/tools/asset-tool.ts +142 -0
  170. package/src/aldehyde/draw-canvas/edit/components/render/tools/attract-tool.ts +440 -0
  171. package/src/aldehyde/draw-canvas/edit/components/render/tools/copy-tool.ts +269 -0
  172. package/src/aldehyde/draw-canvas/edit/components/render/tools/import-export-tool.ts +603 -0
  173. package/src/aldehyde/draw-canvas/edit/components/render/tools/index.ts +9 -0
  174. package/src/aldehyde/draw-canvas/edit/components/render/tools/link-tool.ts +225 -0
  175. package/src/aldehyde/draw-canvas/edit/components/render/tools/position-tool.ts +194 -0
  176. package/src/aldehyde/draw-canvas/edit/components/render/tools/selection-tool.ts +132 -0
  177. package/src/aldehyde/draw-canvas/edit/components/render/tools/z-index-tool.ts +227 -0
  178. package/src/aldehyde/draw-canvas/edit/components/render/types.ts +291 -0
  179. package/src/aldehyde/draw-canvas/edit/components/render/utils/a-star.ts +116 -0
  180. package/src/aldehyde/draw-canvas/edit/components/render/utils/bezier-scene-func.ts +73 -0
  181. package/src/aldehyde/draw-canvas/edit/components/setting-form/imag-upload.tsx +118 -0
  182. package/src/aldehyde/draw-canvas/edit/components/setting-form/index.tsx +295 -0
  183. package/src/aldehyde/draw-canvas/edit/constant.ts +6 -0
  184. package/src/aldehyde/draw-canvas/edit/index.less +49 -0
  185. package/src/aldehyde/draw-canvas/edit/index.tsx +197 -0
  186. package/src/aldehyde/draw-canvas/view/index.less +60 -0
  187. package/src/aldehyde/draw-canvas/view/index.tsx +48 -0
  188. package/src/aldehyde/draw-canvas/view/view.tsx +114 -0
  189. package/src/aldehyde/form/form-Item-group.tsx +5 -5
  190. package/src/aldehyde/icon/local-aliIcon/iconfont.js +1 -1
  191. package/src/aldehyde/lowcode-components/index.ts +4 -2
  192. package/src/aldehyde/lowcode-components/lowcode-view/component/assets.ts +8 -0
  193. package/src/aldehyde/lowcode-components/radar-chart/index.tsx +323 -0
  194. package/src/aldehyde/module/dtmpl-edit-card.tsx +18 -1
  195. package/src/aldehyde/module/dtmpl-edit-page.tsx +19 -2
  196. package/src/aldehyde/routable/ltmpl-route.tsx +39 -3
  197. package/src/aldehyde/table/act-table.tsx +7 -4
  198. package/src/aldehyde/table/column/column-builder.tsx +29 -9
  199. package/src/aldehyde/tmpl/control-type-supportor.tsx +1 -0
  200. package/src/aldehyde/tmpl/hcservice-v3.tsx +44 -0
  201. package/src/aldehyde/tmpl/interface.tsx +15 -1
  202. package/src/aldehyde/tmpl/tmpl-config-analysis.tsx +1 -1
  203. package/src/aldehyde/units/index.tsx +31 -3
@@ -0,0 +1,776 @@
1
+ import * as _ from 'lodash';
2
+ import Konva from 'konva';
3
+ import { GraphDraw, LinkDraw, RulerDraw, PreviewDraw, RefLineDraw, BgDraw, ContextmenuDraw } from './draws';
4
+ import { LinkDrawPoint, GraphType, AssetType, RenderConfig, Draw, Handler, RenderEvents, LinkDrawPair, PageSettings, AssetSettings, ImageType, LinkSettings } from './types';
5
+ import { DragHandlers, ZoomHandlers, DragOutsideHandlers, SelectionHandlers, KeyMoveHandlers, ShutcutHandlers, LinkHandlers, GraphHandlers, TextHandlers } from './handlers';
6
+ import { AssetTool, SelectionTool, CopyTool, PositionTool, ZIndexTool, ImportExportTool, AlignTool, LinkTool, AttractTool } from './tools';
7
+
8
+ // 简单的事件系统替代 mitt
9
+ class SimpleEventEmitter {
10
+ private listeners: Map<string, Set<Function>> = new Map();
11
+
12
+ on(event: string, handler: Function) {
13
+ if (!this.listeners.has(event)) {
14
+ this.listeners.set(event, new Set());
15
+ }
16
+ this.listeners.get(event)!.add(handler);
17
+ return () => this.off(event, handler);
18
+ }
19
+
20
+ off(event: string, handler: Function) {
21
+ this.listeners.get(event)?.delete(handler);
22
+ }
23
+
24
+ emit(event: string, ...args: any[]) {
25
+ this.listeners.get(event)?.forEach(handler => handler(...args));
26
+ }
27
+ }
28
+
29
+ // 渲染器
30
+ export class Render {
31
+ stage: Konva.Stage;
32
+ layer: Konva.Layer = new Konva.Layer({ id: 'main' }); // 主要层
33
+ layerFloor: Konva.Layer = new Konva.Layer(); // 辅助层 - 背景
34
+ layerCover: Konva.Layer = new Konva.Layer({ id: 'cover' }); // 辅助层 - 连接线、对齐线
35
+ config: RenderConfig; // 配置
36
+ draws: { [index: string]: (Draw & Handler) | undefined } = {}; // 附加工具
37
+ assetTool: AssetTool; // 素材工具
38
+ selectionTool: SelectionTool; // 选择工具
39
+ copyTool: CopyTool; // 复制工具
40
+ positionTool: PositionTool; // 定位工具
41
+ zIndexTool: ZIndexTool; // 层级工具
42
+ importExportTool: ImportExportTool; // 导入导出
43
+ alignTool: AlignTool; // 对齐工具
44
+ linkTool: LinkTool; // 连线工具
45
+ attractTool: AttractTool; // 磁贴工具
46
+ groupTransformer: Konva.Group = new Konva.Group(); // 多选器层
47
+
48
+ // 多选器
49
+ transformer: Konva.Transformer = new Konva.Transformer({
50
+ shouldOverdrawWholeArea: true,
51
+ borderDash: [4, 4],
52
+ padding: 1,
53
+ rotationSnaps: [0, 45, 90, 135, 180, 225, 270, 315, 360],
54
+ flipEnabled: false
55
+ });
56
+
57
+ // 选择框
58
+ selectRect: Konva.Rect = new Konva.Rect({
59
+ id: 'selectRect',
60
+ fill: 'rgba(0,0,255,0.1)',
61
+ visible: false
62
+ });
63
+
64
+ // 事件处理
65
+ handlers: { [index: string]: Handler } = {};
66
+
67
+ // 参数
68
+ bgSize = 20;
69
+ rulerSize = 0;
70
+ previewSize = 0.2; // 预览框大小(比例)
71
+ pointSize = 6;
72
+ history: string[] = [];
73
+ historyIndex = -1;
74
+ graphType: GraphType | undefined = undefined; // 画图类型
75
+ texting = false; // 添加文字中
76
+ showGrid = true; // 显示网格
77
+ showAttract = true; // 显示磁吸
78
+
79
+ // 事件发射器(替代 mitt)
80
+ private emitter = new SimpleEventEmitter();
81
+ on: <K extends keyof RenderEvents>(event: K, handler: (payload: RenderEvents[K]) => void) => (() => void);
82
+ off: <K extends keyof RenderEvents>(event: K, handler: (payload: RenderEvents[K]) => void) => void;
83
+ emit: <K extends keyof RenderEvents>(event: K, payload: RenderEvents[K]) => void;
84
+
85
+ constructor(stageEle: HTMLDivElement, config: RenderConfig) {
86
+ this.config = config;
87
+ // 绑定事件方法
88
+ this.on = this.emitter.on.bind(this.emitter) as any;
89
+ this.off = this.emitter.off.bind(this.emitter) as any;
90
+ this.emit = this.emitter.emit.bind(this.emitter) as any;
91
+ if (this.config.showRuler) {
92
+ this.rulerSize = 40;
93
+ }
94
+ this.stage = new Konva.Stage({
95
+ container: stageEle,
96
+ x: this.rulerSize,
97
+ y: this.rulerSize,
98
+ width: config.width,
99
+ height: config.height
100
+ });
101
+ // 辅助层 - 顶层
102
+ this.groupTransformer.add(this.transformer);
103
+ this.groupTransformer.add(this.selectRect);
104
+ this.layerCover.add(this.groupTransformer);
105
+
106
+ if (this.config.showBg) { // 背景
107
+ this.draws[BgDraw.name] = new BgDraw(this, this.layerFloor, { size: this.bgSize, showGrid: this.showGrid, readonly: this.config.readonly });
108
+ }
109
+
110
+ this.draws[LinkDraw.name] = new LinkDraw(this, this.layerCover, {
111
+ size: this.pointSize
112
+ });
113
+
114
+ if (!this.config.readonly && this.config.showRuler) {
115
+ this.draws[RulerDraw.name] = new RulerDraw(this, this.layerCover, {
116
+ size: this.rulerSize
117
+ });
118
+ }
119
+
120
+ if (!this.config.readonly && this.config.showRefLine) {
121
+ this.draws[RefLineDraw.name] = new RefLineDraw(this, this.layerCover, {
122
+ padding: this.rulerSize
123
+ });
124
+ }
125
+
126
+ if (this.config.showContextmenu) {
127
+ this.draws[ContextmenuDraw.name] = new ContextmenuDraw(this, this.layerCover, {});
128
+ }
129
+
130
+ if (!this.config.readonly && this.config.showPreview) {
131
+ this.draws[PreviewDraw.name] = new PreviewDraw(this, this.layerCover, {
132
+ size: this.previewSize
133
+ });
134
+ }
135
+
136
+ this.draws[GraphDraw.name] = new GraphDraw(this, this.layerCover, {});
137
+
138
+ this.assetTool = new AssetTool(this); // 素材工具
139
+ this.selectionTool = new SelectionTool(this); // 选择工具
140
+ this.copyTool = new CopyTool(this); // 复制工具
141
+ this.positionTool = new PositionTool(this); // 定位工具
142
+ this.zIndexTool = new ZIndexTool(this); // 定位工具
143
+ this.importExportTool = new ImportExportTool(this); // 导入导出
144
+ this.alignTool = new AlignTool(this); // 对齐工具
145
+ this.linkTool = new LinkTool(this); // 对齐工具
146
+ this.attractTool = new AttractTool(this); // 磁贴工具
147
+
148
+ // 事件处理
149
+ this.handlers[DragHandlers.name] = new DragHandlers(this);
150
+ this.handlers[ZoomHandlers.name] = new ZoomHandlers(this);
151
+
152
+ if (!this.config.readonly) {
153
+ this.handlers[DragOutsideHandlers.name] = new DragOutsideHandlers(this);
154
+ this.handlers[SelectionHandlers.name] = new SelectionHandlers(this);
155
+ this.handlers[KeyMoveHandlers.name] = new KeyMoveHandlers(this);
156
+ this.handlers[LinkHandlers.name] = new LinkHandlers(this);
157
+ this.handlers[GraphHandlers.name] = new GraphHandlers(this);
158
+ this.handlers[TextHandlers.name] = new TextHandlers(this);
159
+ }
160
+ if (!this.config.readonly && this.config.showRefLine) {
161
+ if (this.draws[RefLineDraw.name] !== void 0) {
162
+ this.handlers[RefLineDraw.name] = this.draws[RefLineDraw.name]!;
163
+ }
164
+ }
165
+ this.handlers[ShutcutHandlers.name] = new ShutcutHandlers(this);
166
+ // 初始化
167
+ this.init();
168
+ }
169
+
170
+ // 初始化
171
+ init() {
172
+ this.stage.add(this.layerFloor);
173
+ this.draws[BgDraw.name]?.init();
174
+ this.stage.add(this.layer);
175
+ this.stage.add(this.layerCover);
176
+ this.draws[LinkDraw.name]?.init();
177
+ this.draws[RulerDraw.name]?.init();
178
+ this.draws[RefLineDraw.name]?.init();
179
+ this.draws[ContextmenuDraw.name]?.init();
180
+ this.draws[PreviewDraw.name]?.init();
181
+ // 事件绑定
182
+ this.eventBind();
183
+ // 更新历史
184
+ this.updateHistory();
185
+ }
186
+
187
+ // 更新 stage 尺寸
188
+ resize(width: number, height: number) {
189
+ this.stage.setAttrs({
190
+ width: width,
191
+ height: height
192
+ });
193
+ // 重绘
194
+ this.redraw();
195
+ }
196
+
197
+ // 移除元素
198
+ remove(nodes: Konva.Node[]) {
199
+ for (const node of nodes) {
200
+ if (node instanceof Konva.Transformer) {
201
+ // 移除已选择的节点
202
+ this.remove(this.selectionTool.selectingNodes);
203
+ } else {
204
+ // 移除相关联系线信息
205
+ const groupId = node.id();
206
+ for (const rn of this.layer.getChildren()) {
207
+ if (rn.id() !== groupId && Array.isArray(rn.attrs.points)) {
208
+ for (const point of rn.attrs.points) {
209
+ if (Array.isArray(point.pairs)) {
210
+ // 移除拐点记录
211
+ if (rn.attrs.manualPointsMap) {
212
+ point.pairs
213
+ .filter(
214
+ (pair: LinkDrawPair) =>
215
+ pair.from.groupId === groupId || pair.to.groupId === groupId
216
+ )
217
+ .forEach((pair: LinkDrawPair) => {
218
+ rn.attrs.manualPointsMap[pair.id] = undefined;
219
+ });
220
+ }
221
+ // 连接线信息
222
+ point.pairs = point.pairs.filter(
223
+ (pair: LinkDrawPair) =>
224
+ pair.from.groupId !== groupId && pair.to.groupId !== groupId
225
+ );
226
+ }
227
+ }
228
+ rn.setAttrs({ points: rn.attrs.points });
229
+ }
230
+ }
231
+ // 移除未选择的节点
232
+ node.destroy();
233
+ }
234
+ }
235
+
236
+ if (nodes.length > 0) {
237
+ // 清除选择
238
+ this.selectionTool.selectingClear();
239
+ this.linkTool.selectingClear();
240
+ // 更新历史
241
+ this.updateHistory();
242
+ // 重绘
243
+ this.redraw();
244
+ }
245
+ }
246
+
247
+ // 撤销
248
+ prevHistory() {
249
+ const record = this.history[this.historyIndex - 1];
250
+ if (record) {
251
+ this.importExportTool.restore(record, true);
252
+ this.historyIndex--;
253
+ // 历史变化事件
254
+ this.emit('history-change', {
255
+ records: _.clone(this.history),
256
+ index: this.historyIndex
257
+ });
258
+ }
259
+ }
260
+
261
+ // 恢复
262
+ nextHistory() {
263
+ const record = this.history[this.historyIndex + 1];
264
+ if (record) {
265
+ this.importExportTool.restore(record, true);
266
+ this.historyIndex++;
267
+ // 历史变化事件
268
+ this.emit('history-change', {
269
+ records: _.clone(this.history),
270
+ index: this.historyIndex
271
+ });
272
+ }
273
+ }
274
+
275
+ updateHistory() {
276
+ this.history.splice(this.historyIndex + 1);
277
+ this.history.push(this.importExportTool.save());
278
+ this.historyIndex = this.history.length - 1;
279
+ // 历史变化事件
280
+ this.emit('history-change', {
281
+ records: _.clone(this.history),
282
+ index: this.historyIndex
283
+ });
284
+ }
285
+
286
+ // 事件绑定
287
+ eventBind() {
288
+ for (const event of [
289
+ 'mousedown',
290
+ 'mouseup',
291
+ 'mousemove',
292
+ 'wheel',
293
+ 'contextmenu',
294
+ 'pointerclick'
295
+ ]) {
296
+ this.stage.on(event, (e) => {
297
+ e?.evt?.preventDefault();
298
+ for (const k in this.draws) {
299
+ this.draws[k]?.handlers?.stage?.[event]?.(e);
300
+ }
301
+ for (const k in this.handlers) {
302
+ this.handlers[k]?.handlers?.stage?.[event]?.(e);
303
+ }
304
+ });
305
+ }
306
+
307
+ const container = this.stage.container();
308
+ container.tabIndex = 1;
309
+ container.focus();
310
+ for (const event of [
311
+ 'mouseenter',
312
+ 'dragenter',
313
+ 'mousemove',
314
+ 'mouseout',
315
+ 'dragenter',
316
+ 'dragover',
317
+ 'drop',
318
+ 'keydown',
319
+ 'keyup'
320
+ ]) {
321
+ container.addEventListener(event, (e) => {
322
+ e?.preventDefault();
323
+ if (['mouseenter', 'dragenter'].includes(event)) {
324
+ // 激活 dom 事件
325
+ this.stage.container().focus();
326
+ }
327
+ for (const k in this.draws) {
328
+ this.draws[k]?.handlers?.dom?.[event]?.(e);
329
+ }
330
+ for (const k in this.handlers) {
331
+ this.handlers[k]?.handlers?.dom?.[event]?.(e);
332
+ }
333
+ });
334
+ }
335
+
336
+ for (const event of [
337
+ 'mousedown',
338
+ 'transformstart',
339
+ 'transform',
340
+ 'transformend',
341
+ 'dragstart',
342
+ 'dragmove',
343
+ 'dragend',
344
+ 'mousemove',
345
+ 'mouseleave',
346
+ 'dblclick'
347
+ ]) {
348
+ this.transformer.on(event, (e) => {
349
+ e?.evt?.preventDefault();
350
+ for (const k in this.draws) {
351
+ this.draws[k]?.handlers?.transformer?.[event]?.(e);
352
+ }
353
+ for (const k in this.handlers) {
354
+ this.handlers[k]?.handlers?.transformer?.[event]?.(e);
355
+ }
356
+ });
357
+ }
358
+
359
+ this.handlers[SelectionHandlers.name]?.transformerConfig?.anchorDragBoundFunc &&
360
+ this.transformer.anchorDragBoundFunc(
361
+ this.handlers[SelectionHandlers.name].transformerConfig!.anchorDragBoundFunc!
362
+ );
363
+ }
364
+
365
+ // 获取 stage 状态
366
+ getStageState() {
367
+ return {
368
+ width: this.stage.width() - this.rulerSize,
369
+ height: this.stage.height() - this.rulerSize,
370
+ scale: this.stage.scaleX(),
371
+ x: this.stage.x(),
372
+ y: this.stage.y()
373
+ };
374
+ }
375
+
376
+ // 相对大小(基于 stage,且无视 scale)
377
+ toStageValue(boardPos: number) {
378
+ return boardPos / this.stage.scaleX();
379
+ }
380
+
381
+ // 绝对大小(基于可视区域像素)
382
+ toBoardValue(stagePos: number) {
383
+ return stagePos * this.stage.scaleX();
384
+ }
385
+
386
+ // 忽略非素材
387
+ ignore(node: Konva.Node) {
388
+ // 素材有各自根 group
389
+ const isGroup = node instanceof Konva.Group;
390
+ return !isGroup || this.ignoreSelect(node) || this.ignoreDraw(node) || this.ignoreLink(node);
391
+ }
392
+
393
+ // 忽略 选择时 辅助元素
394
+ ignoreSelect(node: Konva.Node) {
395
+ return node.id() === 'selectRect' || node.id() === 'hoverRect';
396
+ }
397
+
398
+ // 忽略各 draw 的根 group
399
+ ignoreDraw(node: Konva.Node) {
400
+ return [BgDraw.name, RulerDraw.name, RefLineDraw.name, ContextmenuDraw.name, PreviewDraw.name, LinkDraw.name, GraphDraw.name].includes(node.name());
401
+ }
402
+
403
+ // 忽略各 draw 的根 group
404
+ ignoreLink(node: Konva.Node) {
405
+ return ["link-anchor", "linking-line", "link-point", "link-line", "link-manual-point"].includes(node.name());
406
+ }
407
+
408
+ // 重绘(可选择)
409
+ redraw(drawNames?: string[]) {
410
+ const all = [
411
+ // layerFloor
412
+ BgDraw.name, // 更新背景
413
+ // layerCover(按先后顺序)
414
+ GraphDraw.name, // 更新图形调整点
415
+ LinkDraw.name, // 更新连线
416
+ RulerDraw.name, // 更新比例尺
417
+ RefLineDraw.name, // 更新参考线
418
+ PreviewDraw.name, // 更新预览
419
+ ContextmenuDraw.name // 更新右键菜单
420
+ ];
421
+
422
+ // 可以以此发现缺失的 draw
423
+ // console.log('redraw', drawNames)
424
+
425
+ if (Array.isArray(drawNames)) {
426
+ // 选择性 draw 也要保持顺序
427
+ for (const name of all) {
428
+ if (drawNames.includes(name)) {
429
+ this.draws[name]?.draw();
430
+ }
431
+ }
432
+ } else {
433
+ for (const name of all) {
434
+ this.draws[name]?.draw();
435
+ }
436
+ }
437
+ }
438
+
439
+ changeDraggable(disabled: boolean) {
440
+ this.layer.children.forEach((asset) => {
441
+ asset.draggable(disabled);
442
+ });
443
+ }
444
+
445
+ // 改变画图类型
446
+ changeGraphType(type?: GraphType) {
447
+ if (type) {
448
+ this.texting = false;
449
+ this.emit('texting-change', this.texting);
450
+ }
451
+ this.graphType = type;
452
+ this.emit('graph-type-change', this.graphType);
453
+ // 绘制 Graph 的时候,不允许直接拖动其他素材
454
+ this.changeDraggable(!this.config.readonly && this.graphType === void 0);
455
+ }
456
+
457
+ // 添加文字状态
458
+ changeTexting(texting: boolean) {
459
+ if (texting) {
460
+ this.graphType = undefined;
461
+ this.emit('graph-type-change', this.graphType);
462
+ }
463
+ this.texting = texting;
464
+ this.emit('texting-change', this.texting);
465
+ document.body.style.cursor = this.texting ? 'text' : 'default';
466
+ }
467
+
468
+ // 更改网格显示
469
+ changeShowGrid(show: boolean) {
470
+ this.showGrid = show;
471
+ (this.draws[BgDraw.name] as BgDraw)?.updateOption({ showGrid: show });
472
+ }
473
+
474
+ // 更改磁吸显示
475
+ changeShowAttract(show: boolean) {
476
+ this.showAttract = show;
477
+ }
478
+
479
+ // 页面设置 默认值
480
+ static PageSettingsDefault: PageSettings = {
481
+ // 画布默认尺寸
482
+ pageWidth: 1280,
483
+ pageHeight: 720,
484
+ // 样式默认值
485
+ background: undefined,
486
+ stroke: 'rgb(0,0,0)',
487
+ strokeWidth: 1,
488
+ fill: 'rgb(0,0,0)',
489
+ linkStroke: 'rgb(0,0,0)',
490
+ linkStrokeWidth: 1,
491
+ fontSize: 24,
492
+ textFill: 'rgb(0,0,0)'
493
+ };
494
+
495
+ // 获取页面设置
496
+ getPageSettings(): PageSettings {
497
+ return this.stage.attrs.pageSettings ?? { ...Render.PageSettingsDefault };
498
+ }
499
+
500
+ // 更新页面设置
501
+ setPageSettings(settings: PageSettings, update = false) {
502
+ this.stage.setAttr('pageSettings', settings);
503
+ this.emit('page-settings-change', settings);
504
+ // 更新背景
505
+ this.updateBackground();
506
+ if (update) {
507
+ // 更新历史
508
+ this.updateHistory();
509
+ }
510
+ }
511
+
512
+ // 获取背景
513
+ getBackground() {
514
+ return this.draws[BgDraw.name]?.layer.findOne(`.${BgDraw.name}__background`) as Konva.Rect;
515
+ }
516
+
517
+ // 更新背景
518
+ updateBackground() {
519
+ this.draws[BgDraw.name]?.draw();
520
+ this.draws[GraphDraw.name]?.draw();
521
+ this.draws[LinkDraw.name]?.draw();
522
+ this.draws[PreviewDraw.name]?.draw();
523
+ }
524
+
525
+ // 素材设置 默认值
526
+ static AssetSettingsDefault: AssetSettings = {
527
+ stroke: '',
528
+ strokeWidth: 0,
529
+ fill: '',
530
+ arrowStart: false,
531
+ arrowEnd: false,
532
+ fontSize: 0,
533
+ textFill: '',
534
+ text: 'Text',
535
+ x: 0,
536
+ y: 0,
537
+ rotation: 0,
538
+ tension: 0
539
+ };
540
+
541
+ // 获取素材设置
542
+ getAssetSettings(asset?: Konva.Node): AssetSettings {
543
+ const base = asset?.attrs.assetSettings ?? { ...Render.AssetSettingsDefault };
544
+ return {
545
+ // 特定
546
+ ...base,
547
+ // 继承全局
548
+ stroke: base.stroke || this.getPageSettings().stroke,
549
+ strokeWidth: base.strokeWidth || this.getPageSettings().strokeWidth,
550
+ fontSize: base.fontSize || this.getPageSettings().fontSize,
551
+ textFill: base.textFill || this.getPageSettings().textFill,
552
+ // 绘制图形,默认不填充
553
+ fill:
554
+ base.fill ||
555
+ (asset?.attrs.assetType === AssetType.Graph
556
+ ? 'transparent'
557
+ : this.getPageSettings().fill),
558
+ x: parseFloat((asset?.position().x ?? 0).toFixed(1)),
559
+ y: parseFloat((asset?.position().y ?? 0).toFixed(1)),
560
+ rotation: parseFloat((asset?.rotation() ?? 0).toFixed(1)),
561
+ tension:
562
+ asset?.attrs.assetType === AssetType.Graph &&
563
+ asset?.attrs.graphType === "Curve"
564
+ ? base.tension
565
+ : undefined
566
+ };
567
+ }
568
+
569
+ // 设置 svgXML 样式(部分)
570
+ setSvgXMLSettings(xml: string, settings: AssetSettings) {
571
+ const reg = /<(circle|ellipse|line|path|polygon|rect|text|textPath|tref|tspan)[^>/]*\/?>/g;
572
+ const shapes = xml.match(reg);
573
+ const regStroke = / stroke="([^"]*)"/;
574
+ const regFill = / fill="([^"]*)"/;
575
+
576
+ for (const shape of shapes ?? []) {
577
+ let result = shape;
578
+ if (settings.stroke) {
579
+ if (regStroke.test(shape)) {
580
+ result = result.replace(regStroke, ` stroke="${settings.stroke}"`);
581
+ } else {
582
+ result = result.replace(/(<[^>/]*)(\/?>)/, `$1 stroke="${settings.stroke}" $2`);
583
+ }
584
+ }
585
+
586
+ if (settings.fill) {
587
+ if (regFill.test(shape)) {
588
+ result = result.replace(regFill, ` fill="${settings.fill}"`);
589
+ } else {
590
+ result = result.replace(/(<[^>/]*)(\/?>)/, `$1 fill="${settings.fill}" $2`);
591
+ }
592
+ }
593
+
594
+ xml = xml.replace(shape, result);
595
+ }
596
+ return xml;
597
+ }
598
+
599
+ rotatePoint({ x, y }: { x: number; y: number }, rad: number) {
600
+ const rCos = Math.cos(rad);
601
+ const rSin = Math.sin(rad);
602
+ return { x: x * rCos - y * rSin, y: y * rCos + x * rSin };
603
+ }
604
+
605
+ rotateAroundCenter(node: Konva.Node, rotation: number) {
606
+ const topLeft = { x: -node.width() / 2, y: -node.height() / 2 };
607
+ const current = this.rotatePoint(topLeft, Konva.getAngle(node.rotation()));
608
+ const rotated = this.rotatePoint(topLeft, Konva.getAngle(rotation));
609
+ const dx = rotated.x - current.x;
610
+ const dy = rotated.y - current.y;
611
+
612
+ node.rotation(rotation);
613
+ node.x(node.x() + dx);
614
+ node.y(node.y() + dy);
615
+ }
616
+
617
+ // 更新素材设置
618
+ async setAssetSettings(asset: Konva.Node, settings: AssetSettings, update = false) {
619
+ asset.setAttr('assetSettings', settings);
620
+ if (asset instanceof Konva.Group) {
621
+ if (asset.attrs.imageType === ImageType.svg) {
622
+ const node = asset.children[0] as Konva.Shape;
623
+ if (node instanceof Konva.Image) {
624
+ if (node.attrs.svgXML) {
625
+ const n = await this.assetTool.loadSvgXML(
626
+ this.setSvgXMLSettings(node.attrs.svgXML, settings)
627
+ );
628
+ node.parent?.add(n);
629
+ node.remove();
630
+ node.destroy();
631
+ n.zIndex(0);
632
+ }
633
+ }
634
+ } else if (asset.attrs.assetType === AssetType.Graph) {
635
+ const node = asset.findOne('.graph');
636
+ if (node instanceof Konva.Shape) {
637
+ node.strokeWidth(settings.strokeWidth);
638
+ node.stroke(settings.stroke);
639
+ if (node instanceof Konva.Arrow) {
640
+ // 箭头跟随 stroke
641
+ node.fill(settings.stroke);
642
+ } else {
643
+ node.fill(settings.fill);
644
+ }
645
+ if (node instanceof Konva.Arrow) {
646
+ node.pointerAtBeginning(settings.arrowStart);
647
+ node.pointerAtEnding(settings.arrowEnd);
648
+ }
649
+ if (node instanceof Konva.Arrow && asset.attrs.graphType === "Curve") {
650
+ node.tension(settings.tension);
651
+ }
652
+ }
653
+ } else if (asset.attrs.assetType === AssetType.Text) {
654
+ const node = asset.findOne('Text');
655
+ const rect = asset.findOne('Rect');
656
+ if (node instanceof Konva.Text && rect instanceof Konva.Rect) {
657
+ let sizeChanged = false;
658
+ if (node.fontSize() !== settings.fontSize || node.text() !== settings.text) {
659
+ sizeChanged = true;
660
+ }
661
+
662
+ node.fill(settings.textFill);
663
+ node.fontSize(settings.fontSize);
664
+ node.text(settings.text);
665
+
666
+ // 内容为空时,给一个半透明背景色
667
+ rect.fill(node.text().trim() ? '' : 'rgba(0,0,0,0.1)');
668
+ rect.width(Math.max(node.width(), settings.fontSize));
669
+ rect.height(Math.max(node.height(), settings.fontSize));
670
+
671
+ // 刷新 transformer 大小
672
+ if (sizeChanged) {
673
+ this.selectionTool.select([asset]);
674
+ }
675
+ }
676
+ }
677
+
678
+ // rotate 会影响 position,不能同时改变
679
+ // 区分属性面板正在调整
680
+ if (Math.abs(settings.rotation - asset.rotation()) >= 0.1) {
681
+ this.rotateAroundCenter(asset, settings.rotation);
682
+ // 同步 position 的变化
683
+ this.emit('asset-position-change', [asset]);
684
+ } else {
685
+ const prevSettings = this.getAssetSettings(asset);
686
+ asset.position({
687
+ x: parseFloat(settings.x.toFixed(1)),
688
+ y: parseFloat(settings.y.toFixed(1))
689
+ });
690
+ // 外部调用变化同步
691
+ if (settings.x !== prevSettings.x || settings.y !== prevSettings.y) {
692
+ this.emit('asset-position-change', [asset]);
693
+ }
694
+ }
695
+ }
696
+
697
+ if (update) {
698
+ // 更新历史
699
+ this.updateHistory();
700
+ }
701
+
702
+ this.draws[BgDraw.name]?.draw();
703
+ this.draws[GraphDraw.name]?.draw();
704
+ this.draws[LinkDraw.name]?.draw();
705
+ this.draws[PreviewDraw.name]?.draw();
706
+ }
707
+
708
+ // 连接线设置 默认值
709
+ static LinkSettingsDefault: LinkSettings = {
710
+ stroke: '',
711
+ strokeWidth: 0,
712
+ arrowStart: false,
713
+ arrowEnd: false,
714
+ tension: 0
715
+ };
716
+
717
+ // 连接线设置
718
+ async setLinkSettings(link: Konva.Line, settings: LinkSettings, update = false) {
719
+ const group = this.layer.findOne(`#${link.attrs.groupId}`);
720
+ if (Array.isArray(group?.attrs.points)) {
721
+ const point = (group?.attrs.points as LinkDrawPoint[]).find(
722
+ (o: LinkDrawPoint) => o.id === link.attrs.pointId
723
+ );
724
+ if (point) {
725
+ const pair = point.pairs.find((o) => o.id === link.attrs.pairId);
726
+ if (pair) {
727
+ pair.style = {
728
+ ...pair.style,
729
+ ...settings,
730
+ strokeWidth: Number(settings.strokeWidth ?? pair.style.strokeWidth),
731
+ };
732
+ group.setAttr('points', group?.attrs.points);
733
+ }
734
+ }
735
+ }
736
+
737
+ if (update) {
738
+ // 更新历史
739
+ this.updateHistory();
740
+ }
741
+
742
+ this.draws[BgDraw.name]?.draw();
743
+ this.draws[GraphDraw.name]?.draw();
744
+ this.draws[LinkDraw.name]?.draw();
745
+ this.draws[PreviewDraw.name]?.draw();
746
+ }
747
+
748
+ // 获取连接线设置
749
+ getLinkSettings(link?: Konva.Line): LinkSettings {
750
+ let settings: (Konva.LineConfig & LinkSettings) | undefined = undefined;
751
+ if (link) {
752
+ const group = this.layer.findOne(`#${link.attrs.groupId}`);
753
+ if (Array.isArray(group?.attrs.points)) {
754
+ const point = (group?.attrs.points as LinkDrawPoint[]).find(
755
+ (o: LinkDrawPoint) => o.id === link.attrs.pointId
756
+ );
757
+ if (point) {
758
+ const pair = point.pairs.find((o) => o.id === link.attrs.pairId);
759
+ if (pair) {
760
+ settings = pair.style;
761
+ }
762
+ }
763
+ }
764
+ }
765
+
766
+ const base = settings ?? { ...Render.LinkSettingsDefault };
767
+
768
+ return {
769
+ // 特定
770
+ ...base,
771
+ // 继承全局
772
+ stroke: (base.stroke as string) || this.getPageSettings().linkStroke,
773
+ strokeWidth: base.strokeWidth || this.getPageSettings().linkStrokeWidth
774
+ };
775
+ }
776
+ }