Fix:重构节点拖拽逻辑,修复节点拖拽没有适配各种结构的问题
This commit is contained in:
parent
b09d408ab3
commit
13f571e0b5
@ -212,9 +212,6 @@ class Drag extends Base {
|
|||||||
if (!this.drawTransform || !this.placeholder) {
|
if (!this.drawTransform || !this.placeholder) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const { nodeDragPlaceholderMaxSize } = this.mindMap.opt
|
|
||||||
let x = this.mouseMoveX
|
|
||||||
let y = this.mouseMoveY
|
|
||||||
this.overlapNode = null
|
this.overlapNode = null
|
||||||
this.prevNode = null
|
this.prevNode = null
|
||||||
this.nextNode = null
|
this.nextNode = null
|
||||||
@ -229,94 +226,33 @@ class Drag extends Base {
|
|||||||
if (this.overlapNode || (this.prevNode && this.nextNode)) {
|
if (this.overlapNode || (this.prevNode && this.nextNode)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let nodeRect = this.getNodeRect(node)
|
switch (this.mindMap.opt.layout) {
|
||||||
let oneFourthHeight = nodeRect.height / 4
|
case 'logicalStructure':
|
||||||
// 前一个和后一个节点
|
this.handleLogicalStructure(node)
|
||||||
let checkList = node.parent
|
break
|
||||||
? node.parent.children.filter(item => {
|
case 'mindMap':
|
||||||
return item !== this.node
|
this.handleMindMap(node)
|
||||||
})
|
break
|
||||||
: []
|
case 'organizationStructure':
|
||||||
let index = checkList.findIndex(item => {
|
this.handleOrganizationStructure(node)
|
||||||
return item.uid === node.uid
|
break
|
||||||
})
|
case 'catalogOrganization':
|
||||||
let prevBrother = null
|
this.handleCatalogOrganization(node)
|
||||||
let nextBrother = null
|
break
|
||||||
if (index !== -1) {
|
case 'timeline':
|
||||||
if (index - 1 >= 0) {
|
this.handleTimeLine(node)
|
||||||
prevBrother = checkList[index - 1]
|
break
|
||||||
}
|
case 'timeline2':
|
||||||
if (index + 1 <= checkList.length - 1) {
|
this.handleTimeLine2(node)
|
||||||
nextBrother = checkList[index + 1]
|
break
|
||||||
}
|
case 'verticalTimeline':
|
||||||
}
|
this.handleLogicalStructure(node)
|
||||||
// 和前一个兄弟节点的距离
|
break
|
||||||
let prevBrotherOffset = 0
|
case 'fishbone':
|
||||||
if (prevBrother) {
|
this.handleFishbone(node)
|
||||||
let prevNodeRect = this.getNodeRect(prevBrother)
|
break
|
||||||
prevBrotherOffset = nodeRect.top - prevNodeRect.bottom
|
default:
|
||||||
// 间距小于10就当它不存在
|
this.handleLogicalStructure(node)
|
||||||
prevBrotherOffset =
|
|
||||||
prevBrotherOffset >= this.minOffset ? prevBrotherOffset / 2 : 0
|
|
||||||
} else {
|
|
||||||
// 没有前一个兄弟节点,那么假设和前一个节点的距离为20
|
|
||||||
prevBrotherOffset = this.minOffset
|
|
||||||
}
|
|
||||||
// 和后一个兄弟节点的距离
|
|
||||||
let nextBrotherOffset = 0
|
|
||||||
if (nextBrother) {
|
|
||||||
let nextNodeRect = this.getNodeRect(nextBrother)
|
|
||||||
nextBrotherOffset = nextNodeRect.top - nodeRect.bottom
|
|
||||||
nextBrotherOffset =
|
|
||||||
nextBrotherOffset >= this.minOffset ? nextBrotherOffset / 2 : 0
|
|
||||||
} else {
|
|
||||||
nextBrotherOffset = this.minOffset
|
|
||||||
}
|
|
||||||
if (nodeRect.left <= x && nodeRect.right >= x) {
|
|
||||||
// 检测兄弟节点位置
|
|
||||||
if (
|
|
||||||
!this.overlapNode &&
|
|
||||||
!this.prevNode &&
|
|
||||||
!this.nextNode &&
|
|
||||||
!node.isRoot
|
|
||||||
) {
|
|
||||||
let checkIsPrevNode =
|
|
||||||
nextBrotherOffset > 0 // 距离下一个兄弟节点的距离大于0
|
|
||||||
? y > nodeRect.bottom && y <= nodeRect.bottom + nextBrotherOffset // 那么在当前节点外底部判断
|
|
||||||
: y >= nodeRect.bottom - oneFourthHeight && y <= nodeRect.bottom // 否则在当前节点内底部1/4区间判断
|
|
||||||
let checkIsNextNode =
|
|
||||||
prevBrotherOffset > 0 // 距离上一个兄弟节点的距离大于0
|
|
||||||
? y < nodeRect.top && y >= nodeRect.top - prevBrotherOffset // 那么在当前节点外底部判断
|
|
||||||
: y >= nodeRect.top && y <= nodeRect.top + oneFourthHeight
|
|
||||||
if (checkIsPrevNode) {
|
|
||||||
this.prevNode = node
|
|
||||||
let size =
|
|
||||||
nextBrotherOffset > 0
|
|
||||||
? Math.min(nextBrotherOffset, nodeDragPlaceholderMaxSize)
|
|
||||||
: 5
|
|
||||||
this.placeholder
|
|
||||||
.size(node.width, size)
|
|
||||||
.move(nodeRect.originLeft, nodeRect.originBottom)
|
|
||||||
} else if (checkIsNextNode) {
|
|
||||||
this.nextNode = node
|
|
||||||
let size =
|
|
||||||
prevBrotherOffset > 0
|
|
||||||
? Math.min(prevBrotherOffset, nodeDragPlaceholderMaxSize)
|
|
||||||
: 5
|
|
||||||
this.placeholder
|
|
||||||
.size(node.width, size)
|
|
||||||
.move(nodeRect.originLeft, nodeRect.originTop - size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 检测是否重叠
|
|
||||||
if (!this.overlapNode && !this.prevNode && !this.nextNode) {
|
|
||||||
if (
|
|
||||||
nodeRect.top + (prevBrotherOffset > 0 ? 0 : oneFourthHeight) <= y &&
|
|
||||||
nodeRect.bottom - (nextBrotherOffset > 0 ? 0 : oneFourthHeight) >= y
|
|
||||||
) {
|
|
||||||
this.overlapNode = node
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (this.overlapNode) {
|
if (this.overlapNode) {
|
||||||
@ -324,6 +260,299 @@ class Drag extends Base {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 垂直方向比较
|
||||||
|
// isReverse:是否反向
|
||||||
|
handleVerticalCheck(node, checkList, isReverse = false) {
|
||||||
|
let x = this.mouseMoveX
|
||||||
|
let y = this.mouseMoveY
|
||||||
|
let nodeRect = this.getNodeRect(node)
|
||||||
|
if (isReverse) {
|
||||||
|
checkList = checkList.reverse()
|
||||||
|
}
|
||||||
|
let oneFourthHeight = nodeRect.height / 4
|
||||||
|
let { prevBrotherOffset, nextBrotherOffset } =
|
||||||
|
this.getNodeDistanceToSiblingNode(checkList, node, nodeRect, 'v')
|
||||||
|
if (nodeRect.left <= x && nodeRect.right >= x) {
|
||||||
|
// 检测兄弟节点位置
|
||||||
|
if (
|
||||||
|
!this.overlapNode &&
|
||||||
|
!this.prevNode &&
|
||||||
|
!this.nextNode &&
|
||||||
|
!node.isRoot
|
||||||
|
) {
|
||||||
|
let checkIsPrevNode =
|
||||||
|
nextBrotherOffset > 0 // 距离下一个兄弟节点的距离大于0
|
||||||
|
? y > nodeRect.bottom && y <= nodeRect.bottom + nextBrotherOffset // 那么在当前节点外底部判断
|
||||||
|
: y >= nodeRect.bottom - oneFourthHeight && y <= nodeRect.bottom // 否则在当前节点内底部1/4区间判断
|
||||||
|
let checkIsNextNode =
|
||||||
|
prevBrotherOffset > 0 // 距离上一个兄弟节点的距离大于0
|
||||||
|
? y < nodeRect.top && y >= nodeRect.top - prevBrotherOffset // 那么在当前节点外底部判断
|
||||||
|
: y >= nodeRect.top && y <= nodeRect.top + oneFourthHeight
|
||||||
|
if (checkIsPrevNode) {
|
||||||
|
if (isReverse) {
|
||||||
|
this.nextNode = node
|
||||||
|
} else {
|
||||||
|
this.prevNode = node
|
||||||
|
}
|
||||||
|
let size = this.formatPlaceholderSize(nextBrotherOffset)
|
||||||
|
this.setPlaceholderRect(
|
||||||
|
node.width,
|
||||||
|
size,
|
||||||
|
nodeRect.originLeft,
|
||||||
|
nodeRect.originBottom
|
||||||
|
)
|
||||||
|
} else if (checkIsNextNode) {
|
||||||
|
if (isReverse) {
|
||||||
|
this.prevNode = node
|
||||||
|
} else {
|
||||||
|
this.nextNode = node
|
||||||
|
}
|
||||||
|
let size = this.formatPlaceholderSize(prevBrotherOffset)
|
||||||
|
this.setPlaceholderRect(
|
||||||
|
node.width,
|
||||||
|
size,
|
||||||
|
nodeRect.originLeft,
|
||||||
|
nodeRect.originTop - size
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 检测是否重叠
|
||||||
|
this.checkIsOverlap({
|
||||||
|
node,
|
||||||
|
dir: 'v',
|
||||||
|
prevBrotherOffset,
|
||||||
|
nextBrotherOffset,
|
||||||
|
size: oneFourthHeight,
|
||||||
|
pos: y,
|
||||||
|
nodeRect
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 水平方向比较
|
||||||
|
handleHorizontalCheck(node, checkList) {
|
||||||
|
let x = this.mouseMoveX
|
||||||
|
let y = this.mouseMoveY
|
||||||
|
let nodeRect = this.getNodeRect(node)
|
||||||
|
let oneFourthWidth = nodeRect.width / 4
|
||||||
|
let { prevBrotherOffset, nextBrotherOffset } =
|
||||||
|
this.getNodeDistanceToSiblingNode(checkList, node, nodeRect, 'h')
|
||||||
|
if (nodeRect.top <= y && nodeRect.bottom >= y) {
|
||||||
|
// 检测兄弟节点位置
|
||||||
|
if (
|
||||||
|
!this.overlapNode &&
|
||||||
|
!this.prevNode &&
|
||||||
|
!this.nextNode &&
|
||||||
|
!node.isRoot
|
||||||
|
) {
|
||||||
|
let checkIsPrevNode =
|
||||||
|
nextBrotherOffset > 0 // 距离下一个兄弟节点的距离大于0
|
||||||
|
? x < nodeRect.right + nextBrotherOffset && x >= nodeRect.right // 那么在当前节点外底部判断
|
||||||
|
: x <= nodeRect.right && x >= nodeRect.right - oneFourthWidth // 否则在当前节点内底部1/4区间判断
|
||||||
|
let checkIsNextNode =
|
||||||
|
prevBrotherOffset > 0 // 距离上一个兄弟节点的距离大于0
|
||||||
|
? x > nodeRect.left - prevBrotherOffset && x <= nodeRect.left // 那么在当前节点外底部判断
|
||||||
|
: x <= nodeRect.left + oneFourthWidth && x >= nodeRect.left
|
||||||
|
if (checkIsPrevNode) {
|
||||||
|
this.prevNode = node
|
||||||
|
let size = this.formatPlaceholderSize(nextBrotherOffset)
|
||||||
|
this.setPlaceholderRect(
|
||||||
|
size,
|
||||||
|
node.height,
|
||||||
|
nodeRect.originRight,
|
||||||
|
nodeRect.originTop
|
||||||
|
)
|
||||||
|
} else if (checkIsNextNode) {
|
||||||
|
this.nextNode = node
|
||||||
|
let size = this.formatPlaceholderSize(prevBrotherOffset)
|
||||||
|
this.setPlaceholderRect(
|
||||||
|
size,
|
||||||
|
node.height,
|
||||||
|
nodeRect.originLeft - size,
|
||||||
|
nodeRect.originTop
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 检测是否重叠
|
||||||
|
this.checkIsOverlap({
|
||||||
|
node,
|
||||||
|
dir: 'h',
|
||||||
|
prevBrotherOffset,
|
||||||
|
nextBrotherOffset,
|
||||||
|
size: oneFourthWidth,
|
||||||
|
pos: x,
|
||||||
|
nodeRect
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取节点距前一个和后一个节点的距离
|
||||||
|
getNodeDistanceToSiblingNode(checkList, node, nodeRect, dir) {
|
||||||
|
let dir1 = dir === 'v' ? 'top' : 'left'
|
||||||
|
let dir2 = dir === 'v' ? 'bottom' : 'right'
|
||||||
|
let index = checkList.findIndex(item => {
|
||||||
|
return item.uid === node.uid
|
||||||
|
})
|
||||||
|
let prevBrother = null
|
||||||
|
let nextBrother = null
|
||||||
|
if (index !== -1) {
|
||||||
|
if (index - 1 >= 0) {
|
||||||
|
prevBrother = checkList[index - 1]
|
||||||
|
}
|
||||||
|
if (index + 1 <= checkList.length - 1) {
|
||||||
|
nextBrother = checkList[index + 1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 和前一个兄弟节点的距离
|
||||||
|
let prevBrotherOffset = 0
|
||||||
|
if (prevBrother) {
|
||||||
|
let prevNodeRect = this.getNodeRect(prevBrother)
|
||||||
|
prevBrotherOffset = nodeRect[dir1] - prevNodeRect[dir2]
|
||||||
|
// 间距小于10就当它不存在
|
||||||
|
prevBrotherOffset =
|
||||||
|
prevBrotherOffset >= this.minOffset ? prevBrotherOffset / 2 : 0
|
||||||
|
} else {
|
||||||
|
// 没有前一个兄弟节点,那么假设和前一个节点的距离为20
|
||||||
|
prevBrotherOffset = this.minOffset
|
||||||
|
}
|
||||||
|
// 和后一个兄弟节点的距离
|
||||||
|
let nextBrotherOffset = 0
|
||||||
|
if (nextBrother) {
|
||||||
|
let nextNodeRect = this.getNodeRect(nextBrother)
|
||||||
|
nextBrotherOffset = nextNodeRect[dir1] - nodeRect[dir2]
|
||||||
|
nextBrotherOffset =
|
||||||
|
nextBrotherOffset >= this.minOffset ? nextBrotherOffset / 2 : 0
|
||||||
|
} else {
|
||||||
|
nextBrotherOffset = this.minOffset
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
prevBrotherOffset,
|
||||||
|
nextBrotherOffset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理提示元素的大小
|
||||||
|
formatPlaceholderSize(size) {
|
||||||
|
const { nodeDragPlaceholderMaxSize } = this.mindMap.opt
|
||||||
|
return size > 0 ? Math.min(size, nodeDragPlaceholderMaxSize) : 5
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置提示元素的大小和位置
|
||||||
|
setPlaceholderRect(w, h, x, y) {
|
||||||
|
this.placeholder.size(w, h).move(x, y)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测是否重叠
|
||||||
|
checkIsOverlap({
|
||||||
|
node,
|
||||||
|
dir,
|
||||||
|
prevBrotherOffset,
|
||||||
|
nextBrotherOffset,
|
||||||
|
size,
|
||||||
|
pos,
|
||||||
|
nodeRect
|
||||||
|
}) {
|
||||||
|
let dir1 = dir === 'v' ? 'top' : 'left'
|
||||||
|
let dir2 = dir === 'v' ? 'bottom' : 'right'
|
||||||
|
if (!this.overlapNode && !this.prevNode && !this.nextNode) {
|
||||||
|
if (
|
||||||
|
nodeRect[dir1] + (prevBrotherOffset > 0 ? 0 : size) <= pos &&
|
||||||
|
nodeRect[dir2] - (nextBrotherOffset > 0 ? 0 : size) >= pos
|
||||||
|
) {
|
||||||
|
this.overlapNode = node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理逻辑结构图
|
||||||
|
handleLogicalStructure(node) {
|
||||||
|
const checkList = this.commonGetNodeCheckList(node)
|
||||||
|
this.handleVerticalCheck(node, checkList)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理思维导图
|
||||||
|
handleMindMap(node) {
|
||||||
|
const checkList = node.parent
|
||||||
|
? node.parent.children.filter(item => {
|
||||||
|
let sameDir = true
|
||||||
|
if (node.layerIndex === 1) {
|
||||||
|
sameDir = item.dir === node.dir
|
||||||
|
}
|
||||||
|
return item !== this.node && sameDir
|
||||||
|
})
|
||||||
|
: []
|
||||||
|
this.handleVerticalCheck(node, checkList)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理组织结构图
|
||||||
|
handleOrganizationStructure(node) {
|
||||||
|
const checkList = this.commonGetNodeCheckList(node)
|
||||||
|
this.handleHorizontalCheck(node, checkList)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理目录组织图
|
||||||
|
handleCatalogOrganization(node) {
|
||||||
|
const checkList = this.commonGetNodeCheckList(node)
|
||||||
|
if (node.layerIndex === 1) {
|
||||||
|
this.handleHorizontalCheck(node, checkList)
|
||||||
|
} else {
|
||||||
|
this.handleVerticalCheck(node, checkList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理时间轴
|
||||||
|
handleTimeLine(node) {
|
||||||
|
let checkList = this.commonGetNodeCheckList(node)
|
||||||
|
if (node.layerIndex === 1) {
|
||||||
|
this.handleHorizontalCheck(node, checkList)
|
||||||
|
} else {
|
||||||
|
this.handleVerticalCheck(node, checkList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理时间轴2
|
||||||
|
handleTimeLine2(node) {
|
||||||
|
let checkList = this.commonGetNodeCheckList(node)
|
||||||
|
if (node.layerIndex === 1) {
|
||||||
|
this.handleHorizontalCheck(node, checkList)
|
||||||
|
} else {
|
||||||
|
// 处于上方的三级节点需要特殊处理,因为节点排列方向反向了
|
||||||
|
if (node.dir === 'top' && node.layerIndex === 2) {
|
||||||
|
this.handleVerticalCheck(node, checkList, true)
|
||||||
|
} else {
|
||||||
|
this.handleVerticalCheck(node, checkList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理鱼骨图
|
||||||
|
handleFishbone(node) {
|
||||||
|
let checkList = node.parent
|
||||||
|
? node.parent.children.filter(item => {
|
||||||
|
return item !== this.node && item.layerIndex > 1
|
||||||
|
})
|
||||||
|
: []
|
||||||
|
if (node.layerIndex === 1) {
|
||||||
|
this.handleHorizontalCheck(node, checkList)
|
||||||
|
} else {
|
||||||
|
// 处于上方的三级节点需要特殊处理,因为节点排列方向反向了
|
||||||
|
if (node.dir === 'top' && node.layerIndex === 2) {
|
||||||
|
this.handleVerticalCheck(node, checkList, true)
|
||||||
|
} else {
|
||||||
|
this.handleVerticalCheck(node, checkList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取节点的兄弟节点列表通用方法
|
||||||
|
commonGetNodeCheckList(node) {
|
||||||
|
return node.parent
|
||||||
|
? node.parent.children.filter(item => {
|
||||||
|
return item !== this.node
|
||||||
|
})
|
||||||
|
: []
|
||||||
|
}
|
||||||
|
|
||||||
// 计算节点的位置尺寸信息
|
// 计算节点的位置尺寸信息
|
||||||
getNodeRect(node) {
|
getNodeRect(node) {
|
||||||
let { scaleX, scaleY, translateX, translateY } = this.drawTransform
|
let { scaleX, scaleY, translateX, translateY } = this.drawTransform
|
||||||
@ -331,6 +560,7 @@ class Drag extends Base {
|
|||||||
let originLeft = left
|
let originLeft = left
|
||||||
let originTop = top
|
let originTop = top
|
||||||
let originBottom = top + height
|
let originBottom = top + height
|
||||||
|
let originRight = left + width
|
||||||
let right = (left + width) * scaleX + translateX
|
let right = (left + width) * scaleX + translateX
|
||||||
let bottom = (top + height) * scaleY + translateY
|
let bottom = (top + height) * scaleY + translateY
|
||||||
left = left * scaleX + translateX
|
left = left * scaleX + translateX
|
||||||
@ -344,7 +574,8 @@ class Drag extends Base {
|
|||||||
bottom,
|
bottom,
|
||||||
originLeft,
|
originLeft,
|
||||||
originTop,
|
originTop,
|
||||||
originBottom
|
originBottom,
|
||||||
|
originRight
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user