# 拖拽 Dnd
在流程图编辑场景中比起通过代码配置注册节点以外,我们可能更需要通过图形用户界面来操作创建流程图,这时候就可以通过拖拽的方式来实现。
拖拽需要结合图形面板来实现,步骤:创建面板 → 拖拽初始化 → 监听drop事件创建节点
示例如下:
// 顶层App组件,渲染画布,对图形面板绑定拖拽事件
export default class App extends Component<IProps, IState> {
lf: LogicFlow;
componentDidMount() {
this.lf = new LogicFlow({
container: document.querySelector('#graph'),
width: 700,
height: 600,
});
this.lf.render();
}
mouseDownHandle = config => {
this.lf.dnd.startDrag(config);
};
render() {
return (
<div className="designer">
<Panel mouseDownHandle={this.mouseDownHandle} />
<div
className="viewport"
id="graph"
/>
</div>
);
}
}
// Panel组件
export default class Panel extends Component<IProps, IState> {
constructor() {
super();
this.state = {
shapeList: [
{
type: 'rect',
text: '矩形',
},
{
type: 'circle',
text: '圆形',
},
],
};
}
mouseDown({ type, text }) {
const { mouseDownHandle } = this.props;
mouseDownHandle({
type,
text,
});
}
render() {
const { shapeList } = this.state;
return (
<div>
{shapeList.map(shape => {
const { type, text } = shape;
return (
<div className="panel-item">
<div
className={`panel-${type}`}
onMouseDown={() => { this.mouseDown(shape); }}
/>
<span>{text}</span>
</div>
);
})}
</div>
);
}
}
通过上面的代码可以看出,将节点通过div
标签+css
样式的方式绘制到面板中,并为其绑定onMouseDown
事件,当拖拽图形时,会触发lf.dnd.startDrag
函数,表示开始拖拽,并传入选中图形的配置,startDrag
入参格式:
startDrag(nodeConfig: NodeConfig):void
type NodeConfig = {
id?: string;
type: string;
x: number;
y: number;
text?: TextConfig;
properties?: Record<string, unknown>;
};
拖拽结束鼠标松开时,将当前鼠标的位置转换为画布上的坐标,并以此为节点的中心点坐标x
、y
,合并拖拽节点传入的nodeConfig
,监听到drop事件后会调用lf.addNode
方法创建节点。
注意:如果是用图片作为配置面板中添加节点的元素,需要将其设置为不可拖动的。详细请参考#267 (opens new window)