Feat: 关联线拖动效果优化

This commit is contained in:
eseasky 2023-08-30 20:11:44 +08:00 committed by yhyf123/chent
parent df2dc96ba5
commit 91bc0351b8
3 changed files with 70 additions and 45 deletions

View File

@ -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) => {

View File

@ -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
} }

View File

@ -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)]
} }