mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-17 22:08:25 +08:00
242 lines
6.5 KiB
JavaScript
242 lines
6.5 KiB
JavaScript
import {
|
||
getAssociativeLineTargetIndex,
|
||
joinCubicBezierPath,
|
||
computeNodePoints,
|
||
getDefaultControlPointOffsets
|
||
} from './associativeLineUtils'
|
||
|
||
// 创建控制点、连线节点
|
||
function createControlNodes() {
|
||
let { associativeLineActiveColor } = this.mindMap.themeConfig
|
||
// 连线
|
||
this.controlLine1 = this.draw
|
||
.line()
|
||
.stroke({ color: associativeLineActiveColor, width: 2 })
|
||
this.controlLine2 = this.draw
|
||
.line()
|
||
.stroke({ color: associativeLineActiveColor, width: 2 })
|
||
// 控制点
|
||
this.controlPoint1 = this.createOneControlNode('controlPoint1')
|
||
this.controlPoint2 = this.createOneControlNode('controlPoint2')
|
||
}
|
||
|
||
// 创建控制点
|
||
function createOneControlNode(pointKey) {
|
||
let { associativeLineActiveColor } = this.mindMap.themeConfig
|
||
return this.draw
|
||
.circle(this.controlPointDiameter)
|
||
.stroke({ color: associativeLineActiveColor })
|
||
.fill({ color: '#fff' })
|
||
.click(e => {
|
||
e.stopPropagation()
|
||
})
|
||
.mousedown(e => {
|
||
this.onControlPointMousedown(e, pointKey)
|
||
})
|
||
}
|
||
|
||
// 控制点的鼠标按下事件
|
||
function onControlPointMousedown(e, pointKey) {
|
||
e.stopPropagation()
|
||
this.isControlPointMousedown = true
|
||
this.mousedownControlPointKey = pointKey
|
||
}
|
||
|
||
// 控制点的鼠标移动事件
|
||
function onControlPointMousemove(e) {
|
||
if (
|
||
!this.isControlPointMousedown ||
|
||
!this.mousedownControlPointKey ||
|
||
!this[this.mousedownControlPointKey]
|
||
)
|
||
return
|
||
e.stopPropagation()
|
||
e.preventDefault()
|
||
let radius = this.controlPointDiameter / 2
|
||
// 转换鼠标当前的位置
|
||
let { x, y } = this.getTransformedEventPos(e)
|
||
this.controlPointMousemoveState.pos = {
|
||
x,
|
||
y
|
||
}
|
||
// 更新当前拖拽的控制点的位置
|
||
this[this.mousedownControlPointKey].x(x - radius).y(y - radius)
|
||
let [path, clickPath, text, node, toNode] = this.activeLine
|
||
let [startPoint, endPoint] = computeNodePoints(node, toNode)
|
||
this.controlPointMousemoveState.startPoint = startPoint
|
||
this.controlPointMousemoveState.endPoint = endPoint
|
||
let targetIndex = getAssociativeLineTargetIndex(node, toNode)
|
||
this.controlPointMousemoveState.targetIndex = targetIndex
|
||
let offsets = []
|
||
let associativeLineTargetControlOffsets =
|
||
node.nodeData.data.associativeLineTargetControlOffsets
|
||
if (!associativeLineTargetControlOffsets) {
|
||
// 兼容0.4.5版本,没有associativeLineTargetControlOffsets的情况
|
||
offsets = getDefaultControlPointOffsets(startPoint, endPoint)
|
||
} else {
|
||
offsets = associativeLineTargetControlOffsets[targetIndex]
|
||
}
|
||
let point1 = null
|
||
let point2 = null
|
||
// 拖拽的是控制点1
|
||
if (this.mousedownControlPointKey === 'controlPoint1') {
|
||
point1 = {
|
||
x,
|
||
y
|
||
}
|
||
point2 = {
|
||
x: endPoint.x + offsets[1].x,
|
||
y: endPoint.y + offsets[1].y
|
||
}
|
||
// 更新控制点1的连线
|
||
this.controlLine1.plot(startPoint.x, startPoint.y, point1.x, point1.y)
|
||
} else {
|
||
// 拖拽的是控制点2
|
||
point1 = {
|
||
x: startPoint.x + offsets[0].x,
|
||
y: startPoint.y + offsets[0].y
|
||
}
|
||
point2 = {
|
||
x,
|
||
y
|
||
}
|
||
// 更新控制点2的连线
|
||
this.controlLine2.plot(endPoint.x, endPoint.y, point2.x, point2.y)
|
||
}
|
||
// 更新关联线
|
||
let pathStr = joinCubicBezierPath(startPoint, endPoint, point1, point2)
|
||
path.plot(pathStr)
|
||
clickPath.plot(pathStr)
|
||
this.updateTextPos(path, text)
|
||
this.updateTextEditBoxPos(text)
|
||
}
|
||
|
||
// 控制点的鼠标移动事件
|
||
function onControlPointMouseup(e) {
|
||
if (!this.isControlPointMousedown) return
|
||
e.stopPropagation()
|
||
e.preventDefault()
|
||
let { pos, startPoint, endPoint, targetIndex } =
|
||
this.controlPointMousemoveState
|
||
let [, , , node] = this.activeLine
|
||
let offsetList = []
|
||
let associativeLineTargetControlOffsets =
|
||
node.nodeData.data.associativeLineTargetControlOffsets
|
||
if (!associativeLineTargetControlOffsets) {
|
||
// 兼容0.4.5版本,没有associativeLineTargetControlOffsets的情况
|
||
offsetList[targetIndex] = getDefaultControlPointOffsets(
|
||
startPoint,
|
||
endPoint
|
||
)
|
||
} else {
|
||
offsetList = associativeLineTargetControlOffsets
|
||
}
|
||
let offset1 = null
|
||
let offset2 = null
|
||
if (this.mousedownControlPointKey === 'controlPoint1') {
|
||
// 更新控制点1数据
|
||
offset1 = {
|
||
x: pos.x - startPoint.x,
|
||
y: pos.y - startPoint.y
|
||
}
|
||
offset2 = offsetList[targetIndex][1]
|
||
} else {
|
||
// 更新控制点2数据
|
||
offset1 = offsetList[targetIndex][0]
|
||
offset2 = {
|
||
x: pos.x - endPoint.x,
|
||
y: pos.y - endPoint.y
|
||
}
|
||
}
|
||
offsetList[targetIndex] = [offset1, offset2]
|
||
this.mindMap.execCommand('SET_NODE_DATA', node, {
|
||
associativeLineTargetControlOffsets: offsetList
|
||
})
|
||
// 这里要加个setTimeout0是因为draw_click事件比mouseup事件触发的晚,所以重置isControlPointMousedown需要等draw_click事件触发完以后
|
||
setTimeout(() => {
|
||
this.resetControlPoint()
|
||
}, 0)
|
||
}
|
||
|
||
// 复位控制点移动
|
||
function resetControlPoint() {
|
||
this.isControlPointMousedown = false
|
||
this.mousedownControlPointKey = ''
|
||
this.controlPointMousemoveState = {
|
||
pos: null,
|
||
startPoint: null,
|
||
endPoint: null,
|
||
targetIndex: ''
|
||
}
|
||
}
|
||
|
||
// 渲染控制点
|
||
function renderControls(startPoint, endPoint, point1, point2) {
|
||
if (!this.controlLine1) {
|
||
this.createControlNodes()
|
||
}
|
||
let radius = this.controlPointDiameter / 2
|
||
// 控制点和起终点的连线
|
||
this.controlLine1.plot(startPoint.x, startPoint.y, point1.x, point1.y)
|
||
this.controlLine2.plot(endPoint.x, endPoint.y, point2.x, point2.y)
|
||
// 控制点
|
||
this.controlPoint1.x(point1.x - radius).y(point1.y - radius)
|
||
this.controlPoint2.x(point2.x - radius).y(point2.y - radius)
|
||
}
|
||
|
||
// 删除控制点
|
||
function removeControls() {
|
||
if (!this.controlLine1) return
|
||
;[
|
||
this.controlLine1,
|
||
this.controlLine2,
|
||
this.controlPoint1,
|
||
this.controlPoint2
|
||
].forEach(item => {
|
||
item.remove()
|
||
})
|
||
this.controlLine1 = null
|
||
this.controlLine2 = null
|
||
this.controlPoint1 = null
|
||
this.controlPoint2 = null
|
||
}
|
||
|
||
// 隐藏控制点
|
||
function hideControls() {
|
||
if (!this.controlLine1) return
|
||
;[
|
||
this.controlLine1,
|
||
this.controlLine2,
|
||
this.controlPoint1,
|
||
this.controlPoint2
|
||
].forEach(item => {
|
||
item.hide()
|
||
})
|
||
}
|
||
|
||
// 显示控制点
|
||
function showControls() {
|
||
if (!this.controlLine1) return
|
||
;[
|
||
this.controlLine1,
|
||
this.controlLine2,
|
||
this.controlPoint1,
|
||
this.controlPoint2
|
||
].forEach(item => {
|
||
item.show()
|
||
})
|
||
}
|
||
|
||
export default {
|
||
createControlNodes,
|
||
createOneControlNode,
|
||
onControlPointMousedown,
|
||
onControlPointMousemove,
|
||
onControlPointMouseup,
|
||
resetControlPoint,
|
||
renderControls,
|
||
removeControls,
|
||
hideControls,
|
||
showControls
|
||
}
|