aldehyde 0.2.493 → 0.2.495

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 (138) hide show
  1. package/lib/controls/icon-selector/icon/phonenode-menu-icon/iconfont.css +63 -63
  2. package/lib/draw-canvas-edit/components/asset-bar/index.less +35 -35
  3. package/lib/draw-canvas-edit/components/main-header/index.less +23 -23
  4. package/lib/layout2/page.d.ts +2 -1
  5. package/lib/layout2/page.d.ts.map +1 -1
  6. package/lib/layout2/page.js +19 -8
  7. package/lib/layout2/page.js.map +1 -1
  8. package/lib/layout2/type/layout-type.d.ts +1 -0
  9. package/lib/layout2/type/layout-type.d.ts.map +1 -1
  10. package/lib/lowcode-components/base-table/index.less +61 -61
  11. package/lib/lowcode-components/base-text/index.less +19 -19
  12. package/lib/lowcode-components/column-chart/index.js +2 -2
  13. package/lib/lowcode-components/column-chart/index.js.map +1 -1
  14. package/lib/lowcode-components/data-number/index.less +10 -10
  15. package/lib/lowcode-components/date-time/index.less +4 -4
  16. package/lib/lowcode-components/four-angle-glow-border/index.less +49 -49
  17. package/lib/lowcode-components/line-bar-chart/index.d.ts.map +1 -1
  18. package/lib/lowcode-components/line-bar-chart/index.js +6 -2
  19. package/lib/lowcode-components/line-bar-chart/index.js.map +1 -1
  20. package/lib/lowcode-components/line-chart/index.d.ts.map +1 -1
  21. package/lib/lowcode-components/line-chart/index.js +6 -2
  22. package/lib/lowcode-components/line-chart/index.js.map +1 -1
  23. package/lib/lowcode-components/lowcode-view/component/font/FontGlobal.css +26 -26
  24. package/lib/lowcode-components/lowcode-view/component/screen-fit/index.less +13 -13
  25. package/lib/lowcode-components/text-scroller/index.less +28 -28
  26. package/lib/module/ltmpl-table.d.ts +7 -0
  27. package/lib/module/ltmpl-table.d.ts.map +1 -1
  28. package/lib/module/ltmpl-table.js +12 -16
  29. package/lib/module/ltmpl-table.js.map +1 -1
  30. package/lib/routable/dtmpl-route.d.ts.map +1 -1
  31. package/lib/routable/dtmpl-route.js +8 -2
  32. package/lib/routable/dtmpl-route.js.map +1 -1
  33. package/lib/routable/import-route.d.ts.map +1 -1
  34. package/lib/routable/import-route.js +9 -1
  35. package/lib/routable/import-route.js.map +1 -1
  36. package/lib/routable/ltmpl-route.d.ts.map +1 -1
  37. package/lib/routable/ltmpl-route.js +13 -6
  38. package/lib/routable/ltmpl-route.js.map +1 -1
  39. package/lib/routable/splitview-ltmpl-route.d.ts.map +1 -1
  40. package/lib/routable/splitview-ltmpl-route.js +11 -10
  41. package/lib/routable/splitview-ltmpl-route.js.map +1 -1
  42. package/lib/routable/ttmpl-route.d.ts.map +1 -1
  43. package/lib/routable/ttmpl-route.js +9 -2
  44. package/lib/routable/ttmpl-route.js.map +1 -1
  45. package/lib/table/act-table.d.ts +1 -0
  46. package/lib/table/act-table.d.ts.map +1 -1
  47. package/lib/table/act-table.js +31 -9
  48. package/lib/table/act-table.js.map +1 -1
  49. package/lib/table/page-chart.js +1 -1
  50. package/lib/table/page-chart.js.map +1 -1
  51. package/lib/table/row-table.d.ts +6 -0
  52. package/lib/table/row-table.d.ts.map +1 -1
  53. package/lib/table/row-table.js +21 -6
  54. package/lib/table/row-table.js.map +1 -1
  55. package/lib/tmpl/interface.d.ts +1 -0
  56. package/lib/tmpl/interface.d.ts.map +1 -1
  57. package/lib/tree/act-tree.d.ts +1 -0
  58. package/lib/tree/act-tree.d.ts.map +1 -1
  59. package/lib/tree/act-tree.js +6 -7
  60. package/lib/tree/act-tree.js.map +1 -1
  61. package/lib/tree/tree-utils.d.ts +1 -1
  62. package/lib/tree/tree-utils.d.ts.map +1 -1
  63. package/lib/tree/tree-utils.js +4 -4
  64. package/lib/tree/tree-utils.js.map +1 -1
  65. package/lib/units/index.d.ts +4 -0
  66. package/lib/units/index.d.ts.map +1 -1
  67. package/lib/units/index.js +10 -3
  68. package/lib/units/index.js.map +1 -1
  69. package/package.json +1 -1
  70. package/src/aldehyde/controls/icon-selector/icon/phonenode-menu-icon/iconfont.css +63 -63
  71. package/src/aldehyde/controls/icon-selector/icon/phonenode-menu-icon/iconfont.json +93 -93
  72. package/src/aldehyde/draw-canvas-edit/components/asset-bar/index.less +35 -35
  73. package/src/aldehyde/draw-canvas-edit/components/asset-bar/index.tsx +110 -110
  74. package/src/aldehyde/draw-canvas-edit/components/main-header/index.less +23 -23
  75. package/src/aldehyde/draw-canvas-edit/components/main-header/index.tsx +263 -263
  76. package/src/aldehyde/draw-canvas-edit/components/render/draws/index.ts +7 -7
  77. package/src/aldehyde/draw-canvas-edit/components/render/graphs/base-graph.ts +241 -241
  78. package/src/aldehyde/draw-canvas-edit/components/render/graphs/circle.ts +699 -699
  79. package/src/aldehyde/draw-canvas-edit/components/render/graphs/curve.ts +500 -500
  80. package/src/aldehyde/draw-canvas-edit/components/render/graphs/index.ts +5 -5
  81. package/src/aldehyde/draw-canvas-edit/components/render/graphs/line.ts +493 -493
  82. package/src/aldehyde/draw-canvas-edit/components/render/graphs/rect.ts +680 -680
  83. package/src/aldehyde/draw-canvas-edit/components/render/handlers/drag-handlers.ts +68 -68
  84. package/src/aldehyde/draw-canvas-edit/components/render/handlers/graph-handlers.ts +113 -113
  85. package/src/aldehyde/draw-canvas-edit/components/render/handlers/index.ts +9 -9
  86. package/src/aldehyde/draw-canvas-edit/components/render/handlers/key-move-handlers.ts +49 -49
  87. package/src/aldehyde/draw-canvas-edit/components/render/handlers/link-handlers.ts +45 -45
  88. package/src/aldehyde/draw-canvas-edit/components/render/handlers/shutcut-handlers.ts +45 -45
  89. package/src/aldehyde/draw-canvas-edit/components/render/handlers/text-handlers.ts +81 -81
  90. package/src/aldehyde/draw-canvas-edit/components/render/handlers/zoom-handlers.ts +59 -59
  91. package/src/aldehyde/draw-canvas-edit/components/render/tools/align-tool.ts +89 -89
  92. package/src/aldehyde/draw-canvas-edit/components/render/tools/asset-tool.ts +154 -154
  93. package/src/aldehyde/draw-canvas-edit/components/render/tools/link-tool.ts +222 -222
  94. package/src/aldehyde/draw-canvas-edit/components/render/tools/z-index-tool.ts +224 -224
  95. package/src/aldehyde/draw-canvas-edit/components/render/utils/a-star.ts +116 -116
  96. package/src/aldehyde/draw-canvas-edit/components/render/utils/bezier-scene-func.ts +72 -72
  97. package/src/aldehyde/draw-canvas-edit/components/setting-form/imag-upload.tsx +119 -119
  98. package/src/aldehyde/layout2/page.tsx +17 -9
  99. package/src/aldehyde/layout2/type/layout-type.ts +1 -0
  100. package/src/aldehyde/layout4/imgs/user.svg +26 -26
  101. package/src/aldehyde/lowcode-components/base-color-block/index.tsx +31 -31
  102. package/src/aldehyde/lowcode-components/base-table/index.less +61 -61
  103. package/src/aldehyde/lowcode-components/base-text/index.less +19 -19
  104. package/src/aldehyde/lowcode-components/column-chart/index.tsx +2 -2
  105. package/src/aldehyde/lowcode-components/data-number/index.less +10 -10
  106. package/src/aldehyde/lowcode-components/date-time/index.less +4 -4
  107. package/src/aldehyde/lowcode-components/date-time/index.tsx +64 -64
  108. package/src/aldehyde/lowcode-components/four-angle-glow-border/index.less +49 -49
  109. package/src/aldehyde/lowcode-components/four-angle-glow-border/index.tsx +53 -53
  110. package/src/aldehyde/lowcode-components/line-bar-chart/index.tsx +5 -2
  111. package/src/aldehyde/lowcode-components/line-chart/index.tsx +5 -2
  112. package/src/aldehyde/lowcode-components/lowcode-view/component/abstract-controller.ts +64 -64
  113. package/src/aldehyde/lowcode-components/lowcode-view/component/abstract-definition.ts +77 -77
  114. package/src/aldehyde/lowcode-components/lowcode-view/component/abstract-designer-loader.ts +36 -36
  115. package/src/aldehyde/lowcode-components/lowcode-view/component/component-container.tsx +91 -91
  116. package/src/aldehyde/lowcode-components/lowcode-view/component/font/FontGlobal.css +26 -26
  117. package/src/aldehyde/lowcode-components/lowcode-view/component/group-layer/controller.ts +36 -36
  118. package/src/aldehyde/lowcode-components/lowcode-view/component/group-layer/definition.ts +53 -53
  119. package/src/aldehyde/lowcode-components/lowcode-view/component/group-layer/index.tsx +15 -15
  120. package/src/aldehyde/lowcode-components/lowcode-view/component/layer-builder.tsx +98 -98
  121. package/src/aldehyde/lowcode-components/lowcode-view/component/screen-fit/index.less +13 -13
  122. package/src/aldehyde/lowcode-components/lowcode-view/component/screen-fit/index.tsx +121 -121
  123. package/src/aldehyde/lowcode-components/placeholder-component/index.tsx +81 -81
  124. package/src/aldehyde/lowcode-components/text-scroller/index.less +28 -28
  125. package/src/aldehyde/lowcode-components/text-scroller/index.tsx +173 -173
  126. package/src/aldehyde/module/ltmpl-table.tsx +14 -15
  127. package/src/aldehyde/routable/dtmpl-route.tsx +14 -8
  128. package/src/aldehyde/routable/import-route.tsx +12 -5
  129. package/src/aldehyde/routable/ltmpl-route.tsx +14 -9
  130. package/src/aldehyde/routable/splitview-ltmpl-route.tsx +11 -8
  131. package/src/aldehyde/routable/ttmpl-route.tsx +13 -8
  132. package/src/aldehyde/table/act-table.tsx +28 -9
  133. package/src/aldehyde/table/page-chart.tsx +1 -1
  134. package/src/aldehyde/table/row-table.tsx +29 -6
  135. package/src/aldehyde/tmpl/interface.tsx +1 -0
  136. package/src/aldehyde/tree/act-tree.tsx +8 -6
  137. package/src/aldehyde/tree/tree-utils.tsx +4 -4
  138. package/src/aldehyde/units/index.tsx +11 -3
