aldehyde 0.2.488 → 0.2.489

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