aldehyde 0.2.479 → 0.2.480

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 (153) hide show
  1. package/lib/controls/2dEditor/components/card.js +2 -2
  2. package/lib/controls/2dEditor/components/card.js.map +1 -1
  3. package/lib/controls/entity-select/entity-select.js +3 -3
  4. package/lib/controls/entity-select/entity-select.js.map +1 -1
  5. package/lib/draw-canvas-edit/components/asset-bar/index.d.ts +1 -0
  6. package/lib/draw-canvas-edit/components/asset-bar/index.d.ts.map +1 -1
  7. package/lib/draw-canvas-edit/components/asset-bar/index.js +8 -6
  8. package/lib/draw-canvas-edit/components/asset-bar/index.js.map +1 -1
  9. package/lib/draw-canvas-edit/components/main-header/index.less +3 -0
  10. package/lib/draw-canvas-edit/components/render/draws/bg-draw.d.ts.map +1 -1
  11. package/lib/draw-canvas-edit/components/render/draws/bg-draw.js +14 -1
  12. package/lib/draw-canvas-edit/components/render/draws/bg-draw.js.map +1 -1
  13. package/lib/draw-canvas-edit/components/render/draws/contextmenu-draw.d.ts.map +1 -1
  14. package/lib/draw-canvas-edit/components/render/draws/contextmenu-draw.js +30 -6
  15. package/lib/draw-canvas-edit/components/render/draws/contextmenu-draw.js.map +1 -1
  16. package/lib/draw-canvas-edit/components/render/graphs/bezier.js +3 -3
  17. package/lib/draw-canvas-edit/components/render/graphs/bezier.js.map +1 -1
  18. package/lib/draw-canvas-edit/components/render/graphs/circle.js +2 -2
  19. package/lib/draw-canvas-edit/components/render/graphs/circle.js.map +1 -1
  20. package/lib/draw-canvas-edit/components/render/graphs/curve.js +3 -3
  21. package/lib/draw-canvas-edit/components/render/graphs/curve.js.map +1 -1
  22. package/lib/draw-canvas-edit/components/render/graphs/line.js +3 -3
  23. package/lib/draw-canvas-edit/components/render/graphs/line.js.map +1 -1
  24. package/lib/draw-canvas-edit/components/render/graphs/rect.js +2 -2
  25. package/lib/draw-canvas-edit/components/render/graphs/rect.js.map +1 -1
  26. package/lib/draw-canvas-edit/components/render/handlers/drag-outside-handlers.d.ts +1 -1
  27. package/lib/draw-canvas-edit/components/render/handlers/drag-outside-handlers.d.ts.map +1 -1
  28. package/lib/draw-canvas-edit/components/render/handlers/drag-outside-handlers.js +58 -122
  29. package/lib/draw-canvas-edit/components/render/handlers/drag-outside-handlers.js.map +1 -1
  30. package/lib/draw-canvas-edit/components/render/handlers/graph-handlers.d.ts.map +1 -1
  31. package/lib/draw-canvas-edit/components/render/handlers/graph-handlers.js +2 -1
  32. package/lib/draw-canvas-edit/components/render/handlers/graph-handlers.js.map +1 -1
  33. package/lib/draw-canvas-edit/components/render/handlers/selection-handlers.d.ts.map +1 -1
  34. package/lib/draw-canvas-edit/components/render/handlers/selection-handlers.js +11 -4
  35. package/lib/draw-canvas-edit/components/render/handlers/selection-handlers.js.map +1 -1
  36. package/lib/draw-canvas-edit/components/render/index.d.ts +3 -1
  37. package/lib/draw-canvas-edit/components/render/index.d.ts.map +1 -1
  38. package/lib/draw-canvas-edit/components/render/index.js +37 -26
  39. package/lib/draw-canvas-edit/components/render/index.js.map +1 -1
  40. package/lib/draw-canvas-edit/components/render/tools/attract-tool.d.ts +2 -1
  41. package/lib/draw-canvas-edit/components/render/tools/attract-tool.d.ts.map +1 -1
  42. package/lib/draw-canvas-edit/components/render/tools/attract-tool.js +33 -8
  43. package/lib/draw-canvas-edit/components/render/tools/attract-tool.js.map +1 -1
  44. package/lib/draw-canvas-edit/components/render/tools/component-factory.d.ts +62 -0
  45. package/lib/draw-canvas-edit/components/render/tools/component-factory.d.ts.map +1 -0
  46. package/lib/draw-canvas-edit/components/render/tools/component-factory.js +289 -0
  47. package/lib/draw-canvas-edit/components/render/tools/component-factory.js.map +1 -0
  48. package/lib/draw-canvas-edit/components/render/tools/copy-tool.d.ts +0 -2
  49. package/lib/draw-canvas-edit/components/render/tools/copy-tool.d.ts.map +1 -1
  50. package/lib/draw-canvas-edit/components/render/tools/copy-tool.js +23 -45
  51. package/lib/draw-canvas-edit/components/render/tools/copy-tool.js.map +1 -1
  52. package/lib/draw-canvas-edit/components/render/tools/import-export-tool.d.ts.map +1 -1
  53. package/lib/draw-canvas-edit/components/render/tools/import-export-tool.js +20 -41
  54. package/lib/draw-canvas-edit/components/render/tools/import-export-tool.js.map +1 -1
  55. package/lib/draw-canvas-edit/components/render/tools/index.d.ts +1 -0
  56. package/lib/draw-canvas-edit/components/render/tools/index.d.ts.map +1 -1
  57. package/lib/draw-canvas-edit/components/render/tools/index.js +1 -0
  58. package/lib/draw-canvas-edit/components/render/tools/index.js.map +1 -1
  59. package/lib/draw-canvas-edit/components/render/tools/selection-tool.d.ts.map +1 -1
  60. package/lib/draw-canvas-edit/components/render/tools/selection-tool.js +32 -19
  61. package/lib/draw-canvas-edit/components/render/tools/selection-tool.js.map +1 -1
  62. package/lib/draw-canvas-edit/components/render/types.d.ts +8 -6
  63. package/lib/draw-canvas-edit/components/render/types.d.ts.map +1 -1
  64. package/lib/draw-canvas-edit/components/render/types.js.map +1 -1
  65. package/lib/draw-canvas-edit/components/setting-form/imag-upload.d.ts.map +1 -1
  66. package/lib/draw-canvas-edit/components/setting-form/imag-upload.js +2 -2
  67. package/lib/draw-canvas-edit/components/setting-form/imag-upload.js.map +1 -1
  68. package/lib/draw-canvas-edit/components/setting-form/index.d.ts.map +1 -1
  69. package/lib/draw-canvas-edit/components/setting-form/index.js +3 -5
  70. package/lib/draw-canvas-edit/components/setting-form/index.js.map +1 -1
  71. package/lib/draw-canvas-edit/index.d.ts.map +1 -1
  72. package/lib/draw-canvas-edit/index.js +4 -1
  73. package/lib/draw-canvas-edit/index.js.map +1 -1
  74. package/lib/draw-canvas-view/index.d.ts.map +1 -1
  75. package/lib/draw-canvas-view/index.js +4 -2
  76. package/lib/draw-canvas-view/index.js.map +1 -1
  77. package/lib/draw-canvas-view/view.d.ts +2 -0
  78. package/lib/draw-canvas-view/view.d.ts.map +1 -1
  79. package/lib/draw-canvas-view/view.js +46 -35
  80. package/lib/draw-canvas-view/view.js.map +1 -1
  81. package/lib/form/criteria-form.js +17 -17
  82. package/lib/form/criteria-form.js.map +1 -1
  83. package/lib/form/dtmpl-form.d.ts.map +1 -1
  84. package/lib/form/dtmpl-form.js +9 -0
  85. package/lib/form/dtmpl-form.js.map +1 -1
  86. package/lib/form/form-Item-group.js +2 -2
  87. package/lib/form/form-Item-group.js.map +1 -1
  88. package/lib/module/dtmpl-edit-card.js +4 -4
  89. package/lib/module/dtmpl-edit-card.js.map +1 -1
  90. package/lib/module/dtmpl-edit-page.d.ts.map +1 -1
  91. package/lib/module/dtmpl-edit-page.js +7 -4
  92. package/lib/module/dtmpl-edit-page.js.map +1 -1
  93. package/lib/table/act-table.js +8 -8
  94. package/lib/table/act-table.js.map +1 -1
  95. package/lib/table/modal-select-table.d.ts +2 -2
  96. package/lib/table/modal-select-table.d.ts.map +1 -1
  97. package/lib/table/modal-select-table.js +10 -10
  98. package/lib/table/modal-select-table.js.map +1 -1
  99. package/lib/table/relation-table.d.ts +2 -2
  100. package/lib/table/relation-table.js +1 -1
  101. package/lib/table/relation-table.js.map +1 -1
  102. package/lib/table/select-table.js +2 -2
  103. package/lib/table/select-table.js.map +1 -1
  104. package/lib/tmpl/hc-data-source.js +2 -2
  105. package/lib/tmpl/hc-data-source.js.map +1 -1
  106. package/lib/tmpl/interface.d.ts +7 -7
  107. package/lib/tmpl/interface.d.ts.map +1 -1
  108. package/lib/tmpl/tmpl-config-analysis.d.ts.map +1 -1
  109. package/lib/tmpl/tmpl-config-analysis.js +23 -23
  110. package/lib/tmpl/tmpl-config-analysis.js.map +1 -1
  111. package/lib/units/index.js +3 -3
  112. package/lib/units/index.js.map +1 -1
  113. package/package.json +1 -1
  114. package/src/aldehyde/controls/2dEditor/components/card.tsx +2 -2
  115. package/src/aldehyde/controls/entity-select/entity-select.tsx +3 -3
  116. package/src/aldehyde/draw-canvas-edit/components/asset-bar/index.tsx +8 -6
  117. package/src/aldehyde/draw-canvas-edit/components/main-header/index.less +3 -0
  118. package/src/aldehyde/draw-canvas-edit/components/render/draws/bg-draw.ts +17 -1
  119. package/src/aldehyde/draw-canvas-edit/components/render/draws/contextmenu-draw.ts +30 -6
  120. package/src/aldehyde/draw-canvas-edit/components/render/graphs/bezier.ts +3 -3
  121. package/src/aldehyde/draw-canvas-edit/components/render/graphs/circle.ts +2 -2
  122. package/src/aldehyde/draw-canvas-edit/components/render/graphs/curve.ts +3 -3
  123. package/src/aldehyde/draw-canvas-edit/components/render/graphs/line.ts +3 -3
  124. package/src/aldehyde/draw-canvas-edit/components/render/graphs/rect.ts +2 -2
  125. package/src/aldehyde/draw-canvas-edit/components/render/handlers/drag-outside-handlers.ts +45 -130
  126. package/src/aldehyde/draw-canvas-edit/components/render/handlers/graph-handlers.ts +7 -1
  127. package/src/aldehyde/draw-canvas-edit/components/render/handlers/selection-handlers.ts +11 -5
  128. package/src/aldehyde/draw-canvas-edit/components/render/index.ts +38 -29
  129. package/src/aldehyde/draw-canvas-edit/components/render/tools/attract-tool.ts +30 -10
  130. package/src/aldehyde/draw-canvas-edit/components/render/tools/component-factory.ts +302 -0
  131. package/src/aldehyde/draw-canvas-edit/components/render/tools/copy-tool.ts +24 -46
  132. package/src/aldehyde/draw-canvas-edit/components/render/tools/import-export-tool.ts +22 -46
  133. package/src/aldehyde/draw-canvas-edit/components/render/tools/index.ts +1 -0
  134. package/src/aldehyde/draw-canvas-edit/components/render/tools/selection-tool.ts +34 -23
  135. package/src/aldehyde/draw-canvas-edit/components/render/types.ts +6 -6
  136. package/src/aldehyde/draw-canvas-edit/components/setting-form/imag-upload.tsx +2 -1
  137. package/src/aldehyde/draw-canvas-edit/components/setting-form/index.tsx +3 -5
  138. package/src/aldehyde/draw-canvas-edit/index.tsx +4 -1
  139. package/src/aldehyde/draw-canvas-view/index.tsx +3 -1
  140. package/src/aldehyde/draw-canvas-view/view.tsx +228 -212
  141. package/src/aldehyde/form/criteria-form.tsx +18 -18
  142. package/src/aldehyde/form/dtmpl-form.tsx +9 -0
  143. package/src/aldehyde/form/form-Item-group.tsx +2 -2
  144. package/src/aldehyde/module/dtmpl-edit-card.tsx +4 -4
  145. package/src/aldehyde/module/dtmpl-edit-page.tsx +7 -4
  146. package/src/aldehyde/table/act-table.tsx +8 -8
  147. package/src/aldehyde/table/modal-select-table.tsx +10 -10
  148. package/src/aldehyde/table/relation-table.tsx +1 -1
  149. package/src/aldehyde/table/select-table.tsx +2 -2
  150. package/src/aldehyde/tmpl/hc-data-source.tsx +2 -2
  151. package/src/aldehyde/tmpl/interface.tsx +7 -7
  152. package/src/aldehyde/tmpl/tmpl-config-analysis.tsx +23 -24
  153. package/src/aldehyde/units/index.tsx +3 -3