@@ -1,501 +1,501 @@
1
- import Konva from 'konva';
2
- import { GraphAnchor, Render, AssetInfoPoint, LineManualPoint } from '../types';
3
- import { GraphDraw, LinkDraw, PreviewDraw } from '../draws';
4
- import { BaseGraph } from './base-graph';
5
-
6
- /**
7
- * 曲线
8
- */
9
- export class Curve extends BaseGraph {
10
- // 实现:更新 图形 的 调整点 的 锚点位置
11
- static override updateAnchorShadows(graph: Konva.Group, anchorShadows: Konva.Circle[], shape?: Konva.Line): void {
12
- if (shape) {
13
- const points = shape.points();
14
- for (const shadow of anchorShadows) {
15
- switch (shadow.attrs.adjustType) {
16
- case 'start':
17
- shadow.position({ x: points[0], y: points[1] });
18
- break;
19
- case 'end':
20
- shadow.position({ x: points[points.length - 2], y: points[points.length - 1] });
21
- break;
22
- }
23
- }
24
- }
25
- }
26
-
27
- // 实现:更新 图形 的 连接点 的 锚点位置
28
- static override updateLinkAnchorShadows(graph: Konva.Group, linkAnchorShadows: Konva.Circle[], shape?: Konva.Line): void {
29
- if (shape) {
30
- const points = shape.points();
31
- for (const shadow of linkAnchorShadows) {
32
- switch (shadow.attrs.alias) {
33
- case 'start':
34
- shadow.position({ x: points[0], y: points[1] });
35
- break;
36
- case 'end':
37
- shadow.position({ x: points[points.length - 2], y: points[points.length - 1] });
38
- break;
39
- }
40
- }
41
- }
42
- }
43
-
44
- static calculateAngle(sideA: number, sideB: number) {
45
- if (!isNaN(sideA) && !isNaN(sideB)) {
46
- const angleInRadians = Math.atan2(sideA, sideB);
47
- const angleInDegrees = angleInRadians * (180 / Math.PI);
48
- return angleInDegrees;
49
- }
50
- return 0;
51
- }
52
-
53
- // 实现:生成 调整点
54
- static override createAnchorShapes(
55
- render: Render,
56
- graph: Konva.Group,
57
- anchorAndShadows: {
58
- anchor: GraphAnchor;
59
- anchorShadow: Konva.Circle;
60
- shape?: Konva.Shape;
61
- }[],
62
- // eslint-disable-next-line
63
- adjustAnchor?: GraphAnchor
64
- ): {
65
- anchorAndShadows: {
66
- anchor: GraphAnchor;
67
- anchorShadow: Konva.Circle;
68
- shape?: Konva.Shape | undefined;
69
- }[]
70
- } {
71
- const stageState = render.getStageState();
72
- const graphShape = graph.findOne('.graph') as Konva.Line;
73
- if (graphShape) {
74
- const points = graphShape.points();
75
- for (const anchorAndShadow of anchorAndShadows) {
76
- let rotate = 0;
77
- const { anchor, anchorShadow } = anchorAndShadow;
78
- const x = render.toStageValue(anchorShadow.getAbsolutePosition().x - stageState.x),
79
- y = render.toStageValue(anchorShadow.getAbsolutePosition().y - stageState.y);
80
- if (anchor.adjustType === 'manual') {
81
- const anchorShape = new Konva.Circle({
82
- name: 'anchor',
83
- anchor: anchor,
84
- fill: anchor.adjusted ? `rgba(0,0,0,0.4)` : `rgba(0,0,255,0.4)`,
85
- radius: render.toStageValue(5),
86
- strokeWidth: 0,
87
- x: x,
88
- y: y,
89
- rotation: graph.getAbsoluteRotation(),
90
- visible: graph.attrs.adjusting || graph.attrs.hover === true
91
- });
92
- anchorShape.on('mouseenter', () => {
93
- document.body.style.cursor = 'move';
94
- graph.setAttr('hover', true);
95
- graph.setAttr('hoverAnchor', true);
96
- });
97
- anchorShape.on('mouseleave', () => {
98
- document.body.style.cursor = anchorShape.attrs.adjusting ? 'move' : 'default';
99
- graph.setAttr('hover', false);
100
- graph.setAttr('hoverAnchor', false);
101
- render.redraw([GraphDraw.NAME]);
102
- });
103
- anchorAndShadow.shape = anchorShape;
104
- } else {
105
- if (anchor.adjustType === 'start') {
106
- rotate = Curve.calculateAngle(points[2] - points[0], points[3] - points[1]);
107
- } else if (anchor.adjustType === 'end') {
108
- rotate = Curve.calculateAngle(points[points.length - 2] - points[points.length - 4], points[points.length - 1] - points[points.length - 3]);
109
- }
110
- const cos = Math.cos((rotate * Math.PI) / 180);
111
- const sin = Math.sin((rotate * Math.PI) / 180);
112
- const offset = render.toStageValue(render.pointSize - 20);
113
- const offsetX = offset * sin;
114
- const offsetY = offset * cos;
115
- const anchorShape = new Konva.Circle({
116
- name: 'anchor',
117
- anchor: anchor,
118
- fill: `rgba(0,0,255,0.4)`,
119
- radius: render.toStageValue(5),
120
- strokeWidth: 0,
121
- x: x,
122
- y: y,
123
- offsetX: anchor.adjustType === 'start' ? offsetX : anchor.adjustType === 'end' ? -offsetX : 0,
124
- offsetY: anchor.adjustType === 'start' ? offsetY : anchor.adjustType === 'end' ? -offsetY : 0,
125
- rotation: graph.getAbsoluteRotation(),
126
- visible: graph.attrs.adjusting || graph.attrs.hover === true
127
- });
128
- anchorShape.on('mouseenter', () => {
129
- document.body.style.cursor = 'move';
130
- graph.setAttr('hover', true);
131
- graph.setAttr('hoverAnchor', true);
132
- });
133
- anchorShape.on('mouseleave', () => {
134
- document.body.style.cursor = anchorShape.attrs.adjusting ? 'move' : 'default';
135
- graph.setAttr('hover', false);
136
- graph.setAttr('hoverAnchor', false);
137
- render.redraw([GraphDraw.NAME]);
138
- });
139
- anchorAndShadow.shape = anchorShape;
140
- }
141
- }
142
- }
143
- return { anchorAndShadows };
144
- }
145
-
146
- /**
147
- * 矩阵变换:坐标系中的一个点,围绕着另外一个点进行旋转
148
- * - - - - - - - -
149
- * |x`| |cos -sin| |x-a| |a|
150
- * | | = | | | | +
151
- * |y`| |sin cos| |y-b| |b|
152
- * - - - - - - - -
153
- * @param x 目标节点坐标 x
154
- * @param y 目标节点坐标 y
155
- * @param centerX 围绕的点坐标 x
156
- * @param centerY 围绕的点坐标 y
157
- * @param angle 旋转角度
158
- * @returns
159
- */
160
- static rotatePoint(x: number, y: number, centerX: number, centerY: number, angle: number) {
161
- // 将角度转换为弧度
162
- const radians = (angle * Math.PI) / 180;
163
- // 计算旋转后的坐标
164
- const newX = Math.cos(radians) * (x - centerX) - Math.sin(radians) * (y - centerY) + centerX;
165
- const newY = Math.sin(radians) * (x - centerX) + Math.cos(radians) * (y - centerY) + centerY;
166
- return { x: newX, y: newY };
167
- }
168
-
169
- // 实现:调整 图形
170
- static override adjust(
171
- render: Render,
172
- graph: Konva.Group,
173
- graphSnap: Konva.Group,
174
- adjustShape: Konva.Shape,
175
- anchorAndShadows: {
176
- anchor: GraphAnchor;
177
- anchorShadow: Konva.Circle;
178
- shape?: Konva.Shape | undefined;
179
- }[],
180
- startPoint: Konva.Vector2d,
181
- endPoint: Konva.Vector2d,
182
- hoverRect?: Konva.Rect
183
- ) {
184
- // 目标 曲线
185
- const line = graph.findOne('.graph') as Konva.Line;
186
- const lineSnap = graphSnap.findOne('.graph') as Konva.Line;
187
- const anchors = (graph.find('.anchor') ?? []) as Konva.Circle[];
188
- const anchorsSnap = (graphSnap.find('.anchor') ?? []) as Konva.Circle[];
189
- const linkAnchors = (graph.find('.link-anchor') ?? []) as Konva.Circle[];
190
- if (line && lineSnap) {
191
- const stageState = render.getStageState();
192
- {
193
- const [graphRotation, adjustType, ex, ey] = [
194
- Math.round(graph.rotation()),
195
- adjustShape.attrs.anchor?.adjustType,
196
- endPoint.x,
197
- endPoint.y
198
- ];
199
- const { x: cx, y: cy, width: cw, height: ch } = graphSnap.getClientRect();
200
- const { x, y } = graph.position();
201
- const [centerX, centerY] = [cx + cw / 2, cy + ch / 2];
202
- const { x: sx, y: sy } = Curve.rotatePoint(ex, ey, centerX, centerY, -graphRotation);
203
- const { x: rx, y: ry } = Curve.rotatePoint(x, y, centerX, centerY, -graphRotation);
204
- const points = line.points();
205
- const manualPoints = (line.attrs.manualPoints ?? []) as LineManualPoint[];
206
- if (adjustType === 'manual') {
207
- if (adjustShape.attrs.anchor?.manualIndex !== void 0) {
208
- const index = adjustShape.attrs.anchor?.adjusted ? adjustShape.attrs.anchor?.manualIndex : adjustShape.attrs.anchor?.manualIndex + 1;
209
- const manualPointIndex = manualPoints.findIndex((o) => o.index === index);
210
- if (manualPointIndex > -1) {
211
- manualPoints[manualPointIndex].x = (sx - rx) / graph.scaleX();
212
- manualPoints[manualPointIndex].y = (sy - ry) / graph.scaleY();
213
- }
214
- const linkPoints = [
215
- [points[0], points[1]],
216
- ...manualPoints.sort((a, b) => a.index - b.index).map((o) => [o.x, o.y]),
217
- [points[points.length - 2], points[points.length - 1]]
218
- ];
219
- line.setAttr('manualPoints', manualPoints);
220
- line.points(linkPoints.flat());
221
- const adjustAnchorShadow = anchors.find((o) => o.attrs.adjustType === 'manual' && o.attrs.manualIndex === index);
222
- if (adjustAnchorShadow) {
223
- adjustAnchorShadow.position({
224
- x: (sx - rx) / graph.scaleX(),
225
- y: (sy - ry) / graph.scaleY()
226
- });
227
- }
228
- }
229
- } else {
230
- const anchor = anchors.find((o) => o.attrs.adjustType === adjustType);
231
- const anchorShadow = anchorsSnap.find((o) => o.attrs.adjustType === adjustType);
232
- if (anchor && anchorShadow) {
233
- const linkPoints = [
234
- [points[0], points[1]],
235
- ...manualPoints.sort((a, b) => a.index - b.index).map((o) => [o.x, o.y]),
236
- [points[points.length - 2], points[points.length - 1]]
237
- ];
238
- switch (adjustType) {
239
- case 'start':
240
- linkPoints[0] = [(sx - rx) / graph.scaleX(), (sy - ry) / graph.scaleY()];
241
- line.points(linkPoints.flat());
242
- break;
243
- case 'end':
244
- linkPoints[linkPoints.length - 1] = [(sx - rx) / graph.scaleX(), (sy - ry) / graph.scaleY()];
245
- line.points(linkPoints.flat());
246
- break;
247
- }
248
- }
249
- }
250
- }
251
- Curve.updateAnchor(render, graph);
252
- Curve.updateAnchorShadows(graph, anchors, line);
253
- Curve.updateLinkAnchorShadows(graph, linkAnchors, line);
254
- for (const anchor of anchors) {
255
- for (const { shape } of anchorAndShadows) {
256
- if (shape) {
257
- if (shape.attrs.anchor?.adjustType === anchor.attrs.adjustType) {
258
- const anchorShadow = graph.find(`.anchor`).find((o) => o.attrs.adjustType === anchor.attrs.adjustType);
259
- if (anchorShadow) {
260
- shape.position({
261
- x: render.toStageValue(anchorShadow.getAbsolutePosition().x - stageState.x),
262
- y: render.toStageValue(anchorShadow.getAbsolutePosition().y - stageState.y)
263
- });
264
- shape.rotation(graph.getAbsoluteRotation());
265
- }
266
- }
267
- }
268
- }
269
- }
270
- render.redraw([GraphDraw.NAME, LinkDraw.NAME, PreviewDraw.NAME]);
271
- }
272
- const allXs = line.points().reduce((arr, item, idx) => {
273
- if (idx % 2 === 0) arr.push(item);
274
- return arr;
275
- }, [] as number[]);
276
- const allYs = line.points().reduce((arr, item, idx) => {
277
- if (idx % 2 === 1) arr.push(item);
278
- return arr;
279
- }, [] as number[]);
280
- const minX = Math.min(...allXs);
281
- const maxX = Math.max(...allXs);
282
- const minY = Math.min(...allYs);
283
- const maxY = Math.max(...allYs);
284
- BaseGraph.adjust(
285
- render,
286
- graph,
287
- graphSnap,
288
- adjustShape,
289
- anchorAndShadows,
290
- startPoint,
291
- endPoint,
292
- hoverRect,
293
- { width: maxX - minX, height: maxY - minY },
294
- { x: minX, y: minY }
295
- );
296
- }
297
-
298
- /**
299
- * 提供给 GraphDraw draw 使用
300
- */
301
- static override draw(graph: Konva.Group, render: Render, adjustAnchor?: GraphAnchor) {
302
- const anchors = (graph.attrs.anchors ?? []) as (GraphAnchor & { manualIndex?: number; adjusted?: boolean })[];
303
- const anchorShapes = graph.find(`.anchor`);
304
- const anchorAndShadows = anchors
305
- .map((anchor) => ({
306
- anchor,
307
- anchorShadow: anchorShapes.find((shape) => shape.attrs.adjustType === anchor.adjustType && shape.attrs.manualIndex === anchor.manualIndex) as Konva.Circle
308
- }))
309
- .filter((o) => o.anchorShadow !== void 0);
310
- return Curve.createAnchorShapes(render, graph, anchorAndShadows, adjustAnchor);
311
- }
312
-
313
- /**
314
- * 默认图形大小
315
- */
316
- static size = 100;
317
-
318
- /**
319
- * 曲线 对应的 Konva 实例
320
- */
321
- private line: Konva.Line;
322
-
323
- constructor(render: Render, dropPoint: Konva.Vector2d) {
324
- super(render, dropPoint, {
325
- type: "Curve",
326
- anchors: [{ adjustType: 'start' }, { adjustType: 'end' }].map((o) => ({ adjustType: o.adjustType })),
327
- linkAnchors: [
328
- { x: 0, y: 0, alias: 'start' },
329
- { x: 0, y: 0, alias: 'end' }
330
- ] as AssetInfoPoint[]
331
- });
332
- this.line = new Konva.Arrow({
333
- name: 'graph',
334
- x: 0,
335
- y: 0,
336
- stroke: "#000000",
337
- strokeWidth: 1,
338
- fill: "#000000",
339
- points: [],
340
- pointerAtBeginning: false,
341
- pointerAtEnding: false,
342
- tension: 0
343
- });
344
- // 给予 1 像素,防止导出图片 toDataURL 失败
345
- this.group.size({ width: 1, height: 1 });
346
- this.group.add(this.line);
347
- this.group.position(this.dropPoint); // 鼠标按下位置 作为起点
348
- }
349
-
350
- // 实现:拖动进行时
351
- override drawMove(point: Konva.Vector2d): void {
352
- const offsetX = point.x - this.dropPoint.x,
353
- offsetY = point.y - this.dropPoint.y;
354
- // 起点、终点
355
- const linkPoints = [
356
- [this.line.x(), this.line.y()],
357
- [this.line.x() + offsetX, this.line.y() + offsetY]
358
- ];
359
- // 曲线 路径
360
- this.line.points(linkPoints.flat());
361
- // 更新 图形 的 调整点 的 锚点位置
362
- Curve.updateAnchorShadows(this.group, this.anchorShadows, this.line);
363
- // 更新 图形 的 连接点 的 锚点位置
364
- Curve.updateLinkAnchorShadows(this.group, this.linkAnchorShadows, this.line);
365
- this.render.redraw([GraphDraw.NAME, LinkDraw.NAME, PreviewDraw.NAME]);
366
- }
367
-
368
- // 实现:拖动结束
369
- override drawEnd(): void {
370
- if (this.line.width() <= 10 && this.line.height() <= 10) {
371
- const width = Curve.size, height = width;
372
- const linkPoints = [
373
- [this.line.x(), this.line.y()],
374
- [this.line.x() + width, this.line.y() + height]
375
- ];
376
- this.line.points(linkPoints.flat());
377
- }
378
- Curve.updateAnchor(this.render, this.group);
379
- Curve.updateAnchorShadows(this.group, this.anchorShadows, this.line);
380
- Curve.updateLinkAnchorShadows(this.group, this.linkAnchorShadows, this.line);
381
- const size = {// 扣除多余的间隙
382
- width: this.line.size().width - 10,
383
- height: this.line.size().height - 10
384
- };
385
- this.group.size(size); // 更新大小
386
- this.render.attractTool.alignLinesClear(); // 对齐线清除
387
- this.render.updateHistory(); // 更新历史
388
- this.render.redraw([GraphDraw.NAME, LinkDraw.NAME, PreviewDraw.NAME]);
389
- super.drawEnd(size, {
390
- x: Math.min(...this.line.points().reduce((arr, item, idx) => {
391
- if (idx % 2 === 0) arr.push(item);
392
- return arr;
393
- }, [] as number[])),
394
- y: Math.min(...this.line.points().reduce((arr, item, idx) => {
395
- if (idx % 2 === 1) arr.push(item);
396
- return arr;
397
- }, [] as number[]))
398
- });
399
- }
400
-
401
- /**
402
- * 更新 调整点(拐点)
403
- * @param render
404
- * @param graph
405
- */
406
- static updateAnchor(render: Render, graph: Konva.Group) {
407
- const anchors = graph.attrs.anchors ?? [];
408
- const anchorShadows = graph.find('.anchor') ?? [];
409
- const shape = graph.findOne('.graph') as Konva.Line;
410
- if (shape) {
411
- let manualPoints = (shape.attrs.manualPoints ?? []) as LineManualPoint[];
412
- const points = shape.points();
413
- const linkPoints = [
414
- [points[0], points[1]],
415
- ...manualPoints.sort((a, b) => a.index - b.index).map((o) => [o.x, o.y]),
416
- [points[points.length - 2], points[points.length - 1]]
417
- ];
418
- // 清空 调整点(拐点),保留 start end
419
- anchors.splice(2);
420
- const shadows = anchorShadows.splice(2);
421
- for (const shadow of shadows) {
422
- shadow.remove();
423
- shadow.destroy();
424
- }
425
- manualPoints = [];
426
- for (let i = linkPoints.length - 1; i > 0; i--) {
427
- linkPoints.splice(i, 0, []);
428
- }
429
- for (let i = 1; i < linkPoints.length - 1; i++) {
430
- const anchor = {
431
- type: graph.attrs.graphType,
432
- adjustType: 'manual',
433
- name: 'anchor',
434
- groupId: graph.id(),
435
- manualIndex: i,
436
- adjusted: false
437
- };
438
- if (linkPoints[i].length === 0) {
439
- anchor.adjusted = false;
440
- const prev = linkPoints[i - 1];
441
- const next = linkPoints[i + 1];
442
- const circle = new Konva.Circle({
443
- adjustType: anchor.adjustType,
444
- anchorType: anchor.type,
445
- name: anchor.name,
446
- manualIndex: anchor.manualIndex,
447
- radius: 0,
448
- x: (prev[0] + next[0]) / 2,
449
- y: (prev[1] + next[1]) / 2,
450
- anchor
451
- });
452
- graph.add(circle);
453
- } else {
454
- anchor.adjusted = true;
455
- const circle = new Konva.Circle({
456
- adjustType: anchor.adjustType,
457
- anchorType: anchor.type,
458
- name: anchor.name,
459
- manualIndex: anchor.manualIndex,
460
- adjusted: true,
461
- radius: 0,
462
- x: linkPoints[i][0],
463
- y: linkPoints[i][1],
464
- anchor
465
- });
466
- graph.add(circle);
467
- manualPoints.push({ x: linkPoints[i][0], y: linkPoints[i][1], index: anchor.manualIndex });
468
- }
469
- anchors.push(anchor);
470
- }
471
- shape.setAttr('manualPoints', manualPoints);
472
- graph.setAttr('anchors', anchors);
473
- }
474
- }
475
-
476
- /**
477
- * 调整之前
478
- */
479
- static adjustStart(
480
- render: Render,
481
- graph: Konva.Group,
482
- adjustAnchor: GraphAnchor & { manualIndex?: number; adjusted?: boolean },
483
- endPoint: Konva.Vector2d
484
- ) {
485
- const { x: gx, y: gy } = graph.position();
486
- const shape = graph.findOne('.graph') as Konva.Line;
487
- if (shape && typeof adjustAnchor.manualIndex === 'number') {
488
- const manualPoints = (shape.attrs.manualPoints ?? []) as LineManualPoint[];
489
- if (adjustAnchor.adjusted) {
490
- } else {
491
- manualPoints.push({
492
- x: endPoint.x - gx,
493
- y: endPoint.y - gy,
494
- index: adjustAnchor.manualIndex
495
- });
496
- shape.setAttr('manualPoints', manualPoints);
497
- }
498
- Curve.updateAnchor(render, graph);
499
- }
500
- }
1
+ import Konva from 'konva';
2
+ import { GraphAnchor, Render, AssetInfoPoint, LineManualPoint } from '../types';
3
+ import { GraphDraw, LinkDraw, PreviewDraw } from '../draws';
4
+ import { BaseGraph } from './base-graph';
5
+
6
+ /**
7
+ * 曲线
8
+ */
9
+ export class Curve extends BaseGraph {
10
+ // 实现:更新 图形 的 调整点 的 锚点位置
11
+ static override updateAnchorShadows(graph: Konva.Group, anchorShadows: Konva.Circle[], shape?: Konva.Line): void {
12
+ if (shape) {
13
+ const points = shape.points();
14
+ for (const shadow of anchorShadows) {
15
+ switch (shadow.attrs.adjustType) {
16
+ case 'start':
17
+ shadow.position({ x: points[0], y: points[1] });
18
+ break;
19
+ case 'end':
20
+ shadow.position({ x: points[points.length - 2], y: points[points.length - 1] });
21
+ break;
22
+ }
23
+ }
24
+ }
25
+ }
26
+
27
+ // 实现:更新 图形 的 连接点 的 锚点位置
28
+ static override updateLinkAnchorShadows(graph: Konva.Group, linkAnchorShadows: Konva.Circle[], shape?: Konva.Line): void {
29
+ if (shape) {
30
+ const points = shape.points();
31
+ for (const shadow of linkAnchorShadows) {
32
+ switch (shadow.attrs.alias) {
33
+ case 'start':
34
+ shadow.position({ x: points[0], y: points[1] });
35
+ break;
36
+ case 'end':
37
+ shadow.position({ x: points[points.length - 2], y: points[points.length - 1] });
38
+ break;
39
+ }
40
+ }
41
+ }
42
+ }
43
+
44
+ static calculateAngle(sideA: number, sideB: number) {
45
+ if (!isNaN(sideA) && !isNaN(sideB)) {
46
+ const angleInRadians = Math.atan2(sideA, sideB);
47
+ const angleInDegrees = angleInRadians * (180 / Math.PI);
48
+ return angleInDegrees;
49
+ }
50
+ return 0;
51
+ }
52
+
53
+ // 实现:生成 调整点
54
+ static override createAnchorShapes(
55
+ render: Render,
56
+ graph: Konva.Group,
57
+ anchorAndShadows: {
58
+ anchor: GraphAnchor;
59
+ anchorShadow: Konva.Circle;
60
+ shape?: Konva.Shape;
61
+ }[],
62
+ // eslint-disable-next-line
63
+ adjustAnchor?: GraphAnchor
64
+ ): {
65
+ anchorAndShadows: {
66
+ anchor: GraphAnchor;
67
+ anchorShadow: Konva.Circle;
68
+ shape?: Konva.Shape | undefined;
69
+ }[]
70
+ } {
71
+ const stageState = render.getStageState();
72
+ const graphShape = graph.findOne('.graph') as Konva.Line;
73
+ if (graphShape) {
74
+ const points = graphShape.points();
75
+ for (const anchorAndShadow of anchorAndShadows) {
76
+ let rotate = 0;
77
+ const { anchor, anchorShadow } = anchorAndShadow;
78
+ const x = render.toStageValue(anchorShadow.getAbsolutePosition().x - stageState.x),
79
+ y = render.toStageValue(anchorShadow.getAbsolutePosition().y - stageState.y);
80
+ if (anchor.adjustType === 'manual') {
81
+ const anchorShape = new Konva.Circle({
82
+ name: 'anchor',
83
+ anchor: anchor,
84
+ fill: anchor.adjusted ? `rgba(0,0,0,0.4)` : `rgba(0,0,255,0.4)`,
85
+ radius: render.toStageValue(5),
86
+ strokeWidth: 0,
87
+ x: x,
88
+ y: y,
89
+ rotation: graph.getAbsoluteRotation(),
90
+ visible: graph.attrs.adjusting || graph.attrs.hover === true
91
+ });
92
+ anchorShape.on('mouseenter', () => {
93
+ document.body.style.cursor = 'move';
94
+ graph.setAttr('hover', true);
95
+ graph.setAttr('hoverAnchor', true);
96
+ });
97
+ anchorShape.on('mouseleave', () => {
98
+ document.body.style.cursor = anchorShape.attrs.adjusting ? 'move' : 'default';
99
+ graph.setAttr('hover', false);
100
+ graph.setAttr('hoverAnchor', false);
101
+ render.redraw([GraphDraw.NAME]);
102
+ });
103
+ anchorAndShadow.shape = anchorShape;
104
+ } else {
105
+ if (anchor.adjustType === 'start') {
106
+ rotate = Curve.calculateAngle(points[2] - points[0], points[3] - points[1]);
107
+ } else if (anchor.adjustType === 'end') {
108
+ rotate = Curve.calculateAngle(points[points.length - 2] - points[points.length - 4], points[points.length - 1] - points[points.length - 3]);
109
+ }
110
+ const cos = Math.cos((rotate * Math.PI) / 180);
111
+ const sin = Math.sin((rotate * Math.PI) / 180);
112
+ const offset = render.toStageValue(render.pointSize - 20);
113
+ const offsetX = offset * sin;
114
+ const offsetY = offset * cos;
115
+ const anchorShape = new Konva.Circle({
116
+ name: 'anchor',
117
+ anchor: anchor,
118
+ fill: `rgba(0,0,255,0.4)`,
119
+ radius: render.toStageValue(5),
120
+ strokeWidth: 0,
121
+ x: x,
122
+ y: y,
123
+ offsetX: anchor.adjustType === 'start' ? offsetX : anchor.adjustType === 'end' ? -offsetX : 0,
124
+ offsetY: anchor.adjustType === 'start' ? offsetY : anchor.adjustType === 'end' ? -offsetY : 0,
125
+ rotation: graph.getAbsoluteRotation(),
126
+ visible: graph.attrs.adjusting || graph.attrs.hover === true
127
+ });
128
+ anchorShape.on('mouseenter', () => {
129
+ document.body.style.cursor = 'move';
130
+ graph.setAttr('hover', true);
131
+ graph.setAttr('hoverAnchor', true);
132
+ });
133
+ anchorShape.on('mouseleave', () => {
134
+ document.body.style.cursor = anchorShape.attrs.adjusting ? 'move' : 'default';
135
+ graph.setAttr('hover', false);
136
+ graph.setAttr('hoverAnchor', false);
137
+ render.redraw([GraphDraw.NAME]);
138
+ });
139
+ anchorAndShadow.shape = anchorShape;
140
+ }
141
+ }
142
+ }
143
+ return { anchorAndShadows };
144
+ }
145
+
146
+ /**
147
+ * 矩阵变换:坐标系中的一个点,围绕着另外一个点进行旋转
148
+ * - - - - - - - -
149
+ * |x`| |cos -sin| |x-a| |a|
150
+ * | | = | | | | +
151
+ * |y`| |sin cos| |y-b| |b|
152
+ * - - - - - - - -
153
+ * @param x 目标节点坐标 x
154
+ * @param y 目标节点坐标 y
155
+ * @param centerX 围绕的点坐标 x
156
+ * @param centerY 围绕的点坐标 y
157
+ * @param angle 旋转角度
158
+ * @returns
159
+ */
160
+ static rotatePoint(x: number, y: number, centerX: number, centerY: number, angle: number) {
161
+ // 将角度转换为弧度
162
+ const radians = (angle * Math.PI) / 180;
163
+ // 计算旋转后的坐标
164
+ const newX = Math.cos(radians) * (x - centerX) - Math.sin(radians) * (y - centerY) + centerX;
165
+ const newY = Math.sin(radians) * (x - centerX) + Math.cos(radians) * (y - centerY) + centerY;
166
+ return { x: newX, y: newY };
167
+ }
168
+
169
+ // 实现:调整 图形
170
+ static override adjust(
171
+ render: Render,
172
+ graph: Konva.Group,
173
+ graphSnap: Konva.Group,
174
+ adjustShape: Konva.Shape,
175
+ anchorAndShadows: {
176
+ anchor: GraphAnchor;
177
+ anchorShadow: Konva.Circle;
178
+ shape?: Konva.Shape | undefined;
179
+ }[],
180
+ startPoint: Konva.Vector2d,
181
+ endPoint: Konva.Vector2d,
182
+ hoverRect?: Konva.Rect
183
+ ) {
184
+ // 目标 曲线
185
+ const line = graph.findOne('.graph') as Konva.Line;
186
+ const lineSnap = graphSnap.findOne('.graph') as Konva.Line;
187
+ const anchors = (graph.find('.anchor') ?? []) as Konva.Circle[];
188
+ const anchorsSnap = (graphSnap.find('.anchor') ?? []) as Konva.Circle[];
189
+ const linkAnchors = (graph.find('.link-anchor') ?? []) as Konva.Circle[];
190
+ if (line && lineSnap) {
191
+ const stageState = render.getStageState();
192
+ {
193
+ const [graphRotation, adjustType, ex, ey] = [
194
+ Math.round(graph.rotation()),
195
+ adjustShape.attrs.anchor?.adjustType,
196
+ endPoint.x,
197
+ endPoint.y
198
+ ];
199
+ const { x: cx, y: cy, width: cw, height: ch } = graphSnap.getClientRect();
200
+ const { x, y } = graph.position();
201
+ const [centerX, centerY] = [cx + cw / 2, cy + ch / 2];
202
+ const { x: sx, y: sy } = Curve.rotatePoint(ex, ey, centerX, centerY, -graphRotation);
203
+ const { x: rx, y: ry } = Curve.rotatePoint(x, y, centerX, centerY, -graphRotation);
204
+ const points = line.points();
205
+ const manualPoints = (line.attrs.manualPoints ?? []) as LineManualPoint[];
206
+ if (adjustType === 'manual') {
207
+ if (adjustShape.attrs.anchor?.manualIndex !== void 0) {
208
+ const index = adjustShape.attrs.anchor?.adjusted ? adjustShape.attrs.anchor?.manualIndex : adjustShape.attrs.anchor?.manualIndex + 1;
209
+ const manualPointIndex = manualPoints.findIndex((o) => o.index === index);
210
+ if (manualPointIndex > -1) {
211
+ manualPoints[manualPointIndex].x = (sx - rx) / graph.scaleX();
212
+ manualPoints[manualPointIndex].y = (sy - ry) / graph.scaleY();
213
+ }
214
+ const linkPoints = [
215
+ [points[0], points[1]],
216
+ ...manualPoints.sort((a, b) => a.index - b.index).map((o) => [o.x, o.y]),
217
+ [points[points.length - 2], points[points.length - 1]]
218
+ ];
219
+ line.setAttr('manualPoints', manualPoints);
220
+ line.points(linkPoints.flat());
221
+ const adjustAnchorShadow = anchors.find((o) => o.attrs.adjustType === 'manual' && o.attrs.manualIndex === index);
222
+ if (adjustAnchorShadow) {
223
+ adjustAnchorShadow.position({
224
+ x: (sx - rx) / graph.scaleX(),
225
+ y: (sy - ry) / graph.scaleY()
226
+ });
227
+ }
228
+ }
229
+ } else {
230
+ const anchor = anchors.find((o) => o.attrs.adjustType === adjustType);
231
+ const anchorShadow = anchorsSnap.find((o) => o.attrs.adjustType === adjustType);
232
+ if (anchor && anchorShadow) {
233
+ const linkPoints = [
234
+ [points[0], points[1]],
235
+ ...manualPoints.sort((a, b) => a.index - b.index).map((o) => [o.x, o.y]),
236
+ [points[points.length - 2], points[points.length - 1]]
237
+ ];
238
+ switch (adjustType) {
239
+ case 'start':
240
+ linkPoints[0] = [(sx - rx) / graph.scaleX(), (sy - ry) / graph.scaleY()];
241
+ line.points(linkPoints.flat());
242
+ break;
243
+ case 'end':
244
+ linkPoints[linkPoints.length - 1] = [(sx - rx) / graph.scaleX(), (sy - ry) / graph.scaleY()];
245
+ line.points(linkPoints.flat());
246
+ break;
247
+ }
248
+ }
249
+ }
250
+ }
251
+ Curve.updateAnchor(render, graph);
252
+ Curve.updateAnchorShadows(graph, anchors, line);
253
+ Curve.updateLinkAnchorShadows(graph, linkAnchors, line);
254
+ for (const anchor of anchors) {
255
+ for (const { shape } of anchorAndShadows) {
256
+ if (shape) {
257
+ if (shape.attrs.anchor?.adjustType === anchor.attrs.adjustType) {
258
+ const anchorShadow = graph.find(`.anchor`).find((o) => o.attrs.adjustType === anchor.attrs.adjustType);
259
+ if (anchorShadow) {
260
+ shape.position({
261
+ x: render.toStageValue(anchorShadow.getAbsolutePosition().x - stageState.x),
262
+ y: render.toStageValue(anchorShadow.getAbsolutePosition().y - stageState.y)
263
+ });
264
+ shape.rotation(graph.getAbsoluteRotation());
265
+ }
266
+ }
267
+ }
268
+ }
269
+ }
270
+ render.redraw([GraphDraw.NAME, LinkDraw.NAME, PreviewDraw.NAME]);
271
+ }
272
+ const allXs = line.points().reduce((arr, item, idx) => {
273
+ if (idx % 2 === 0) arr.push(item);
274
+ return arr;
275
+ }, [] as number[]);
276
+ const allYs = line.points().reduce((arr, item, idx) => {
277
+ if (idx % 2 === 1) arr.push(item);
278
+ return arr;
279
+ }, [] as number[]);
280
+ const minX = Math.min(...allXs);
281
+ const maxX = Math.max(...allXs);
282
+ const minY = Math.min(...allYs);
283
+ const maxY = Math.max(...allYs);
284
+ BaseGraph.adjust(
285
+ render,
286
+ graph,
287
+ graphSnap,
288
+ adjustShape,
289
+ anchorAndShadows,
290
+ startPoint,
291
+ endPoint,
292
+ hoverRect,
293
+ { width: maxX - minX, height: maxY - minY },
294
+ { x: minX, y: minY }
295
+ );
296
+ }
297
+
298
+ /**
299
+ * 提供给 GraphDraw draw 使用
300
+ */
301
+ static override draw(graph: Konva.Group, render: Render, adjustAnchor?: GraphAnchor) {
302
+ const anchors = (graph.attrs.anchors ?? []) as (GraphAnchor & { manualIndex?: number; adjusted?: boolean })[];
303
+ const anchorShapes = graph.find(`.anchor`);
304
+ const anchorAndShadows = anchors
305
+ .map((anchor) => ({
306
+ anchor,
307
+ anchorShadow: anchorShapes.find((shape) => shape.attrs.adjustType === anchor.adjustType && shape.attrs.manualIndex === anchor.manualIndex) as Konva.Circle
308
+ }))
309
+ .filter((o) => o.anchorShadow !== void 0);
310
+ return Curve.createAnchorShapes(render, graph, anchorAndShadows, adjustAnchor);
311
+ }
312
+
313
+ /**
314
+ * 默认图形大小
315
+ */
316
+ static size = 100;
317
+
318
+ /**
319
+ * 曲线 对应的 Konva 实例
320
+ */
321
+ private line: Konva.Line;
322
+
323
+ constructor(render: Render, dropPoint: Konva.Vector2d) {
324
+ super(render, dropPoint, {
325
+ type: "Curve",
326
+ anchors: [{ adjustType: 'start' }, { adjustType: 'end' }].map((o) => ({ adjustType: o.adjustType })),
327
+ linkAnchors: [
328
+ { x: 0, y: 0, alias: 'start' },
329
+ { x: 0, y: 0, alias: 'end' }
330
+ ] as AssetInfoPoint[]
331
+ });
332
+ this.line = new Konva.Arrow({
333
+ name: 'graph',
334
+ x: 0,
335
+ y: 0,
336
+ stroke: "#000000",
337
+ strokeWidth: 1,
338
+ fill: "#000000",
339
+ points: [],
340
+ pointerAtBeginning: false,
341
+ pointerAtEnding: false,
342
+ tension: 0
343
+ });
344
+ // 给予 1 像素,防止导出图片 toDataURL 失败
345
+ this.group.size({ width: 1, height: 1 });
346
+ this.group.add(this.line);
347
+ this.group.position(this.dropPoint); // 鼠标按下位置 作为起点
348
+ }
349
+
350
+ // 实现:拖动进行时
351
+ override drawMove(point: Konva.Vector2d): void {
352
+ const offsetX = point.x - this.dropPoint.x,
353
+ offsetY = point.y - this.dropPoint.y;
354
+ // 起点、终点
355
+ const linkPoints = [
356
+ [this.line.x(), this.line.y()],
357
+ [this.line.x() + offsetX, this.line.y() + offsetY]
358
+ ];
359
+ // 曲线 路径
360
+ this.line.points(linkPoints.flat());
361
+ // 更新 图形 的 调整点 的 锚点位置
362
+ Curve.updateAnchorShadows(this.group, this.anchorShadows, this.line);
363
+ // 更新 图形 的 连接点 的 锚点位置
364
+ Curve.updateLinkAnchorShadows(this.group, this.linkAnchorShadows, this.line);
365
+ this.render.redraw([GraphDraw.NAME, LinkDraw.NAME, PreviewDraw.NAME]);
366
+ }
367
+
368
+ // 实现:拖动结束
369
+ override drawEnd(): void {
370
+ if (this.line.width() <= 10 && this.line.height() <= 10) {
371
+ const width = Curve.size, height = width;
372
+ const linkPoints = [
373
+ [this.line.x(), this.line.y()],
374
+ [this.line.x() + width, this.line.y() + height]
375
+ ];
376
+ this.line.points(linkPoints.flat());
377
+ }
378
+ Curve.updateAnchor(this.render, this.group);
379
+ Curve.updateAnchorShadows(this.group, this.anchorShadows, this.line);
380
+ Curve.updateLinkAnchorShadows(this.group, this.linkAnchorShadows, this.line);
381
+ const size = {// 扣除多余的间隙
382
+ width: this.line.size().width - 10,
383
+ height: this.line.size().height - 10
384
+ };
385
+ this.group.size(size); // 更新大小
386
+ this.render.attractTool.alignLinesClear(); // 对齐线清除
387
+ this.render.updateHistory(); // 更新历史
388
+ this.render.redraw([GraphDraw.NAME, LinkDraw.NAME, PreviewDraw.NAME]);
389
+ super.drawEnd(size, {
390
+ x: Math.min(...this.line.points().reduce((arr, item, idx) => {
391
+ if (idx % 2 === 0) arr.push(item);
392
+ return arr;
393
+ }, [] as number[])),
394
+ y: Math.min(...this.line.points().reduce((arr, item, idx) => {
395
+ if (idx % 2 === 1) arr.push(item);
396
+ return arr;
397
+ }, [] as number[]))
398
+ });
399
+ }
400
+
401
+ /**
402
+ * 更新 调整点(拐点)
403
+ * @param render
404
+ * @param graph
405
+ */
406
+ static updateAnchor(render: Render, graph: Konva.Group) {
407
+ const anchors = graph.attrs.anchors ?? [];
408
+ const anchorShadows = graph.find('.anchor') ?? [];
409
+ const shape = graph.findOne('.graph') as Konva.Line;
410
+ if (shape) {
411
+ let manualPoints = (shape.attrs.manualPoints ?? []) as LineManualPoint[];
412
+ const points = shape.points();
413
+ const linkPoints = [
414
+ [points[0], points[1]],
415
+ ...manualPoints.sort((a, b) => a.index - b.index).map((o) => [o.x, o.y]),
416
+ [points[points.length - 2], points[points.length - 1]]
417
+ ];
418
+ // 清空 调整点(拐点),保留 start end
419
+ anchors.splice(2);
420
+ const shadows = anchorShadows.splice(2);
421
+ for (const shadow of shadows) {
422
+ shadow.remove();
423
+ shadow.destroy();
424
+ }
425
+ manualPoints = [];
426
+ for (let i = linkPoints.length - 1; i > 0; i--) {
427
+ linkPoints.splice(i, 0, []);
428
+ }
429
+ for (let i = 1; i < linkPoints.length - 1; i++) {
430
+ const anchor = {
431
+ type: graph.attrs.graphType,
432
+ adjustType: 'manual',
433
+ name: 'anchor',
434
+ groupId: graph.id(),
435
+ manualIndex: i,
436
+ adjusted: false
437
+ };
438
+ if (linkPoints[i].length === 0) {
439
+ anchor.adjusted = false;
440
+ const prev = linkPoints[i - 1];
441
+ const next = linkPoints[i + 1];
442
+ const circle = new Konva.Circle({
443
+ adjustType: anchor.adjustType,
444
+ anchorType: anchor.type,
445
+ name: anchor.name,
446
+ manualIndex: anchor.manualIndex,
447
+ radius: 0,
448
+ x: (prev[0] + next[0]) / 2,
449
+ y: (prev[1] + next[1]) / 2,
450
+ anchor
451
+ });
452
+ graph.add(circle);
453
+ } else {
454
+ anchor.adjusted = true;
455
+ const circle = new Konva.Circle({
456
+ adjustType: anchor.adjustType,
457
+ anchorType: anchor.type,
458
+ name: anchor.name,
459
+ manualIndex: anchor.manualIndex,
460
+ adjusted: true,
461
+ radius: 0,
462
+ x: linkPoints[i][0],
463
+ y: linkPoints[i][1],
464
+ anchor
465
+ });
466
+ graph.add(circle);
467
+ manualPoints.push({ x: linkPoints[i][0], y: linkPoints[i][1], index: anchor.manualIndex });
468
+ }
469
+ anchors.push(anchor);
470
+ }
471
+ shape.setAttr('manualPoints', manualPoints);
472
+ graph.setAttr('anchors', anchors);
473
+ }
474
+ }
475
+
476
+ /**
477
+ * 调整之前
478
+ */
479
+ static adjustStart(
480
+ render: Render,
481
+ graph: Konva.Group,
482
+ adjustAnchor: GraphAnchor & { manualIndex?: number; adjusted?: boolean },
483
+ endPoint: Konva.Vector2d
484
+ ) {
485
+ const { x: gx, y: gy } = graph.position();
486
+ const shape = graph.findOne('.graph') as Konva.Line;
487
+ if (shape && typeof adjustAnchor.manualIndex === 'number') {
488
+ const manualPoints = (shape.attrs.manualPoints ?? []) as LineManualPoint[];
489
+ if (adjustAnchor.adjusted) {
490
+ } else {
491
+ manualPoints.push({
492
+ x: endPoint.x - gx,
493
+ y: endPoint.y - gy,
494
+ index: adjustAnchor.manualIndex
495
+ });
496
+ shape.setAttr('manualPoints', manualPoints);
497
+ }
498
+ Curve.updateAnchor(render, graph);
499
+ }
500
+ }
501
501
  }