Feat: 关联线拖动效果优化
This commit is contained in:
parent
df2dc96ba5
commit
91bc0351b8
@ -6,7 +6,8 @@ import {
|
|||||||
cubicBezierPath,
|
cubicBezierPath,
|
||||||
getNodePoint,
|
getNodePoint,
|
||||||
computeNodePoints,
|
computeNodePoints,
|
||||||
getNodeLinePath
|
getNodeLinePath,
|
||||||
|
getDefaultControlPointOffsets
|
||||||
} from './associativeLine/associativeLineUtils'
|
} from './associativeLine/associativeLineUtils'
|
||||||
import associativeLineControlsMethods from './associativeLine/associativeLineControls'
|
import associativeLineControlsMethods from './associativeLine/associativeLineControls'
|
||||||
import associativeLineTextMethods from './associativeLine/associativeLineText'
|
import associativeLineTextMethods from './associativeLine/associativeLineText'
|
||||||
@ -106,22 +107,21 @@ class AssociativeLine {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 判断关联线坐标是否变更,有变更则使用变化后的坐标,无则默认坐标
|
// 判断关联线坐标是否变更,有变更则使用变化后的坐标,无则默认坐标
|
||||||
updateAllLinesPos(node, toNode, associativeLineTargets) {
|
updateAllLinesPos(node, toNode, associativeLinePoint) {
|
||||||
let startPoint = {}
|
let [startPoint, endPoint] = computeNodePoints(node, toNode)
|
||||||
let endPoint = {}
|
|
||||||
let nodeRange = 0
|
let nodeRange = 0
|
||||||
let nodeDir = 'right'
|
let nodeDir = 'right'
|
||||||
let toNodeRange = 0
|
let toNodeRange = 0
|
||||||
let toNodeDir = 'right'
|
let toNodeDir = 'right'
|
||||||
if (associativeLineTargets.startPoint && associativeLineTargets.endPoint) {
|
if (associativeLinePoint.startPoint) {
|
||||||
nodeRange = associativeLineTargets.startPoint.range || 0
|
nodeRange = associativeLinePoint.startPoint.range || 0
|
||||||
nodeDir = associativeLineTargets.startPoint.dir || 'right'
|
nodeDir = associativeLinePoint.startPoint.dir || 'right'
|
||||||
startPoint = getNodePoint(node, nodeDir, nodeRange)
|
startPoint = getNodePoint(node, nodeDir, nodeRange)
|
||||||
toNodeRange = associativeLineTargets.endPoint.range || 0
|
}
|
||||||
toNodeDir = associativeLineTargets.endPoint.dir || 'right'
|
if (associativeLinePoint.endPoint) {
|
||||||
|
toNodeRange = associativeLinePoint.endPoint.range || 0
|
||||||
|
toNodeDir = associativeLinePoint.endPoint.dir || 'right'
|
||||||
endPoint = getNodePoint(toNode, toNodeDir, toNodeRange)
|
endPoint = getNodePoint(toNode, toNodeDir, toNodeRange)
|
||||||
} else {
|
|
||||||
;[startPoint, endPoint] = computeNodePoints(node, toNode)
|
|
||||||
}
|
}
|
||||||
return [startPoint, endPoint]
|
return [startPoint, endPoint]
|
||||||
}
|
}
|
||||||
@ -158,15 +158,15 @@ class AssociativeLine {
|
|||||||
)
|
)
|
||||||
nodeToIds.forEach((ids, node) => {
|
nodeToIds.forEach((ids, node) => {
|
||||||
ids.forEach((id, index) => {
|
ids.forEach((id, index) => {
|
||||||
let toNode = idToNode.get(id.id)
|
let toNode = idToNode.get(id)
|
||||||
if (!node || !toNode) return
|
if (!node || !toNode) return
|
||||||
const associativeLineTargets =
|
const associativeLinePoint =
|
||||||
node.nodeData.data.associativeLineTargets[index] || {}
|
node.nodeData.data.associativeLinePoint[index] || {}
|
||||||
// 切换结构和布局,都会更新坐标
|
// 切换结构和布局,都会更新坐标
|
||||||
const [startPoint, endPoint] = this.updateAllLinesPos(
|
const [startPoint, endPoint] = this.updateAllLinesPos(
|
||||||
node,
|
node,
|
||||||
toNode,
|
toNode,
|
||||||
associativeLineTargets
|
associativeLinePoint
|
||||||
)
|
)
|
||||||
this.drawLine(startPoint, endPoint, node, toNode)
|
this.drawLine(startPoint, endPoint, node, toNode)
|
||||||
})
|
})
|
||||||
@ -346,10 +346,15 @@ class AssociativeLine {
|
|||||||
|
|
||||||
// 计算节点偏移位置
|
// 计算节点偏移位置
|
||||||
getNodePos(node) {
|
getNodePos(node) {
|
||||||
const { translateX, translateY } = this.mindMap.draw.transform()
|
const {
|
||||||
|
scaleX,
|
||||||
|
scaleY,
|
||||||
|
translateX,
|
||||||
|
translateY
|
||||||
|
} = this.mindMap.draw.transform()
|
||||||
const { left, top, width, height } = node
|
const { left, top, width, height } = node
|
||||||
let translateLeft = left + translateX
|
let translateLeft = left * scaleX + translateX
|
||||||
let translateTop = top + translateY
|
let translateTop = top * scaleY + translateY
|
||||||
return {
|
return {
|
||||||
left,
|
left,
|
||||||
top,
|
top,
|
||||||
@ -409,11 +414,11 @@ class AssociativeLine {
|
|||||||
// 将目标节点id保存起来
|
// 将目标节点id保存起来
|
||||||
let list = fromNode.nodeData.data.associativeLineTargets || []
|
let list = fromNode.nodeData.data.associativeLineTargets || []
|
||||||
// 连线节点是否存在相同的id,存在则阻止添加关联线
|
// 连线节点是否存在相同的id,存在则阻止添加关联线
|
||||||
const sameLine = list.some(item => item.id === id)
|
const sameLine = list.some(item => item === id)
|
||||||
if (sameLine) {
|
if (sameLine) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
list.push({ id })
|
list.push(id)
|
||||||
// 保存控制点
|
// 保存控制点
|
||||||
let [startPoint, endPoint] = computeNodePoints(fromNode, toNode)
|
let [startPoint, endPoint] = computeNodePoints(fromNode, toNode)
|
||||||
let controlPoints = computeCubicBezierPathPoints(
|
let controlPoints = computeCubicBezierPathPoints(
|
||||||
@ -435,9 +440,13 @@ class AssociativeLine {
|
|||||||
y: controlPoints[1].y - endPoint.y
|
y: controlPoints[1].y - endPoint.y
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
let associativeLinePoint = fromNode.nodeData.data.associativeLinePoint || []
|
||||||
|
// 记录关联的起始|结束坐标
|
||||||
|
associativeLinePoint[list.length - 1] = [{ startPoint, endPoint }]
|
||||||
this.mindMap.execCommand('SET_NODE_DATA', fromNode, {
|
this.mindMap.execCommand('SET_NODE_DATA', fromNode, {
|
||||||
associativeLineTargets: list,
|
associativeLineTargets: list,
|
||||||
associativeLineTargetControlOffsets: offsetList
|
associativeLineTargetControlOffsets: offsetList,
|
||||||
|
associativeLinePoint
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -448,6 +457,7 @@ class AssociativeLine {
|
|||||||
this.removeControls()
|
this.removeControls()
|
||||||
let {
|
let {
|
||||||
associativeLineTargets,
|
associativeLineTargets,
|
||||||
|
associativeLinePoint,
|
||||||
associativeLineTargetControlOffsets,
|
associativeLineTargetControlOffsets,
|
||||||
associativeLineText
|
associativeLineText
|
||||||
} = node.nodeData.data
|
} = node.nodeData.data
|
||||||
@ -466,6 +476,10 @@ class AssociativeLine {
|
|||||||
associativeLineTargets: associativeLineTargets.filter((_, index) => {
|
associativeLineTargets: associativeLineTargets.filter((_, index) => {
|
||||||
return index !== targetIndex
|
return index !== targetIndex
|
||||||
}),
|
}),
|
||||||
|
// 连接线坐标
|
||||||
|
associativeLinePoint: associativeLinePoint.filter((_, index) => {
|
||||||
|
return index !== targetIndex
|
||||||
|
}),
|
||||||
// 偏移量
|
// 偏移量
|
||||||
associativeLineTargetControlOffsets: associativeLineTargetControlOffsets
|
associativeLineTargetControlOffsets: associativeLineTargetControlOffsets
|
||||||
? associativeLineTargetControlOffsets.filter((_, index) => {
|
? associativeLineTargetControlOffsets.filter((_, index) => {
|
||||||
|
|||||||
@ -61,10 +61,10 @@ function onControlPointMousemove(e) {
|
|||||||
}
|
}
|
||||||
// 更新当前拖拽的控制点的位置
|
// 更新当前拖拽的控制点的位置
|
||||||
this[this.mousedownControlPointKey].x(x - radius).y(y - radius)
|
this[this.mousedownControlPointKey].x(x - radius).y(y - radius)
|
||||||
let [path, clickPath, text, node, toNode] = this.activeLine
|
let [, , , node, toNode] = this.activeLine
|
||||||
let targetIndex = getAssociativeLineTargetIndex(node, toNode)
|
let targetIndex = getAssociativeLineTargetIndex(node, toNode)
|
||||||
const {
|
const {
|
||||||
associativeLineTargets,
|
associativeLinePoint,
|
||||||
associativeLineTargetControlOffsets
|
associativeLineTargetControlOffsets
|
||||||
} = node.nodeData.data
|
} = node.nodeData.data
|
||||||
const nodePos = this.getNodePos(node)
|
const nodePos = this.getNodePos(node)
|
||||||
@ -72,7 +72,7 @@ function onControlPointMousemove(e) {
|
|||||||
let [startPoint, endPoint] = this.updateAllLinesPos(
|
let [startPoint, endPoint] = this.updateAllLinesPos(
|
||||||
node,
|
node,
|
||||||
toNode,
|
toNode,
|
||||||
associativeLineTargets[targetIndex]
|
associativeLinePoint[targetIndex]
|
||||||
)
|
)
|
||||||
this.controlPointMousemoveState.startPoint = startPoint
|
this.controlPointMousemoveState.startPoint = startPoint
|
||||||
this.controlPointMousemoveState.endPoint = endPoint
|
this.controlPointMousemoveState.endPoint = endPoint
|
||||||
@ -99,16 +99,10 @@ function onControlPointMousemove(e) {
|
|||||||
}
|
}
|
||||||
if (startPoint) {
|
if (startPoint) {
|
||||||
// 保存更新后的坐标
|
// 保存更新后的坐标
|
||||||
associativeLineTargets[targetIndex].startPoint = startPoint
|
associativeLinePoint[targetIndex].startPoint = startPoint
|
||||||
this.controlPointMousemoveState.startPoint = startPoint
|
this.controlPointMousemoveState.startPoint = startPoint
|
||||||
// 更新控制点1的连线
|
// 更新控制点1的连线
|
||||||
this.controlLine1.plot(startPoint.x, startPoint.y, point1.x, point1.y)
|
this.controlLine1.plot(startPoint.x, startPoint.y, point1.x, point1.y)
|
||||||
// 更新关联线
|
|
||||||
const pathStr = joinCubicBezierPath(startPoint, endPoint, point1, point2)
|
|
||||||
path.plot(pathStr)
|
|
||||||
clickPath.plot(pathStr)
|
|
||||||
this.updateTextPos(path, text)
|
|
||||||
this.updateTextEditBoxPos(text)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 拖拽的是控制点2
|
// 拖拽的是控制点2
|
||||||
@ -123,18 +117,35 @@ function onControlPointMousemove(e) {
|
|||||||
}
|
}
|
||||||
if (endPoint) {
|
if (endPoint) {
|
||||||
// 保存更新后结束节点的坐标
|
// 保存更新后结束节点的坐标
|
||||||
associativeLineTargets[targetIndex].endPoint = endPoint
|
associativeLinePoint[targetIndex].endPoint = endPoint
|
||||||
this.controlPointMousemoveState.endPoint = endPoint
|
this.controlPointMousemoveState.endPoint = endPoint
|
||||||
// 更新控制点2的连线
|
// 更新控制点2的连线
|
||||||
this.controlLine2.plot(endPoint.x, endPoint.y, point2.x, point2.y)
|
this.controlLine2.plot(endPoint.x, endPoint.y, point2.x, point2.y)
|
||||||
// 更新关联线
|
|
||||||
const pathStr = joinCubicBezierPath(startPoint, endPoint, point1, point2)
|
|
||||||
path.plot(pathStr)
|
|
||||||
clickPath.plot(pathStr)
|
|
||||||
this.updateTextPos(path, text)
|
|
||||||
this.updateTextEditBoxPos(text)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.updataAassociativeLine(
|
||||||
|
startPoint,
|
||||||
|
endPoint,
|
||||||
|
point1,
|
||||||
|
point2,
|
||||||
|
this.activeLine
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function updataAassociativeLine(
|
||||||
|
startPoint,
|
||||||
|
endPoint,
|
||||||
|
point1,
|
||||||
|
point2,
|
||||||
|
activeLine
|
||||||
|
) {
|
||||||
|
const [path, clickPath, text] = activeLine
|
||||||
|
// 更新关联线
|
||||||
|
const pathStr = joinCubicBezierPath(startPoint, endPoint, point1, point2)
|
||||||
|
path.plot(pathStr)
|
||||||
|
clickPath.plot(pathStr)
|
||||||
|
this.updateTextPos(path, text)
|
||||||
|
this.updateTextEditBoxPos(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 控制点的鼠标移动事件
|
// 控制点的鼠标移动事件
|
||||||
@ -151,7 +162,7 @@ function onControlPointMouseup(e) {
|
|||||||
let [, , , node] = this.activeLine
|
let [, , , node] = this.activeLine
|
||||||
let offsetList = []
|
let offsetList = []
|
||||||
const {
|
const {
|
||||||
associativeLineTargets,
|
associativeLinePoint,
|
||||||
associativeLineTargetControlOffsets
|
associativeLineTargetControlOffsets
|
||||||
} = node.nodeData.data
|
} = node.nodeData.data
|
||||||
if (!associativeLineTargetControlOffsets) {
|
if (!associativeLineTargetControlOffsets) {
|
||||||
@ -183,7 +194,7 @@ function onControlPointMouseup(e) {
|
|||||||
offsetList[targetIndex] = [offset1, offset2]
|
offsetList[targetIndex] = [offset1, offset2]
|
||||||
this.mindMap.execCommand('SET_NODE_DATA', node, {
|
this.mindMap.execCommand('SET_NODE_DATA', node, {
|
||||||
associativeLineTargetControlOffsets: offsetList,
|
associativeLineTargetControlOffsets: offsetList,
|
||||||
associativeLineTargets
|
associativeLinePoint
|
||||||
})
|
})
|
||||||
// 这里要加个setTimeout0是因为draw_click事件比mouseup事件触发的晚,所以重置isControlPointMousedown需要等draw_click事件触发完以后
|
// 这里要加个setTimeout0是因为draw_click事件比mouseup事件触发的晚,所以重置isControlPointMousedown需要等draw_click事件触发完以后
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -270,5 +281,6 @@ export default {
|
|||||||
renderControls,
|
renderControls,
|
||||||
removeControls,
|
removeControls,
|
||||||
hideControls,
|
hideControls,
|
||||||
showControls
|
showControls,
|
||||||
|
updataAassociativeLine
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// 获取目标节点在起始节点的目标数组中的索引
|
// 获取目标节点在起始节点的目标数组中的索引
|
||||||
export const getAssociativeLineTargetIndex = (node, toNode) => {
|
export const getAssociativeLineTargetIndex = (node, toNode) => {
|
||||||
return node.nodeData.data.associativeLineTargets.findIndex(item => {
|
return node.nodeData.data.associativeLineTargets.findIndex(item => {
|
||||||
return item.id === toNode.nodeData.data.id
|
return item === toNode.nodeData.data.id
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +54,6 @@ export const cubicBezierPath = (x1, y1, x2, y2) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算关联线起始|结束坐标
|
|
||||||
export const calcPoint = (node, e) => {
|
export const calcPoint = (node, e) => {
|
||||||
const { left, top, translateLeft, translateTop, width, height } = node
|
const { left, top, translateLeft, translateTop, width, height } = node
|
||||||
const clientX = e.clientX
|
const clientX = e.clientX
|
||||||
@ -220,8 +219,8 @@ export const computeNodePoints = (fromNode, toNode) => {
|
|||||||
toDir = 'bottom'
|
toDir = 'bottom'
|
||||||
} else if (offsetY > 0 && -offsetY < offsetX && offsetY > offsetX) {
|
} else if (offsetY > 0 && -offsetY < offsetX && offsetY > offsetX) {
|
||||||
// down
|
// down
|
||||||
fromDir = 'bottom'
|
fromDir = 'right'
|
||||||
toDir = 'top'
|
toDir = 'right'
|
||||||
}
|
}
|
||||||
return [getNodePoint(fromNode, fromDir), getNodePoint(toNode, toDir)]
|
return [getNodePoint(fromNode, fromDir), getNodePoint(toNode, toDir)]
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user