KonvaJS如何实现两形状间的箭头连接且支持鼠标拖动调整位置
Konva 可自由拖动调整箭头实现方案
实现逻辑很简单:给箭头的首尾两端各绑定一个可拖动的控制点,拖动控制点时实时更新箭头路径即可,不需要删除原有箭头重建。
基础实现步骤
- 第一步:定义变量存储箭头首尾端点的坐标,同时创建箭头实例和两个可拖动的锚点(锚点可以根据需求设置为默认隐藏,hover箭头时显示)
核心代码示例:
// 初始化箭头首尾坐标,可替换为你现有两个自定义形状的连接点坐标 let arrowPoints = { startX: 100, startY: 150, endX: 300, endY: 150 } // 箭头实例 const connectionArrow = new Konva.Arrow({ points: [arrowPoints.startX, arrowPoints.startY, arrowPoints.endX, arrowPoints.endY], pointerLength: 10, pointerWidth: 10, fill: '#222', stroke: '#222', strokeWidth: 2, // 可选:开启箭头整体拖动 // draggable: true }) // 首尾拖动锚点 const startAnchor = new Konva.Circle({ x: arrowPoints.startX, y: arrowPoints.startY, radius: 5, fill: '#fff', stroke: '#222', strokeWidth: 2, draggable: true }) const endAnchor = new Konva.Circle({ x: arrowPoints.endX, y: arrowPoints.endY, radius: 5, fill: '#fff', stroke: '#222', strokeWidth: 2, draggable: true }) // 将元素添加到图层 layer.add(connectionArrow, startAnchor, endAnchor) layer.draw()
- 第二步:给锚点绑定拖动事件,拖动时实时更新箭头路径
// 起点锚点拖动更新 startAnchor.on('dragmove', (e) => { const newX = e.target.x() const newY = e.target.y() arrowPoints.startX = newX arrowPoints.startY = newY // 更新箭头点位 connectionArrow.points([newX, newY, arrowPoints.endX, arrowPoints.endY]) layer.batchDraw() }) // 终点锚点拖动更新 endAnchor.on('dragmove', (e) => { const newX = e.target.x() const newY = e.target.y() arrowPoints.endX = newX arrowPoints.endY = newY connectionArrow.points([arrowPoints.startX, arrowPoints.startY, newX, newY]) layer.batchDraw() })
可选优化
如果需要支持直接拖动箭头整体移动,给箭头添加dragmove事件即可:
connectionArrow.on('dragmove', (e) => { const moveOffsetX = e.target.x() - arrowPoints.startX const moveOffsetY = e.target.y() - arrowPoints.startY // 同步更新两个锚点坐标 startAnchor.x(startAnchor.x() + moveOffsetX) startAnchor.y(startAnchor.y() + moveOffsetY) endAnchor.x(endAnchor.x() + moveOffsetX) endAnchor.y(endAnchor.y() + moveOffsetY) // 更新存储的坐标 arrowPoints.startX += moveOffsetX arrowPoints.startY += moveOffsetY arrowPoints.endX += moveOffsetX arrowPoints.endY += moveOffsetY layer.batchDraw() })
如果需要箭头端点吸附到自定义形状,只需要在锚点的dragend事件中判断锚点是否落在目标形状范围内,修正坐标即可。
内容的提问来源于stack exchange,提问作者Dijkstra Algorithm
相关产品推荐
相关产品推荐

