拖拽实现

This commit is contained in:
戚辰先生 2024-12-05 21:31:16 +08:00
parent 0713c2c83e
commit 4b37225a50

View File

@ -3,11 +3,12 @@ import {useNavigate, useParams} from 'react-router-dom';
import {Button, Card, Layout, message, Space, Spin} from 'antd';
import {ArrowLeftOutlined, SaveOutlined} from '@ant-design/icons';
import {getDefinition, updateDefinition} from '../../service';
import {NodeType, WorkflowDefinition, WorkflowStatus} from '../../../Workflow/types';
import {WorkflowDefinition, WorkflowStatus} from '../../../Workflow/types';
import {Graph} from '@antv/x6';
import '@antv/x6-react-shape';
import './index.module.less';
import NodePanel from './components/NodePanel';
import { NodeType } from './service';
const {Sider, Content} = Layout;
@ -18,6 +19,7 @@ const FlowDesigner: React.FC = () => {
const [detail, setDetail] = useState<WorkflowDefinition>();
const containerRef = useRef<HTMLDivElement>(null);
const graphRef = useRef<Graph>();
const draggedNodeRef = useRef<NodeType>();
// 初始化图形
const initGraph = () => {
@ -102,27 +104,11 @@ const FlowDesigner: React.FC = () => {
vertexAddable: true,
vertexDeletable: true,
},
scroller: {
enabled: true,
pannable: true,
pageVisible: false,
pageBreak: false,
translating: {
restrict: true,
},
history: {
enabled: true,
},
clipboard: {
enabled: true,
},
keyboard: {
enabled: true,
},
selecting: {
enabled: true,
multiple: true,
rubberband: true,
movable: true,
showNodeSelectionBox: true,
background: {
color: '#F8F9FA',
},
});
@ -137,6 +123,115 @@ const FlowDesigner: React.FC = () => {
message.error('加载流程图数据失败');
}
}
// 监听画布拖拽事件
containerRef.current.addEventListener('dragover', handleDragOver);
containerRef.current.addEventListener('drop', handleDrop);
};
// 处理拖拽移动
const handleDragOver = (e: DragEvent) => {
e.preventDefault();
e.dataTransfer!.dropEffect = 'copy';
};
// 处理拖拽放置
const handleDrop = (e: DragEvent) => {
e.preventDefault();
const nodeType = draggedNodeRef.current;
if (!nodeType || !graphRef.current || !containerRef.current) return;
// 获取画布相对位置
const rect = containerRef.current.getBoundingClientRect();
const point = {
x: e.clientX - rect.left,
y: e.clientY - rect.top,
};
// 获取画布缩放和平移信息
const matrix = graphRef.current.matrix();
const scale = matrix.a;
const offsetX = matrix.e;
const offsetY = matrix.f;
// 计算实际位置(考虑缩放和平移)
const position = {
x: (point.x - offsetX) / scale,
y: (point.y - offsetY) / scale,
};
// 创建节点
const node = graphRef.current.addNode({
x: position.x - 90, // 节点宽度的一半,使节点中心对准鼠标
y: position.y - 20, // 节点高度的一半,使节点中心对准鼠标
width: 180,
height: 40,
label: nodeType.name,
attrs: {
body: {
fill: '#fff',
stroke: nodeType.color,
strokeWidth: 1,
rx: 4,
ry: 4,
},
label: {
fill: '#333',
fontSize: 14,
refX: 0.5,
refY: 0.5,
textAnchor: 'middle',
textVerticalAnchor: 'middle',
},
},
ports: {
groups: {
in: {
position: 'left',
attrs: {
circle: {
r: 4,
magnet: true,
stroke: '#5F95FF',
strokeWidth: 1,
fill: '#fff',
},
},
},
out: {
position: 'right',
attrs: {
circle: {
r: 4,
magnet: true,
stroke: '#5F95FF',
strokeWidth: 1,
fill: '#fff',
},
},
},
},
items: [
{
id: 'port-in',
group: 'in',
},
{
id: 'port-out',
group: 'out',
},
],
},
data: {
type: nodeType.code,
config: {},
},
});
// 选中新创建的节点
const cells = graphRef.current.getSelectedCells();
cells.forEach(cell => cell.unselect());
node.select();
};
// 获取详情
@ -185,12 +280,18 @@ const FlowDesigner: React.FC = () => {
if (detail && containerRef.current) {
initGraph();
}
// 清理事件监听
return () => {
if (containerRef.current) {
containerRef.current.removeEventListener('dragover', handleDragOver);
containerRef.current.removeEventListener('drop', handleDrop);
}
};
}, [detail, containerRef.current]);
// 处理节点拖拽开始
const handleNodeDragStart = (nodeType: NodeType) => {
// TODO: 实现节点拖拽创建
console.log('Node drag start:', nodeType);
draggedNodeRef.current = nodeType;
};
if (loading) {