From 4d2665c98b4f4185d7f8fd327e5bddae2745ca9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A1=97=E8=A7=92=E5=B0=8F=E6=9E=97?= <1013335014@qq.com> Date: Thu, 21 Dec 2023 17:06:40 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=83=A8=E5=88=86=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E4=BB=A3=E7=A0=81=EF=BC=8C=E5=A2=9E=E5=8A=A0=E8=A7=A3?= =?UTF-8?q?=E7=BB=91=E4=BA=8B=E4=BB=B6=E7=9A=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/plugins/AssociativeLine.js | 83 ++++++--- simple-mind-map/src/plugins/Drag.js | 107 ++++++----- .../src/plugins/KeyboardNavigation.js | 78 ++++++-- simple-mind-map/src/plugins/Scrollbar.js | 5 + simple-mind-map/src/plugins/Search.js | 19 ++ simple-mind-map/src/plugins/Select.js | 169 ++++++++++-------- 6 files changed, 314 insertions(+), 147 deletions(-) diff --git a/simple-mind-map/src/plugins/AssociativeLine.js b/simple-mind-map/src/plugins/AssociativeLine.js index bb6ffa13..6d2c461d 100644 --- a/simple-mind-map/src/plugins/AssociativeLine.js +++ b/simple-mind-map/src/plugins/AssociativeLine.js @@ -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' diff --git a/simple-mind-map/src/plugins/Drag.js b/simple-mind-map/src/plugins/Drag.js index f633c0b4..18ad54b4 100644 --- a/simple-mind-map/src/plugins/Drag.js +++ b/simple-mind-map/src/plugins/Drag.js @@ -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' diff --git a/simple-mind-map/src/plugins/KeyboardNavigation.js b/simple-mind-map/src/plugins/KeyboardNavigation.js index f3eb694e..972e25e2 100644 --- a/simple-mind-map/src/plugins/KeyboardNavigation.js +++ b/simple-mind-map/src/plugins/KeyboardNavigation.js @@ -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' diff --git a/simple-mind-map/src/plugins/Scrollbar.js b/simple-mind-map/src/plugins/Scrollbar.js index 9f97d777..b2ba6dcb 100644 --- a/simple-mind-map/src/plugins/Scrollbar.js +++ b/simple-mind-map/src/plugins/Scrollbar.js @@ -261,6 +261,11 @@ class Scrollbar { this.updateMindMapView(type, offset) } + // 插件被移除前做的事情 + beforePluginRemove() { + this.unBindEvent() + } + // 插件被卸载前做的事情 beforePluginDestroy() { this.unBindEvent() diff --git a/simple-mind-map/src/plugins/Search.js b/simple-mind-map/src/plugins/Search.js index 5a21b1f5..64c763dd 100644 --- a/simple-mind-map/src/plugins/Search.js +++ b/simple-mind-map/src/plugins/Search.js @@ -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' diff --git a/simple-mind-map/src/plugins/Select.js b/simple-mind-map/src/plugins/Select.js index f3a93aa3..b66a9d78 100644 --- a/simple-mind-map/src/plugins/Select.js +++ b/simple-mind-map/src/plugins/Select.js @@ -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'