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,163 @@
1
+ import Konva from 'konva';
2
+ import { Draw, BaseDraw, Render } from '../types';
3
+
4
+ // 画布
5
+
6
+ export interface BgDrawOption {
7
+ size: number;
8
+ readonly?: boolean;
9
+ showGrid?: boolean;
10
+ }
11
+
12
+ export class BgDraw extends BaseDraw implements Draw {
13
+ // @ts-ignore
14
+ static override readonly name = 'bg';
15
+ option: BgDrawOption;
16
+
17
+ // 独立容器:用于存放静态的背景和画布
18
+ private staticGroup: Konva.Group;
19
+ // 独立容器:专门用于存放动态网格
20
+ private gridGroup: Konva.Group;
21
+ // 标记静态元素是否需要重绘
22
+ private isStaticInitialized: boolean = false;
23
+
24
+ constructor(render: Render, layer: Konva.Layer, option: BgDrawOption) {
25
+ super(render, layer);
26
+ this.option = option;
27
+ this.group.listening(false);
28
+
29
+ // 预先创建好两个独立的 Group
30
+ this.staticGroup = new Konva.Group({ name: 'bg-static', listening: false });
31
+ this.gridGroup = new Konva.Group({ name: 'bg-grid', listening: false });
32
+
33
+ // 注意添加顺序:静态在下,网格在上
34
+ this.group.add(this.staticGroup);
35
+ this.group.add(this.gridGroup);
36
+
37
+ // 监听页面配置变化,当配置改变时,重置静态层初始化状态
38
+ this.render.on('page-settings-change', () => {
39
+ this.isStaticInitialized = false;
40
+ // 触发整体重绘,让 draw 方法重新执行
41
+ this.draw();
42
+ });
43
+ }
44
+
45
+ // 更新配置项,触发重绘
46
+ public updateOption(newOption: Partial<BgDrawOption>) {
47
+ this.option = { ...this.option, ...newOption };
48
+ this.draw();
49
+ }
50
+
51
+ override draw() {
52
+ // 1. 如果静态元素未初始化,或者配置发生变化导致标记被重置,则重新绘制
53
+ if (!this.isStaticInitialized) {
54
+ this.renderStaticElements();
55
+ this.isStaticInitialized = true;
56
+ }
57
+ // 2. 仅重绘网格部分(拖拽/缩放时高频调用)
58
+ if (!this.option.readonly && this.option.showGrid) { // 只读页面不显示网格
59
+ this.renderGrid();
60
+ } else { // 清除已渲染网格
61
+ this.gridGroup.destroyChildren();
62
+ }
63
+ }
64
+
65
+ /**
66
+ * 渲染静态元素(仅在初始化或配置改变时执行)
67
+ */
68
+ private renderStaticElements() {
69
+ // 清除旧的静态元素
70
+ this.staticGroup.destroyChildren();
71
+ const { width, height, x, y } = this.render.getStageState();
72
+ const { pageWidth, pageHeight, background, backgroundImg } = this.render.getPageSettings();
73
+
74
+ // 背景层(填满整个 stage)
75
+ const bgRect = new Konva.Rect({
76
+ name: `${this.constructor.name}__background`,
77
+ x: this.render.toStageValue(-x + this.render.rulerSize),
78
+ y: this.render.toStageValue(-y + this.render.rulerSize),
79
+ width: this.render.toStageValue(width),
80
+ height: this.render.toStageValue(height),
81
+ listening: false,
82
+ fill: 'transparent'
83
+ });
84
+
85
+ // 画布边框
86
+ const canvas = new Konva.Rect({
87
+ name: this.constructor.name,
88
+ x: 0,
89
+ y: 0,
90
+ width: pageWidth,
91
+ height: pageHeight,
92
+ stroke: this.option.readonly ? "transparent" : 'rgba(255,0,0,0.3)',
93
+ strokeWidth: this.render.toStageValue(2),
94
+ listening: false,
95
+ dash: [this.render.toStageValue(6), this.render.toStageValue(6)],
96
+ fill: background || 'transparent',
97
+ });
98
+
99
+ this.staticGroup.add(bgRect);
100
+ this.staticGroup.add(canvas);
101
+
102
+ // 处理背景图(异步)
103
+ if (backgroundImg?.src) {
104
+ const img = new Image();
105
+ img.crossOrigin = 'anonymous'; // 如果图片在 CDN 上,必须加上此属性防止跨域问题
106
+ img.src = backgroundImg.src;
107
+ img.onload = () => {
108
+ canvas.fill(null);
109
+ canvas.fillPatternImage(img);
110
+ canvas.fillPatternRepeat('no-repeat');
111
+ // 让图片自适应填满矩形(等比缩放裁剪效果)
112
+ const scaleX = pageWidth / img.width;
113
+ const scaleY = pageHeight / img.height;
114
+ canvas.fillPatternScaleX(scaleX);
115
+ canvas.fillPatternScaleY(scaleY);
116
+ };
117
+ }
118
+ }
119
+
120
+ /**
121
+ * 渲染网格(每次拖拽/缩放时调用)
122
+ */
123
+ private renderGrid() {
124
+ // 仅清空网格 Group,不影响静态层
125
+ this.gridGroup.destroyChildren();
126
+ const { width, height, x, y } = this.render.getStageState();
127
+ const cellSize = this.option.size;
128
+ const lenX = Math.ceil(this.render.toStageValue(width + this.render.rulerSize) / cellSize);
129
+ const lenY = Math.ceil(this.render.toStageValue(height + this.render.rulerSize) / cellSize);
130
+ const startX = -Math.ceil(this.render.toStageValue(x) / cellSize);
131
+ const startY = -Math.ceil(this.render.toStageValue(y) / cellSize);
132
+ const lines: Konva.Line[] = [];
133
+
134
+ // 生成竖线
135
+ for (let i = startX; i < lenX + startX + 2; i++) {
136
+ lines.push(new Konva.Line({
137
+ points: [
138
+ cellSize * i, this.render.toStageValue(-y + this.render.rulerSize),
139
+ cellSize * i, this.render.toStageValue(height - y + this.render.rulerSize)
140
+ ],
141
+ stroke: '#ddd',
142
+ strokeWidth: this.render.toStageValue(1),
143
+ listening: false
144
+ }));
145
+ }
146
+
147
+ // 生成横线
148
+ for (let j = startY; j < lenY + startY + 2; j++) {
149
+ lines.push(new Konva.Line({
150
+ points: [
151
+ this.render.toStageValue(-x + this.render.rulerSize), cellSize * j,
152
+ this.render.toStageValue(width - x + this.render.rulerSize), cellSize * j
153
+ ],
154
+ stroke: '#ddd',
155
+ strokeWidth: this.render.toStageValue(1),
156
+ listening: false
157
+ }));
158
+ }
159
+
160
+ // 批量添加线条到网格 Group
161
+ this.gridGroup.add(...lines);
162
+ }
163
+ }
@@ -0,0 +1,307 @@
1
+ import Konva from 'konva';
2
+ import { BaseDraw, Draw, Render, MouseButton } from '../types';
3
+ import { LinkDraw } from '../draws';
4
+
5
+ // 右键菜单
6
+
7
+ export interface ContextmenuDrawOption { }
8
+
9
+ export class ContextmenuDraw extends BaseDraw implements Draw {
10
+ // @ts-ignore
11
+ static override readonly name = 'contextmenu';
12
+ option: ContextmenuDrawOption;
13
+ state: {
14
+ target: Konva.Node | null, // 右键目标节点(或空白处)
15
+ menuIsMousedown: boolean, // 菜单被鼠标按下状态
16
+ lastPos: Konva.Vector2d | null, // 记录鼠标按下位置(用于判断按下和释放的时候是不是同一位置)
17
+ right: boolean, // 鼠标按下的是否是右键
18
+ }
19
+
20
+ constructor(render: Render, layer: Konva.Layer, option: ContextmenuDrawOption) {
21
+ super(render, layer);
22
+ this.option = option;
23
+ this.state = { target: null, menuIsMousedown: false, lastPos: null, right: false };
24
+ }
25
+
26
+ override draw() {
27
+ this.clear();
28
+ if (this.state.target) {
29
+ // 菜单数组
30
+ const menus: Array<{ name: string, action: (e: Konva.KonvaEventObject<MouseEvent>) => void }> = [];
31
+ if (this.state.target === this.render.stage) {
32
+ // 空白处
33
+ menus.push({
34
+ name: '自适应大小',
35
+ action: () => this.render.positionTool.positionFit()
36
+ });
37
+ menus.push({
38
+ name: '恢复位置',
39
+ action: () => this.render.positionTool.positionReset()
40
+ });
41
+ menus.push({
42
+ name: '恢复大小位置',
43
+ action: () => this.render.positionTool.positionZoomReset()
44
+ });
45
+ } else if (!this.render.config.readonly) {
46
+ if (this.state.target.name() === 'link-line') {
47
+ menus.push({
48
+ name: '删除', // 删除连接线
49
+ action: () => this.render.linkTool.remove(this.state.target as Konva.Line)
50
+ });
51
+ } else {
52
+ // 未选择:真实节点,即素材的容器 group
53
+ // 已选择:transformer
54
+ const target = this.state.target.parent;
55
+ // 目标
56
+ menus.push({
57
+ name: '复制',
58
+ action: () => {
59
+ if (target) {
60
+ this.render.copyTool.copy([target]);
61
+ }
62
+ }
63
+ });
64
+ menus.push({
65
+ name: '删除',
66
+ action: () => {
67
+ if (target) {
68
+ this.render.remove([target]);
69
+ }
70
+ }
71
+ });
72
+ menus.push({
73
+ name: '上移',
74
+ action: () => {
75
+ if (target) {
76
+ this.render.zIndexTool.up([target]);
77
+ }
78
+ }
79
+ });
80
+ menus.push({
81
+ name: '下移',
82
+ action: () => {
83
+ if (target) {
84
+ this.render.zIndexTool.down([target]);
85
+ }
86
+ }
87
+ });
88
+ menus.push({
89
+ name: '置顶',
90
+ action: () => {
91
+ if (target) {
92
+ this.render.zIndexTool.top([target]);
93
+ }
94
+ }
95
+ });
96
+ menus.push({
97
+ name: '置底',
98
+ action: () => {
99
+ if (target) {
100
+ this.render.zIndexTool.bottom([target]);
101
+ }
102
+ }
103
+ });
104
+ if (target instanceof Konva.Transformer) {
105
+ const pos = this.render.stage.getPointerPosition();
106
+ if (pos) {
107
+ // 获取所有图形
108
+ const shapes = target.nodes();
109
+ if (shapes.length > 1) {
110
+ // zIndex 倒序(大的优先)
111
+ shapes.sort((a, b) => b.zIndex() - a.zIndex());
112
+ // 提取重叠目标
113
+ const selected = shapes.find((shape) =>
114
+ // 关键 api
115
+ Konva.Util.haveIntersection(
116
+ { ...pos, width: 1, height: 1 },
117
+ shape.getClientRect()
118
+ )
119
+ );
120
+ // 对齐菜单
121
+ menus.push({
122
+ name: '垂直居中' + (selected ? '于目标' : ''),
123
+ action: () => this.render.alignTool.align("Middle", selected)
124
+ });
125
+ menus.push({
126
+ name: '左对齐' + (selected ? '于目标' : ''),
127
+ action: () => this.render.alignTool.align("Left", selected)
128
+ });
129
+ menus.push({
130
+ name: '右对齐' + (selected ? '于目标' : ''),
131
+ action: () => this.render.alignTool.align("Right", selected)
132
+ });
133
+ menus.push({
134
+ name: '水平居中' + (selected ? '于目标' : ''),
135
+ action: () => this.render.alignTool.align("Center", selected)
136
+ });
137
+ menus.push({
138
+ name: '上对齐' + (selected ? '于目标' : ''),
139
+ action: () => this.render.alignTool.align("Top", selected)
140
+ });
141
+ menus.push({
142
+ name: '下对齐' + (selected ? '于目标' : ''),
143
+ action: () => this.render.alignTool.align("Bottom", selected)
144
+ });
145
+ }
146
+ }
147
+ }
148
+ }
149
+ }
150
+
151
+ // stage 状态
152
+ const stageState = this.render.getStageState();
153
+ // 绘制右键菜单
154
+ const group = new Konva.Group({
155
+ name: 'contextmenu',
156
+ width: stageState.width,
157
+ height: stageState.height
158
+ });
159
+ let top = 0;
160
+ // 菜单每项高度
161
+ const lineHeight = 30;
162
+ const pos = this.render.stage.getPointerPosition();
163
+ if (pos) {
164
+ for (const menu of menus) {
165
+ // 框
166
+ const rect = new Konva.Rect({
167
+ x: this.render.toStageValue(pos.x - stageState.x),
168
+ y: this.render.toStageValue(pos.y + top - stageState.y),
169
+ width: this.render.toStageValue(150),
170
+ height: this.render.toStageValue(lineHeight),
171
+ fill: '#fff',
172
+ stroke: '#999',
173
+ strokeWidth: this.render.toStageValue(1),
174
+ name: 'contextmenu'
175
+ });
176
+ // 标题
177
+ const text = new Konva.Text({
178
+ x: this.render.toStageValue(pos.x - stageState.x),
179
+ y: this.render.toStageValue(pos.y + top - stageState.y),
180
+ text: menu.name,
181
+ name: 'contextmenu',
182
+ listening: false,
183
+ fontSize: this.render.toStageValue(16),
184
+ fill: '#333',
185
+ width: this.render.toStageValue(150),
186
+ height: this.render.toStageValue(lineHeight),
187
+ align: 'center',
188
+ verticalAlign: 'middle'
189
+ });
190
+ group.add(rect);
191
+ group.add(text);
192
+ // 菜单事件
193
+ rect.on('pointerclick', (e) => {
194
+ if (e.evt.button === MouseButton.左键) {
195
+ // 触发事件
196
+ menu.action(e);
197
+ // 移除菜单
198
+ this.group.getChildren().forEach((o) => {
199
+ o.destroy();
200
+ });
201
+ this.group.removeChildren();
202
+ this.state.target = null;
203
+ }
204
+ e.evt.preventDefault();
205
+ e.evt.stopPropagation();
206
+ })
207
+ rect.on('mousedown', (e) => {
208
+ if (e.evt.button === MouseButton.左键) {
209
+ this.state.menuIsMousedown = true;
210
+ // 按下效果
211
+ rect.fill('#dfdfdf');
212
+ }
213
+ e.evt.preventDefault();
214
+ e.evt.stopPropagation();
215
+ })
216
+ rect.on('mouseup', (e) => {
217
+ if (e.evt.button === MouseButton.左键) {
218
+ this.state.menuIsMousedown = false;
219
+ }
220
+ })
221
+ rect.on('mouseenter', (e) => {
222
+ if (this.state.menuIsMousedown) {
223
+ rect.fill('#dfdfdf');
224
+ } else {
225
+ // hover in
226
+ rect.fill('#efefef');
227
+ }
228
+ e.evt.preventDefault();
229
+ e.evt.stopPropagation();
230
+ })
231
+ rect.on('mouseout', () => {
232
+ // hover out
233
+ rect.fill('#fff');
234
+ })
235
+ rect.on('contextmenu', (e) => {
236
+ e.evt.preventDefault();
237
+ e.evt.stopPropagation();
238
+ })
239
+ top += lineHeight - 1;
240
+ }
241
+ }
242
+ this.group.add(group);
243
+ }
244
+ }
245
+
246
+ handlers = {
247
+ stage: {
248
+ mousedown: (e: Konva.KonvaEventObject<GlobalEventHandlersEventMap['mousedown']>) => {
249
+ this.state.lastPos = this.render.stage.getPointerPosition();
250
+ if (e.evt.button === MouseButton.左键) {
251
+ if (!this.state.menuIsMousedown) {
252
+ // 没有按下菜单,清除菜单
253
+ this.state.target = null;
254
+ this.draw();
255
+ }
256
+ } else if (e.evt.button === MouseButton.右键 && !e.evt.ctrlKey) {
257
+ // (判断 ctrlKey 为了排查 mac 拖动快捷键)
258
+ // 右键按下
259
+ this.state.right = true;
260
+ }
261
+ },
262
+ mousemove: () => {
263
+ if (this.state.target && this.state.right) {
264
+ // 拖动画布时(右键),清除菜单
265
+ this.state.target = null;
266
+ this.draw();
267
+ }
268
+ },
269
+ mouseup: () => {
270
+ this.state.right = false;
271
+ },
272
+ contextmenu: (e: Konva.KonvaEventObject<GlobalEventHandlersEventMap['contextmenu']>) => {
273
+ // (判断 ctrlKey 为了排查 mac 拖动快捷键)
274
+ if (!e.evt.ctrlKey) {
275
+ const pos = this.render.stage.getPointerPosition();
276
+ if (pos && this.state.lastPos) {
277
+ const linkGroup = this.render.layerCover.find(`.${LinkDraw.name}`)[0] as Konva.Group;
278
+ // 右键目标可能为 连接线
279
+ let lineSelection: Konva.Node | null = null;
280
+ if (linkGroup) {
281
+ const linkLines = linkGroup.find('.link-line');
282
+ for (const line of linkLines) {
283
+ if (Konva.Util.haveIntersection({ ...pos, width: 1, height: 1 }, line.getClientRect())) {
284
+ // 右键目标为 连接线
285
+ lineSelection = line;
286
+ break;
287
+ }
288
+ }
289
+ }
290
+ if (pos.x === this.state.lastPos.x || pos.y === this.state.lastPos.y) {
291
+ // 右键 连接线/其它目标
292
+ this.state.target = lineSelection ?? e.target;
293
+ } else {
294
+ this.state.target = null;
295
+ }
296
+ this.draw();
297
+ }
298
+ }
299
+ },
300
+ wheel: () => {
301
+ // 画布缩放时,清除菜单
302
+ this.state.target = null;
303
+ this.draw();
304
+ }
305
+ }
306
+ }
307
+ }