优化部分插件代码,增加解绑事件的逻辑

This commit is contained in:
街角小林
2023-12-21 17:06:40 +08:00
parent 33a2e20ee2
commit 4d2665c98b
6 changed files with 314 additions and 147 deletions

View File

@@ -59,43 +59,70 @@ class AssociativeLine {
// 监听事件
bindEvent() {
// 节点树渲染完毕后渲染连接线
this.renderAllLines = this.renderAllLines.bind(this)
this.onDrawClick = this.onDrawClick.bind(this)
this.onNodeClick = this.onNodeClick.bind(this)
this.removeLine = this.removeLine.bind(this)
this.addLine = this.addLine.bind(this)
this.onMousemove = this.onMousemove.bind(this)
this.onNodeDragging = this.onNodeDragging.bind(this)
this.onNodeDragend = this.onNodeDragend.bind(this)
this.onControlPointMouseup = this.onControlPointMouseup.bind(this)
// 节点树渲染完毕后渲染连接线
this.mindMap.on('node_tree_render_end', this.renderAllLines)
// 状态改变后重新渲染连接线
this.mindMap.on('data_change', this.renderAllLines)
// 监听画布和节点点击事件,用于清除当前激活的连接线
this.mindMap.on('draw_click', () => {
if (this.isControlPointMousedown) {
return
}
this.clearActiveLine()
})
this.mindMap.on('node_click', node => {
if (this.isCreatingLine) {
this.completeCreateLine(node)
} else {
this.clearActiveLine()
}
})
this.mindMap.on('draw_click', this.onDrawClick)
this.mindMap.on('node_click', this.onNodeClick)
// 注册删除快捷键
this.mindMap.keyCommand.addShortcut(
'Del|Backspace',
this.removeLine.bind(this)
)
this.mindMap.keyCommand.addShortcut('Del|Backspace', this.removeLine)
// 注册添加连接线的命令
this.mindMap.command.add('ADD_ASSOCIATIVE_LINE', this.addLine.bind(this))
this.mindMap.command.add('ADD_ASSOCIATIVE_LINE', this.addLine)
// 监听鼠标移动事件
this.mindMap.on('mousemove', this.onMousemove.bind(this))
this.mindMap.on('mousemove', this.onMousemove)
// 节点拖拽事件
this.mindMap.on('node_dragging', this.onNodeDragging.bind(this))
this.mindMap.on('node_dragend', this.onNodeDragend.bind(this))
this.mindMap.on('node_dragging', this.onNodeDragging)
this.mindMap.on('node_dragend', this.onNodeDragend)
// 拖拽控制点
this.mindMap.on('mouseup', this.onControlPointMouseup.bind(this))
this.mindMap.on('mouseup', this.onControlPointMouseup)
// 缩放事件
this.mindMap.on('scale', this.onScale)
}
// 解绑事件
unBindEvent() {
this.mindMap.off('node_tree_render_end', this.renderAllLines)
this.mindMap.off('data_change', this.renderAllLines)
this.mindMap.off('draw_click', this.onDrawClick)
this.mindMap.off('node_click', this.onNodeClick)
this.mindMap.keyCommand.removeShortcut('Del|Backspace', this.removeLine)
this.mindMap.command.remove('ADD_ASSOCIATIVE_LINE', this.addLine)
this.mindMap.off('mousemove', this.onMousemove)
this.mindMap.off('node_dragging', this.onNodeDragging)
this.mindMap.off('node_dragend', this.onNodeDragend)
this.mindMap.off('mouseup', this.onControlPointMouseup)
this.mindMap.off('scale', this.onScale)
}
// 画布点击事件
onDrawClick() {
if (this.isControlPointMousedown) {
return
}
this.clearActiveLine()
}
// 节点点击事件
onNodeClick(node) {
if (this.isCreatingLine) {
this.completeCreateLine(node)
} else {
this.clearActiveLine()
}
}
// 创建箭头
createMarker() {
return this.associativeLineDraw.marker(20, 20, add => {
@@ -544,6 +571,16 @@ class AssociativeLine {
this.associativeLineDraw.back() // 最底层
this.associativeLineDraw.forward() // 连线层上面
}
// 插件被移除前做的事情
beforePluginRemove() {
this.unBindEvent()
}
// 插件被卸载前做的事情
beforePluginDestroy() {
this.unBindEvent()
}
}
AssociativeLine.instanceName = 'associativeLine'

View File

@@ -55,51 +55,68 @@ class Drag extends Base {
// 绑定事件
bindEvent() {
this.checkOverlapNode = throttle(this.checkOverlapNode, 300, this)
this.mindMap.on('node_mousedown', (node, e) => {
// 只读模式、不是鼠标左键按下、按下的是概要节点或根节点直接返回
if (
this.mindMap.opt.readonly ||
e.which !== 1 ||
node.isGeneralization ||
node.isRoot
) {
return
}
e.preventDefault()
this.isMousedown = true
// 记录鼠标按下时的节点
this.mousedownNode = node
// 记录鼠标按下的坐标
const { x, y } = this.mindMap.toPos(e.clientX, e.clientY)
this.mouseDownX = x
this.mouseDownY = y
})
this.mindMap.on('mousemove', e => {
if (this.mindMap.opt.readonly || !this.isMousedown) {
return
}
e.preventDefault()
const { x, y } = this.mindMap.toPos(e.clientX, e.clientY)
this.mouseMoveX = x
this.mouseMoveY = y
// 还没开始移动时鼠标位移过小不认为是拖拽
if (
!this.isDragging &&
Math.abs(x - this.mouseDownX) <= this.checkDragOffset &&
Math.abs(y - this.mouseDownY) <= this.checkDragOffset
) {
return
}
this.mindMap.emit('node_dragging')
this.handleStartMove()
this.onMove(x, y, e)
})
this.onNodeMousedown = this.onNodeMousedown.bind(this)
this.onMousemove = this.onMousemove.bind(this)
this.onMouseup = this.onMouseup.bind(this)
this.checkOverlapNode = throttle(this.checkOverlapNode, 300, this)
this.mindMap.on('node_mousedown', this.onNodeMousedown)
this.mindMap.on('mousemove', this.onMousemove)
this.mindMap.on('node_mouseup', this.onMouseup)
this.mindMap.on('mouseup', this.onMouseup)
}
// 解绑事件
unBindEvent() {
this.mindMap.off('node_mousedown', this.onNodeMousedown)
this.mindMap.off('mousemove', this.onMousemove)
this.mindMap.off('node_mouseup', this.onMouseup)
this.mindMap.off('mouseup', this.onMouseup)
}
// 节点鼠标按下事件
onNodeMousedown(node, e) {
// 只读模式、不是鼠标左键按下、按下的是概要节点或根节点直接返回
if (
this.mindMap.opt.readonly ||
e.which !== 1 ||
node.isGeneralization ||
node.isRoot
) {
return
}
e.preventDefault()
this.isMousedown = true
// 记录鼠标按下时的节点
this.mousedownNode = node
// 记录鼠标按下的坐标
const { x, y } = this.mindMap.toPos(e.clientX, e.clientY)
this.mouseDownX = x
this.mouseDownY = y
}
// 鼠标移动事件
onMousemove(e) {
if (this.mindMap.opt.readonly || !this.isMousedown) {
return
}
e.preventDefault()
const { x, y } = this.mindMap.toPos(e.clientX, e.clientY)
this.mouseMoveX = x
this.mouseMoveY = y
// 还没开始移动时鼠标位移过小不认为是拖拽
if (
!this.isDragging &&
Math.abs(x - this.mouseDownX) <= this.checkDragOffset &&
Math.abs(y - this.mouseDownY) <= this.checkDragOffset
) {
return
}
this.mindMap.emit('node_dragging')
this.handleStartMove()
this.onMove(x, y, e)
}
// 鼠标松开事件
onMouseup(e) {
if (!this.isMousedown) {
@@ -685,6 +702,16 @@ class Drag extends Base {
return item.uid === node.uid || item.isAncestor(node)
})
}
// 插件被移除前做的事情
beforePluginRemove() {
this.unBindEvent()
}
// 插件被卸载前做的事情
beforePluginDestroy() {
this.unBindEvent()
}
}
Drag.instanceName = 'drag'

View File

@@ -7,19 +7,61 @@ class KeyboardNavigation {
constructor(opt) {
this.opt = opt
this.mindMap = opt.mindMap
this.onKeyup = this.onKeyup.bind(this)
this.mindMap.keyCommand.addShortcut(CONSTANTS.KEY_DIR.LEFT, () => {
this.onKeyup(CONSTANTS.KEY_DIR.LEFT)
})
this.mindMap.keyCommand.addShortcut(CONSTANTS.KEY_DIR.UP, () => {
this.onKeyup(CONSTANTS.KEY_DIR.UP)
})
this.mindMap.keyCommand.addShortcut(CONSTANTS.KEY_DIR.RIGHT, () => {
this.onKeyup(CONSTANTS.KEY_DIR.RIGHT)
})
this.mindMap.keyCommand.addShortcut(CONSTANTS.KEY_DIR.DOWN, () => {
this.onKeyup(CONSTANTS.KEY_DIR.DOWN)
})
this.addShortcut()
}
addShortcut() {
this.onLeftKeyUp = this.onLeftKeyUp.bind(this)
this.onUpKeyUp = this.onUpKeyUp.bind(this)
this.onRightKeyUp = this.onRightKeyUp.bind(this)
this.onDownKeyUp = this.onDownKeyUp.bind(this)
this.mindMap.keyCommand.addShortcut(
CONSTANTS.KEY_DIR.LEFT,
this.onLeftKeyUp
)
this.mindMap.keyCommand.addShortcut(CONSTANTS.KEY_DIR.UP, this.onUpKeyUp)
this.mindMap.keyCommand.addShortcut(
CONSTANTS.KEY_DIR.RIGHT,
this.onRightKeyUp
)
this.mindMap.keyCommand.addShortcut(
CONSTANTS.KEY_DIR.DOWN,
this.onDownKeyUp
)
}
removeShortcut() {
this.mindMap.keyCommand.removeShortcut(
CONSTANTS.KEY_DIR.LEFT,
this.onLeftKeyUp
)
this.mindMap.keyCommand.removeShortcut(CONSTANTS.KEY_DIR.UP, this.onUpKeyUp)
this.mindMap.keyCommand.removeShortcut(
CONSTANTS.KEY_DIR.RIGHT,
this.onRightKeyUp
)
this.mindMap.keyCommand.removeShortcut(
CONSTANTS.KEY_DIR.DOWN,
this.onDownKeyUp
)
}
onLeftKeyUp() {
this.onKeyup(CONSTANTS.KEY_DIR.LEFT)
}
onUpKeyUp() {
this.onKeyup(CONSTANTS.KEY_DIR.UP)
}
onRightKeyUp() {
this.onKeyup(CONSTANTS.KEY_DIR.RIGHT)
}
onDownKeyUp() {
this.onKeyup(CONSTANTS.KEY_DIR.DOWN)
}
// 处理按键事件
@@ -228,6 +270,16 @@ class KeyboardNavigation {
y: (top + bottom) / 2
}
}
// 插件被移除前做的事情
beforePluginRemove() {
this.removeShortcut()
}
// 插件被卸载前做的事情
beforePluginDestroy() {
this.removeShortcut()
}
}
KeyboardNavigation.instanceName = 'keyboardNavigation'

View File

@@ -261,6 +261,11 @@ class Scrollbar {
this.updateMindMapView(type, offset)
}
// 插件被移除前做的事情
beforePluginRemove() {
this.unBindEvent()
}
// 插件被卸载前做的事情
beforePluginDestroy() {
this.unBindEvent()

View File

@@ -22,10 +22,19 @@ class Search {
this.notResetSearchText = false
// 是否自动跳转下一个匹配节点
this.isJumpNext = false
this.bindEvent()
}
bindEvent() {
this.onDataChange = this.onDataChange.bind(this)
this.mindMap.on('data_change', this.onDataChange)
}
unBindEvent() {
this.mindMap.off('data_change', this.onDataChange)
}
// 节点数据改变了,需要重新搜索
onDataChange() {
if (this.isJumpNext) {
@@ -177,6 +186,16 @@ class Search {
total: this.matchNodeList.length
})
}
// 插件被移除前做的事情
beforePluginRemove() {
this.unBindEvent()
}
// 插件被卸载前做的事情
beforePluginDestroy() {
this.unBindEvent()
}
}
Search.instanceName = 'search'

View File

@@ -18,82 +18,99 @@ class Select {
// 绑定事件
bindEvent() {
this.checkInNodes = throttle(this.checkInNodes, 300, this)
this.mindMap.on('mousedown', e => {
if (this.mindMap.opt.readonly) {
return
}
let { useLeftKeySelectionRightKeyDrag } = this.mindMap.opt
if (
!e.ctrlKey &&
(useLeftKeySelectionRightKeyDrag ? e.which !== 1 : e.which !== 3)
) {
return
}
e.preventDefault()
this.isMousedown = true
this.cacheActiveList = [...this.mindMap.renderer.activeNodeList]
let { x, y } = this.mindMap.toPos(e.clientX, e.clientY)
this.mouseDownX = x
this.mouseDownY = y
this.createRect(x, y)
})
this.mindMap.on('mousemove', e => {
if (this.mindMap.opt.readonly) {
return
}
if (!this.isMousedown) {
return
}
let { x, y } = this.mindMap.toPos(e.clientX, e.clientY)
this.mouseMoveX = x
this.mouseMoveY = y
if (
Math.abs(x - this.mouseDownX) <= 10 &&
Math.abs(y - this.mouseDownY) <= 10
) {
return
}
this.clearAutoMoveTimer()
this.onMove(
e.clientX,
e.clientY,
() => {
this.isSelecting = true
// 绘制矩形
this.rect.plot([
[this.mouseDownX, this.mouseDownY],
[this.mouseMoveX, this.mouseDownY],
[this.mouseMoveX, this.mouseMoveY],
[this.mouseDownX, this.mouseMoveY]
])
this.checkInNodes()
},
(dir, step) => {
switch (dir) {
case 'left':
this.mouseDownX += step
break
case 'top':
this.mouseDownY += step
break
case 'right':
this.mouseDownX -= step
break
case 'bottom':
this.mouseDownY -= step
break
default:
break
}
}
)
})
this.onMousedown = this.onMousedown.bind(this)
this.onMousemove = this.onMousemove.bind(this)
this.onMouseup = this.onMouseup.bind(this)
this.checkInNodes = throttle(this.checkInNodes, 300, this)
this.mindMap.on('mousedown', this.onMousedown)
this.mindMap.on('mousemove', this.onMousemove)
this.mindMap.on('mouseup', this.onMouseup)
this.mindMap.on('node_mouseup', this.onMouseup)
}
// 解绑事件
unBindEvent() {
this.mindMap.off('mousedown', this.onMousedown)
this.mindMap.off('mousemove', this.onMousemove)
this.mindMap.off('mouseup', this.onMouseup)
this.mindMap.off('node_mouseup', this.onMouseup)
}
// 鼠标按下
onMousedown(e) {
if (this.mindMap.opt.readonly) {
return
}
let { useLeftKeySelectionRightKeyDrag } = this.mindMap.opt
if (
!e.ctrlKey &&
(useLeftKeySelectionRightKeyDrag ? e.which !== 1 : e.which !== 3)
) {
return
}
e.preventDefault()
this.isMousedown = true
this.cacheActiveList = [...this.mindMap.renderer.activeNodeList]
let { x, y } = this.mindMap.toPos(e.clientX, e.clientY)
this.mouseDownX = x
this.mouseDownY = y
this.createRect(x, y)
}
// 鼠标移动
onMousemove(e) {
if (this.mindMap.opt.readonly) {
return
}
if (!this.isMousedown) {
return
}
let { x, y } = this.mindMap.toPos(e.clientX, e.clientY)
this.mouseMoveX = x
this.mouseMoveY = y
if (
Math.abs(x - this.mouseDownX) <= 10 &&
Math.abs(y - this.mouseDownY) <= 10
) {
return
}
this.clearAutoMoveTimer()
this.onMove(
e.clientX,
e.clientY,
() => {
this.isSelecting = true
// 绘制矩形
this.rect.plot([
[this.mouseDownX, this.mouseDownY],
[this.mouseMoveX, this.mouseDownY],
[this.mouseMoveX, this.mouseMoveY],
[this.mouseDownX, this.mouseMoveY]
])
this.checkInNodes()
},
(dir, step) => {
switch (dir) {
case 'left':
this.mouseDownX += step
break
case 'top':
this.mouseDownY += step
break
case 'right':
this.mouseDownX -= step
break
case 'bottom':
this.mouseDownY -= step
break
default:
break
}
}
)
}
// 结束框选
onMouseup() {
if (this.mindMap.opt.readonly) {
@@ -233,6 +250,16 @@ class Select {
hasSelectRange() {
return this.isSelecting
}
// 插件被移除前做的事情
beforePluginRemove() {
this.unBindEvent()
}
// 插件被卸载前做的事情
beforePluginDestroy() {
this.unBindEvent()
}
}
Select.instanceName = 'select'