draggable-text-node.js
4.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
/*
* @Date: 2025-03-17 15:40:00
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-03-18 17:17:47
* @FilePath: /logic-flow2/src/views/api/draggable-text-node.js
* @Description: 可拖动文本的矩形节点
*/
import { RectNode, RectNodeModel } from "@logicflow/core";
import { v4 as uuidv4 } from "uuid";
const useNodeBehavior = () => {
const isTextDraggable = ref(true);
const isTextEditable = ref(false);
const behavior = {
nodeStyle: ref({
stroke: '#1E90FF',
fill: '#F0F8FF',
strokeWidth: 1
}),
selectedStyle: ref({
stroke: '#ff7f0e',
strokeWidth: 2
}),
textStyle: ref({
cursor: 'move'
})
};
return {
isTextDraggable,
isTextEditable,
behavior
};
};
class DraggableTextNodeModel extends RectNodeModel {
initNodeData(data) {
// 确保 data.x 和 data.y 有默认值
const nodeX = data.x || 0;
const nodeY = data.y || 0;
// 处理文本数据
if (!data.text || typeof data.text === "string") {
data.text = {
value: data.text || "",
x: nodeX,
y: nodeY + 80,
};
}
super.initNodeData(data);
const { behavior } = useNodeBehavior();
this.behavior = behavior;
this.text.draggable = true;
this.text.editable = false;
}
getNodeStyle() {
/**
* - 合并基础样式
* - 根据选中状态添加额外样式
*/
return {
...this.behavior.nodeStyle.value,
...(this.isSelected ? this.behavior.selectedStyle.value : {})
};
}
getTextStyle() {
/**
* - 扩展原有文本样式
* - 添加自定义样式(如移动光标)
*/
const style = super.getTextStyle();
return {
...style,
...this.behavior.textStyle.value
};
}
getAnchorStyle() {
const style = super.getAnchorStyle();
style.stroke = "rgb(24, 125, 255)";
style.r = 3;
style.hover.r = 8;
style.hover.fill = "rgb(24, 125, 255)";
style.hover.stroke = "rgb(24, 125, 255)";
return style;
}
getAnchorLineStyle() {
const style = super.getAnchorLineStyle();
style.stroke = "rgb(24, 125, 255)";
return style;
}
getOutlineStyle() {
const style = super.getOutlineStyle();
style.stroke = "red";
style.hover.stroke = "yellow";
return style;
}
createId() {
return `custom-rect-${uuidv4()}`;
}
// 定义节点只有左右两个锚点. 锚点位置通过中心点和宽度算出来。
getDefaultAnchor() {
const { width, height, x, y, id } = this;
return [
{
x: x - width / 2,
y,
name: 'left',
id: `${id}_0`
},
{
x: x + width / 2,
y,
name: 'right',
id: `${id}_1`,
// edgeAddable: false
},
]
}
// getConnectedSourceRules(){
// const rules = super.getConnectedSourceRules();
// const getWayOnlyAsTarget = {
// message: "结束节点只能连入,不能连出!",
// validate: ( source, target, sourceAnchor, targetAnchor ) => {
// let isValid = true;
// if (source) {
// isValid = false;
// }
// return isValid;
// },
// };
// rules.push(getWayOnlyAsTarget);
// return rules;
// }
// getConnectedTargetRules() {
// const rules = super.getConnectedTargetRules();
// const notAsTarget = {
// message: "起始节点不能作为边的终点",
// validate: () => false,
// };
// rules.push(notAsTarget);
// return rules;
// }
isAllowMoveNode(deltaX, deltaY) {
let newX = this.x + deltaX
let newY = this.y + deltaY
let isAllowMoveX = true
let isAllowMoveY = true
// 处理
return {
x: isAllowMoveX,
y: isAllowMoveY,
}
}
// isAllowConnectedAsSource(target, sourceAnchor, targetAnchor) {
// // 根据节点类型判断是否允许连线
// if (this.properties.nodeType === 'source') {
// if (target.properties.nodeType === 'target') {
// return false
// }
// return true
// }
// }
// isAllowConnectedAsTarget(source, sourceAnchor, targetAnchor) {
// // 根据节点类型判断是否允许连线
// if (this.properties.nodeType ==='target') {
// if (source.properties.nodeType === 'source') {
// return false
// }
// return true
// }
// }
}
class DraggableTextNode extends RectNode {}
export default {
type: "custom-rect",
view: DraggableTextNode,
model: DraggableTextNodeModel,
};