@@ -647,8 +647,8 @@ export class Circle extends BaseGraph {
647
647
  y: 0,
648
648
  radiusX: 0,
649
649
  radiusY: 0,
650
- stroke: this.render.getPageSettings().stroke,
651
- strokeWidth: this.render.getPageSettings().strokeWidth
650
+ stroke: "#000000",
651
+ strokeWidth: 1,
652
652
  });
653
653
  this.group.add(this.circle);
654
654
  this.group.position(this.dropPoint); // 鼠标按下位置 作为起点
@@ -333,9 +333,9 @@ export class Curve extends BaseGraph {
333
333
  name: 'graph',
334
334
  x: 0,
335
335
  y: 0,
336
- stroke: this.render.getPageSettings().stroke,
337
- strokeWidth: this.render.getPageSettings().strokeWidth,
338
- fill: this.render.getPageSettings().stroke,
336
+ stroke: "#000000",
337
+ strokeWidth: 1,
338
+ fill: "#000000",
339
339
  points: [],
340
340
  pointerAtBeginning: false,
341
341
  pointerAtEnding: false,
@@ -328,9 +328,9 @@ export class Line extends BaseGraph {
328
328
  name: 'graph',
329
329
  x: 0,
330
330
  y: 0,
331
- stroke: this.render.getPageSettings().stroke,
332
- strokeWidth: this.render.getPageSettings().strokeWidth,
333
- fill: this.render.getPageSettings().stroke,
331
+ stroke: "#000000",
332
+ strokeWidth: 1,
333
+ fill: "#000000",
334
334
  points: [],
335
335
  pointerAtBeginning: false,
336
336
  pointerAtEnding: false
@@ -641,8 +641,8 @@ export class Rect extends BaseGraph {
641
641
  y: 0,
642
642
  width: 0,
643
643
  height: 0,
644
- stroke: this.render.getPageSettings().stroke,
645
- strokeWidth: this.render.getPageSettings().strokeWidth
644
+ stroke: "#000000",
645
+ strokeWidth: 1,
646
646
  });
647
647
  this.group.add(this.rect);
648
648
  this.group.position(this.dropPoint);
@@ -1,7 +1,7 @@
1
1
  import Konva from 'konva';
2
2
  import { nanoid } from 'nanoid';
3
3
  import { Render } from '../index';
4
- import { Handler, AssetInfoPoint, AssetType, LinkDrawPoint } from '../types';
4
+ import { Handler, AssetInfoPoint, LinkDrawPoint } from '../types';
5
5
  import { RefLineDraw, PreviewDraw } from '../draws';
6
6
 
7
7
  export class DragOutsideHandlers implements Handler {
@@ -13,143 +13,58 @@ export class DragOutsideHandlers implements Handler {
13
13
  dom: {
14
14
  dragenter: (e: GlobalEventHandlersEventMap['dragenter']) => {
15
15
  this.render.stage.setPointersPositions(e);
16
- // 更新参考线
17
- this.render.redraw([RefLineDraw.name]);
16
+ this.render.redraw([RefLineDraw.name]); // 更新参考线
18
17
  },
19
18
  dragover: (e: GlobalEventHandlersEventMap['dragover']) => {
20
19
  this.render.stage.setPointersPositions(e);
21
- // 更新参考线
22
- this.render.redraw([RefLineDraw.name]);
20
+ this.render.redraw([RefLineDraw.name]); // 更新参考线
23
21
  },
24
- drop: (e: GlobalEventHandlersEventMap['drop']) => {
22
+ drop: async (e: GlobalEventHandlersEventMap['drop']) => {
23
+ const componentItem = JSON.parse(e.dataTransfer?.getData('componentItem') || '{}');
25
24
  const src = e.dataTransfer?.getData('src');
26
25
  const componentType = e.dataTransfer?.getData('componentType'); // 组件类型
27
- // 接收连接点信息
28
- let morePoints: AssetInfoPoint[] = [];
29
- const morePointsTxt = e.dataTransfer?.getData('points') ?? '[]';
30
- try {
31
- morePoints = JSON.parse(morePointsTxt);
32
- } catch (e) {
33
- console.error(e);
26
+ const showPoints = e.dataTransfer?.getData('showPoints'); // 是否显示连接点
27
+ const type = e.dataTransfer?.getData('type') || "other";
28
+ const stageState = this.render.getStageState();
29
+ this.render.stage.setPointersPositions(e);
30
+ const pos = this.render.stage.getPointerPosition();
31
+ if (!pos) return;
32
+ const factory = this.render.componentFactory;
33
+ let group: Konva.Group | null = null;
34
+ let points: AssetInfoPoint[] = [];
35
+ if (componentType) { // 指定组件类型
36
+ const comGroup = await factory.createTypedComponent({ src, type, componentType });
37
+ group = comGroup.group;
38
+ points = comGroup.points;
39
+ } else if (src && type) { // 图片或组合组件
40
+ if (type === 'json') { // 组合组件
41
+ const jsonGroup = await factory.createJsonComponent({ src });
42
+ group = jsonGroup.group;
43
+ } else { // 图片组件
44
+ const imgGroup = await factory.createImageComponent({ src, type });
45
+ group = imgGroup.group;
46
+ points = imgGroup.points;
47
+ }
34
48
  }
35
- const type = e.dataTransfer?.getData('type');
36
- if (src && type) {
37
- const stageState = this.render.getStageState();
38
- const { pageHeight, pageWidth } = this.render.getPageSettings()
39
- this.render.stage.setPointersPositions(e);
40
- const pos = this.render.stage.getPointerPosition();
41
- if (pos) {
42
- this.render.assetTool[type === 'json' ? 'loadJson' : ({ svg: "loadSvg", gif: "loadGif" }[type] || "loadImg")](src).then((target: Konva.Image | Konva.Group) => {
43
- let group = null;
44
- let width = target.width();
45
- let height = target.height();
46
- if (width > pageWidth || height > pageHeight) {
47
- const sizeScale = Math.min(pageWidth / width, pageHeight / height);
48
- width *= sizeScale;
49
- height *= sizeScale;
50
- target.setSize({ width, height });
51
- }
52
- // 默认连接点
53
- let points: AssetInfoPoint[] = [];
54
- if (target instanceof Konva.Image) { // 图片素材
55
- group = new Konva.Group({
56
- id: nanoid(),
57
- width,
58
- height,
59
- name: 'asset',
60
- assetType: AssetType.Image,
61
- draggable: true,
62
- componentType,
63
- imageType:
64
- type !== 'json'
65
- ? (["svg", "gif", "other"].includes(type) ? type : "other")
66
- : undefined
67
- });
68
- this.render.setAssetSettings(group, this.render.getAssetSettings(), false);
69
- group.add(target);
70
- points = [
71
- { x: 0, y: group.height() / 2, direction: 'left' }, // 左
72
- { x: group.width(), y: group.height() / 2, direction: 'right' }, // 右
73
- { x: group.width() / 2, y: 0, direction: 'top' }, // 上
74
- { x: group.width() / 2, y: group.height(), direction: 'bottom' } // 下
75
- ];
76
- } else {// json 素材
77
- target.id(nanoid());
78
- target.setAttrs({
79
- name: 'asset',
80
- assetType: AssetType.Json,
81
- draggable: true
82
- });
83
- group = target;
84
- this.render.linkTool.groupIdCover(group);
85
- }
86
- target.setAttrs({ x: 0, y: 0 } as any);
87
- this.render.layer.add(group); // 组件添加到画布
88
- const x = this.render.toStageValue(pos.x - stageState.x) - group.width() / 2;
89
- const y = this.render.toStageValue(pos.y - stageState.y) - group.height() / 2;
90
- group.setAttrs({ x, y });
91
- // 更新坐标记录
92
- this.render.setAssetSettings(group, this.render.getAssetSettings(group), false);
93
- // 自定义连接点 覆盖 默认连接点
94
- if (Array.isArray(morePoints) && morePoints.length > 0) {
95
- points = morePoints;
96
- }
97
- // 连接点信息
98
- group.setAttrs({
99
- points: points.map(
100
- (o) =>
101
- ({
102
- ...o,
103
- id: nanoid(),
104
- groupId: group.id(),
105
- visible: false,
106
- pairs: [],
107
- direction: o.direction
108
- }) as LinkDrawPoint
109
- )
110
- });
111
- // 连接点(锚点)
112
- for (const point of group.getAttr('points') ?? []) {
113
- group.add(
114
- new Konva.Circle({
115
- name: 'link-anchor',
116
- id: point.id,
117
- x: point.x,
118
- y: point.y,
119
- radius: this.render.toStageValue(1),
120
- stroke: 'rgba(0,0,255,1)',
121
- strokeWidth: this.render.toStageValue(2),
122
- visible: false,
123
- direction: point.direction
124
- })
125
- );
126
- }
127
- group.on('mouseenter', () => { // 显示 连接点
128
- this.render.linkTool.pointsVisible(true, group);
129
- });
130
- // hover 框(多选时才显示)
131
- group.add(
132
- new Konva.Rect({
133
- id: 'hoverRect',
134
- width: target.width(),
135
- height: target.height(),
136
- fill: 'rgba(0,255,0,0.3)',
137
- visible: false
138
- })
139
- );
140
-
141
- group.on('mouseleave', () => {
142
- // 隐藏 连接点
143
- this.render.linkTool.pointsVisible(false, group);
144
- // 隐藏 hover 框
145
- group.findOne('#hoverRect')?.visible(false);
146
- });
147
- // 更新历史
148
- this.render.updateHistory();
149
- // 重绘
150
- this.render.redraw([PreviewDraw.name]);
151
- })
49
+ if (group) { // 存在组件,设置连接点等功能
50
+ this.render.layer.add(group); // 组件添加到画布
51
+ if (componentItem?.dataSource) { // 组件存在默认数据源,拖拽插入组件时默认设置数据源配置
52
+ this.render.setAssetSettings(group, { ...this.render.getAssetSettings(group), dataSource: componentItem.dataSource.split('@R@')[0] }, false);
152
53
  }
54
+ const x = this.render.toStageValue(pos.x - stageState.x) - group.width() / 2;
55
+ const y = this.render.toStageValue(pos.y - stageState.y) - group.height() / 2;
56
+ group.setAttrs({ x, y });
57
+ // 更新坐标记录
58
+ this.render.setAssetSettings(group, this.render.getAssetSettings(group), false);
59
+ // 设置连接点
60
+ this.render.componentFactory.createComponentLinkPoints({ group, points, showPoints });
61
+ // 组件鼠标移入移出事件
62
+ this.render.componentFactory.groupMouseenter({ group });
63
+ this.render.componentFactory.groupMouseleave({ group });
64
+ // 更新历史
65
+ this.render.updateHistory();
66
+ // 重绘
67
+ this.render.redraw([PreviewDraw.name]);
153
68
  }
154
69
  }
155
70
  }
@@ -70,9 +70,15 @@ export class GraphHandlers implements Handler {
70
70
 
71
71
  // 初始化设置信息
72
72
  if (this.currentGraph) {
73
+ const temSetting = this.render.getAssetSettings(this.currentGraph.group);
73
74
  this.render.setAssetSettings(
74
75
  this.currentGraph.group,
75
- this.render.getAssetSettings(this.currentGraph.group),
76
+ {
77
+ ...temSetting,
78
+ stroke: temSetting.stroke || "#000000",
79
+ strokeWidth: temSetting.strokeWidth || 1,
80
+ fill: temSetting.fill || (["Circle", "Rect"].includes(this.render.graphType) ? "transparent" : "#000000"),
81
+ },
76
82
  false
77
83
  );
78
84
  }
@@ -144,6 +144,10 @@ export class SelectionHandlers implements Handler {
144
144
  // (判断 ctrlKey 为了排查 mac 拖动快捷键)
145
145
  if (e.evt.button === MouseButton["左键"] && !e.evt.ctrlKey) {
146
146
  if (!this.render.ignore(parent) && !this.render.ignoreDraw(e.target)) {
147
+ // 锁定节点:在 select 之前先禁用 Konva 内置拖拽,防止 race condition
148
+ if (parent.attrs.locked) {
149
+ parent.draggable(false);
150
+ }
147
151
  if (e.evt.ctrlKey || e.evt.metaKey) { // 新增多选
148
152
  this.render.selectionTool.select([...this.render.selectionTool.selectingNodes, parent]);
149
153
  } else { // 单选
@@ -278,9 +282,11 @@ export class SelectionHandlers implements Handler {
278
282
  }
279
283
  }
280
284
  }
281
- // 更新坐标记录
282
- for (const group of groups) {
283
- this.render.setAssetSettings(group, this.render.getAssetSettings(group), false);
285
+ // 更新坐标记录(仅记录属性,不干预Konva位置,避免toFixed截断与Konva精确值冲突累积)
286
+ for (const group of groups as Konva.Group[]) {
287
+ group.setAttr('assetSettings', this.render.getAssetSettings(group));
288
+ // 存在tooltip,则tooltip始终箭头朝下,不受group旋转影响
289
+ group.findOne('.tooltip')?.rotation(-group.rotation());
284
290
  }
285
291
  this.render.emit('asset-position-change', groups);
286
292
  this.render.emit('asset-rotation-change', groups);
@@ -312,8 +318,8 @@ export class SelectionHandlers implements Handler {
312
318
  this.updateManualPointsByDrag(rect, undefined, false);
313
319
  }
314
320
  const groups = this.render.transformer.nodes();
315
- for (const group of groups) { // 更新坐标记录
316
- this.render.setAssetSettings(group, this.render.getAssetSettings(group), false);
321
+ for (const group of groups) { // 更新坐标记录(仅记录属性,不干预Konva位置)
322
+ group.setAttr('assetSettings', this.render.getAssetSettings(group));
317
323
  }
318
324
  this.render.emit('asset-position-change', groups);
319
325
  this.render.redraw([GraphDraw.name, LinkDraw.name, RulerDraw.name, PreviewDraw.name]);
@@ -3,7 +3,7 @@ import Konva from 'konva';
3
3
  import { GraphDraw, LinkDraw, RulerDraw, PreviewDraw, RefLineDraw, BgDraw, ContextmenuDraw } from './draws';
4
4
  import { LinkDrawPoint, GraphType, AssetType, RenderConfig, Draw, Handler, RenderEvents, LinkDrawPair, PageSettings, AssetSettings, ImageType, LinkSettings } from './types';
5
5
  import { DragHandlers, ZoomHandlers, DragOutsideHandlers, SelectionHandlers, KeyMoveHandlers, ShutcutHandlers, LinkHandlers, GraphHandlers, TextHandlers } from './handlers';
6
- import { AssetTool, SelectionTool, CopyTool, PositionTool, ZIndexTool, ImportExportTool, AlignTool, LinkTool, AttractTool } from './tools';
6
+ import { AssetTool, SelectionTool, CopyTool, PositionTool, ZIndexTool, ImportExportTool, AlignTool, LinkTool, AttractTool, ComponentFactory } from './tools';
7
7
 
8
8
  // 简单的事件系统替代 mitt
9
9
  class SimpleEventEmitter {
@@ -43,6 +43,7 @@ export class Render {
43
43
  alignTool: AlignTool; // 对齐工具
44
44
  linkTool: LinkTool; // 连线工具
45
45
  attractTool: AttractTool; // 磁贴工具
46
+ componentFactory: ComponentFactory; // 统一组件渲染
46
47
  groupTransformer: Konva.Group = new Konva.Group(); // 多选器层
47
48
 
48
49
  // 多选器
@@ -144,6 +145,7 @@ export class Render {
144
145
  this.alignTool = new AlignTool(this); // 对齐工具
145
146
  this.linkTool = new LinkTool(this); // 对齐工具
146
147
  this.attractTool = new AttractTool(this); // 磁贴工具
148
+ this.componentFactory = new ComponentFactory(this); // 统一组件渲染
147
149
 
148
150
  // 事件处理
149
151
  this.handlers[DragHandlers.name] = new DragHandlers(this);
@@ -438,7 +440,8 @@ export class Render {
438
440
 
439
441
  changeDraggable(disabled: boolean) {
440
442
  this.layer.children.forEach((asset) => {
441
- asset.draggable(disabled);
443
+ // 锁定节点始终保持不可拖拽
444
+ asset.draggable(disabled && !asset.attrs.locked);
442
445
  });
443
446
  }
444
447
 
@@ -483,9 +486,6 @@ export class Render {
483
486
  pageHeight: 720,
484
487
  // 样式默认值
485
488
  background: undefined,
486
- stroke: 'rgb(0,0,0)',
487
- strokeWidth: 1,
488
- fill: 'rgb(0,0,0)',
489
489
  linkStroke: 'rgb(0,0,0)',
490
490
  linkStrokeWidth: 1,
491
491
  fontSize: 24,
@@ -524,9 +524,9 @@ export class Render {
524
524
 
525
525
  // 素材设置 默认值
526
526
  static AssetSettingsDefault: AssetSettings = {
527
- stroke: '',
528
- strokeWidth: 0,
529
- fill: '',
527
+ // stroke: '',
528
+ // strokeWidth: 0,
529
+ // fill: '',
530
530
  arrowStart: false,
531
531
  arrowEnd: false,
532
532
  fontSize: 0,
@@ -545,16 +545,12 @@ export class Render {
545
545
  // 特定
546
546
  ...base,
547
547
  // 继承全局
548
- stroke: base.stroke || this.getPageSettings().stroke,
549
- strokeWidth: base.strokeWidth || this.getPageSettings().strokeWidth,
548
+ stroke: base.stroke,
549
+ strokeWidth: base.strokeWidth,
550
550
  fontSize: base.fontSize || this.getPageSettings().fontSize,
551
551
  textFill: base.textFill || this.getPageSettings().textFill,
552
552
  // 绘制图形,默认不填充
553
- fill:
554
- base.fill ||
555
- (asset?.attrs.assetType === AssetType.Graph
556
- ? 'transparent'
557
- : this.getPageSettings().fill),
553
+ fill: base.fill || "transparent",
558
554
  x: parseFloat((asset?.position().x ?? 0).toFixed(1)),
559
555
  y: parseFloat((asset?.position().y ?? 0).toFixed(1)),
560
556
  rotation: parseFloat((asset?.rotation() ?? 0).toFixed(1)),
@@ -616,19 +612,31 @@ export class Render {
616
612
 
617
613
  // 更新素材设置
618
614
  async setAssetSettings(asset: Konva.Node, settings: AssetSettings, update = false) {
619
- asset.setAttr('assetSettings', settings);
620
615
  if (asset instanceof Konva.Group) {
616
+ this.componentFactory.updateComponentSetting({ node: asset, settings }); // 更新组件配置
621
617
  if (asset.attrs.imageType === ImageType.svg) {
622
618
  const node = asset.children[0] as Konva.Shape;
623
619
  if (node instanceof Konva.Image) {
624
620
  if (node.attrs.svgXML) {
625
- const n = await this.assetTool.loadSvgXML(
626
- this.setSvgXMLSettings(node.attrs.svgXML, settings)
627
- );
628
- node.parent?.add(n);
629
- node.remove();
630
- node.destroy();
631
- n.zIndex(0);
621
+ // 仅在 stroke/fill 变化时才重建 SVG 节点
622
+ const currentSettings = asset.attrs.assetSettings;
623
+ const strokeChanged = settings.stroke !== currentSettings?.stroke;
624
+ const fillChanged = settings.fill !== currentSettings?.fill;
625
+ if (strokeChanged || fillChanged) {
626
+ const n = await this.assetTool.loadSvgXML(
627
+ this.setSvgXMLSettings(node.attrs.svgXML, settings)
628
+ );
629
+ // 保留旧节点的变换状态
630
+ n.x(node.x());
631
+ n.y(node.y());
632
+ n.scaleX(node.scaleX());
633
+ n.scaleY(node.scaleY());
634
+ n.rotation(node.rotation());
635
+ node.parent?.add(n);
636
+ node.remove();
637
+ node.destroy();
638
+ n.zIndex(0);
639
+ }
632
640
  }
633
641
  }
634
642
  } else if (asset.attrs.assetType === AssetType.Graph) {
@@ -676,10 +684,11 @@ export class Render {
676
684
  }
677
685
 
678
686
  // rotate 会影响 position,不能同时改变
679
- // 区分属性面板正在调整
680
687
  if (Math.abs(settings.rotation - asset.rotation()) >= 0.1) {
681
688
  this.rotateAroundCenter(asset, settings.rotation);
682
- // 同步 position 的变化
689
+ // tooltip 始终箭头朝下,不受 group 旋转影响
690
+ asset.findOne('.tooltip')?.rotation(-asset.rotation());
691
+ // 同步 position 的变化
683
692
  this.emit('asset-position-change', [asset]);
684
693
  } else {
685
694
  const prevSettings = this.getAssetSettings(asset);
@@ -693,12 +702,11 @@ export class Render {
693
702
  }
694
703
  }
695
704
  }
696
-
705
+ asset.setAttr('assetSettings', settings);
697
706
  if (update) {
698
707
  // 更新历史
699
708
  this.updateHistory();
700
709
  }
701
-
702
710
  this.draws[BgDraw.name]?.draw();
703
711
  this.draws[GraphDraw.name]?.draw();
704
712
  this.draws[LinkDraw.name]?.draw();
@@ -706,18 +714,19 @@ export class Render {
706
714
  }
707
715
 
708
716
  // 获取画布上所有素材节点及其配置
709
- getAllAssets(): Array<{ id: string; assetType: AssetType; settings: AssetSettings }> {
717
+ getAllAssets(): Array<{ id: string; assetType: AssetType; settings: AssetSettings, componentType?: string }> {
710
718
  const nodes = this.layer.getChildren((node) => !this.ignore(node));
711
719
  return nodes.map((node) => ({
712
720
  id: node.id(),
713
721
  assetType: node.attrs.assetType as AssetType,
722
+ componentType: node.attrs.componentType,
714
723
  settings: this.getAssetSettings(node)
715
724
  }));
716
725
  }
717
726
 
718
727
  // 根据节点 id 动态更新组件属性
719
728
  updateAssetById(id: string, settings: Partial<AssetSettings>) {
720
- const node = this.layer.findOne(`#${id}`);
729
+ const node: Konva.Group = this.layer.findOne(`#${id}`);
721
730
  if (!node) {
722
731
  console.warn(`[Render.updateAssetById] 未找到节点 id=${id}`);
723
732
  return;
@@ -28,23 +28,38 @@ export class AttractTool {
28
28
  this.alignLines = [];
29
29
  }
30
30
 
31
- getSortItems(rect: AlignRect) {
31
+ // 从选中节点 getClientRect 计算真实边界框,绕过 back rect padding
32
+ private getSelectingNodesRect(nodes: Konva.Node[]): AlignRect | null {
33
+ if (nodes.length === 0) return null;
34
+ let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
35
+ for (const node of nodes) {
36
+ const r = node.getClientRect();
37
+ if (r.x < minX) minX = r.x;
38
+ if (r.y < minY) minY = r.y;
39
+ if (r.x + r.width > maxX) maxX = r.x + r.width;
40
+ if (r.y + r.height > maxY) maxY = r.y + r.height;
41
+ }
42
+ return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
43
+ }
44
+
45
+ getSortItems(rect: AlignRect, targetPadding?: number) {
32
46
  const stageState = this.render.getStageState();
47
+ const padding = targetPadding ?? this.render.transformer.padding();
33
48
  // 横向所有需要判断对齐的 x 坐标
34
49
  const sortX: Array<SortItem> = [];
35
50
  // 纵向向所有需要判断对齐的 y 坐标
36
51
  const sortY: Array<SortItem> = [];
37
- // 选择目标所有的对齐 x
52
+ // 选择目标所有的对齐 x(使用实际节点边缘而非 back rect,补偿 padding)
38
53
  sortX.push(
39
- { value: this.render.toStageValue(rect.x - stageState.x) },
54
+ { value: this.render.toStageValue(rect.x - stageState.x + padding) },
40
55
  { value: this.render.toStageValue(rect.x - stageState.x + rect.width / 2) },
41
- { value: this.render.toStageValue(rect.x - stageState.x + rect.width) }
56
+ { value: this.render.toStageValue(rect.x - stageState.x + rect.width - padding) }
42
57
  );
43
- // 选择目标所有的对齐 y
58
+ // 选择目标所有的对齐 y(使用实际节点边缘而非 back rect,补偿 padding)
44
59
  sortY.push(
45
- { value: this.render.toStageValue(rect.y - stageState.y) },
60
+ { value: this.render.toStageValue(rect.y - stageState.y + padding) },
46
61
  { value: this.render.toStageValue(rect.y - stageState.y + rect.height / 2) },
47
- { value: this.render.toStageValue(rect.y - stageState.y + rect.height) }
62
+ { value: this.render.toStageValue(rect.y - stageState.y + rect.height - padding) }
48
63
  );
49
64
  // 拖动目标
50
65
  const targetIds = this.render.selectionTool.selectingNodes.map((o) => o._id);
@@ -72,6 +87,7 @@ export class AttractTool {
72
87
  attractPoint = (pos: Konva.Vector2d) => {
73
88
  this.alignLinesClear(); // 对齐线清除
74
89
  const stageState = this.render.getStageState();
90
+ const showGrid = this.render.showGrid; // 是否显示网格,不显示网格则不网格吸附
75
91
  let newPosX = pos.x;
76
92
  let newPosY = pos.y;
77
93
  let isAttract = false;
@@ -190,7 +206,7 @@ export class AttractTool {
190
206
  }
191
207
  }
192
208
  }
193
- if (!this.render.config.readonly && this.render.config.attractBg) {
209
+ if (!this.render.config.readonly && this.render.config.attractBg && showGrid) {
194
210
  // 没有 x 对齐节点
195
211
  if (pairX === null) {
196
212
  const logicLeftX = this.render.toStageValue(newPosX - stageState.x); // x坐标
@@ -257,6 +273,7 @@ export class AttractTool {
257
273
  const stageState = this.render.getStageState();
258
274
  const width = this.render.transformer.width();
259
275
  const height = this.render.transformer.height();
276
+ const showGrid = this.render.showGrid; // 是否显示网格,不显示网格则不网格吸附
260
277
  let newPosX = rect.x;
261
278
  let newPosY = rect.y;
262
279
  let isAttract = false;
@@ -264,7 +281,10 @@ export class AttractTool {
264
281
  let pairY: SortItemPair | null = null;
265
282
  // 对齐线 磁吸逻辑
266
283
  if (!this.render.config.readonly && this.render.config.attractNode) {
267
- const { sortX, sortY } = this.getSortItems(rect);
284
+ // 从选中节点的真实 getClientRect 计算边界框,避免 back rect 的 padding 补偿引入亚像素偏差
285
+ const selectingNodes = this.render.selectionTool.selectingNodes;
286
+ const nodeRect = this.getSelectingNodesRect(selectingNodes) ?? rect;
287
+ const { sortX, sortY } = this.getSortItems(nodeRect, 0);
268
288
  // x 最短距离
269
289
  let XMin = Infinity;
270
290
  // x 最短距离的【对】(多个)
@@ -375,7 +395,7 @@ export class AttractTool {
375
395
  }
376
396
  }
377
397
  }
378
- if (!this.render.config.readonly && this.render.config.attractBg) {
398
+ if (!this.render.config.readonly && this.render.config.attractBg && showGrid) { // 显示网格则执行网格磁吸
379
399
  // 没有 x 对齐节点
380
400
  if (pairX === null) {
381
401
  const logicLeftX = this.render.toStageValue(newPosX - stageState.x); // x坐标