diff --git a/README.md b/README.md index c1dc4aab..3fc5f8b4 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ npm run build # 安装 -> 当前仓库版本:0.2.16,当前npm版本:0.2.16 +> 当前仓库版本:0.2.18,当前npm版本:0.2.18 ```bash npm i simple-mind-map diff --git a/simple-mind-map/package.json b/simple-mind-map/package.json index 2ef2d070..334d25ad 100644 --- a/simple-mind-map/package.json +++ b/simple-mind-map/package.json @@ -1,6 +1,6 @@ { "name": "simple-mind-map", - "version": "0.2.17", + "version": "0.2.18", "description": "一个简单的web在线思维导图", "authors": [ { diff --git a/simple-mind-map/src/KeyboardNavigation.js b/simple-mind-map/src/KeyboardNavigation.js index ab944bf4..03b08639 100644 --- a/simple-mind-map/src/KeyboardNavigation.js +++ b/simple-mind-map/src/KeyboardNavigation.js @@ -48,10 +48,14 @@ export default class KeyboardNavigation { * @Desc: 聚焦到下一个节点 */ focus(dir) { + // 当前聚焦的节点 let currentActiveNode = this.mindMap.renderer.activeNodeList[0] + // 当前聚焦节点的位置信息 let currentActiveNodeRect = this.getNodeRect(currentActiveNode) + // 寻找的下一个聚焦节点 let targetNode = null let targetDis = Infinity + // 保存并维护距离最近的节点 let checkNodeDis = (rect, node) => { let dis = this.getDistance(currentActiveNodeRect, rect) if (dis < targetDis) { @@ -59,33 +63,172 @@ export default class KeyboardNavigation { targetDis = dis } } - bfsWalk(this.mindMap.renderer.root, node => { - let rect = this.getNodeRect(node) - let { left, top, right, bottom } = rect - if (dir === 'Right') { - if (left >= currentActiveNodeRect.right) { - checkNodeDis(rect, node) - } - } else if (dir === 'Left') { - if (right <= currentActiveNodeRect.left) { - checkNodeDis(rect, node) - } - } else if (dir === 'Up') { - if (bottom <= currentActiveNodeRect.top) { - checkNodeDis(rect, node) - } - } else if (dir === 'Down') { - if (top >= currentActiveNodeRect.bottom) { - checkNodeDis(rect, node) - } - } + + // 第一优先级:阴影算法 + this.getFocusNodeByShadowAlgorithm({ + currentActiveNode, + currentActiveNodeRect, + dir, + checkNodeDis }) + + // 第二优先级:区域算法 + if (!targetNode) { + this.getFocusNodeByAreaAlgorithm({ + currentActiveNode, + currentActiveNodeRect, + dir, + checkNodeDis + }) + } + + // 第三优先级:简单算法 + if (!targetNode) { + this.getFocusNodeBySimpleAlgorithm({ + currentActiveNode, + currentActiveNodeRect, + dir, + checkNodeDis + }) + } + + // 找到了则让目标节点聚焦 if (targetNode) { this.mindMap.renderer.moveNodeToCenter(targetNode) targetNode.active() } } + /** + * javascript comment + * @Author: 王林25 + * @Date: 2022-12-12 16:22:54 + * @Desc: 1.简单算法 + */ + getFocusNodeBySimpleAlgorithm({ + currentActiveNode, + currentActiveNodeRect, + dir, + checkNodeDis + }) { + // 遍历节点树 + bfsWalk(this.mindMap.renderer.root, node => { + // 跳过当前聚焦的节点 + if (node === currentActiveNode) return + // 当前遍历到的节点的位置信息 + let rect = this.getNodeRect(node) + let { left, top, right, bottom } = rect + let match = false + // 按下了左方向键 + if (dir === 'Left') { + // 判断节点是否在当前节点的左侧 + match = right <= currentActiveNodeRect.left + // 按下了右方向键 + } else if (dir === 'Right') { + // 判断节点是否在当前节点的右侧 + match = left >= currentActiveNodeRect.right + // 按下了上方向键 + } else if (dir === 'Up') { + // 判断节点是否在当前节点的上面 + match = bottom <= currentActiveNodeRect.top + // 按下了下方向键 + } else if (dir === 'Down') { + // 判断节点是否在当前节点的下面 + match = top >= currentActiveNodeRect.bottom + } + // 符合要求,判断是否是最近的节点 + if (match) { + checkNodeDis(rect, node) + } + }) + } + + /** + * javascript comment + * @Author: 王林25 + * @Date: 2022-12-12 16:24:54 + * @Desc: 2.阴影算法 + */ + getFocusNodeByShadowAlgorithm({ + currentActiveNode, + currentActiveNodeRect, + dir, + checkNodeDis + }) { + bfsWalk(this.mindMap.renderer.root, node => { + if (node === currentActiveNode) return + let rect = this.getNodeRect(node) + let { left, top, right, bottom } = rect + let match = false + if (dir === 'Left') { + match = + left < currentActiveNodeRect.left && + top < currentActiveNodeRect.bottom && + bottom > currentActiveNodeRect.top + } else if (dir === 'Right') { + match = + right > currentActiveNodeRect.right && + top < currentActiveNodeRect.bottom && + bottom > currentActiveNodeRect.top + } else if (dir === 'Up') { + match = + top < currentActiveNodeRect.top && + left < currentActiveNodeRect.right && + right > currentActiveNodeRect.left + } else if (dir === 'Down') { + match = + bottom > currentActiveNodeRect.bottom && + left < currentActiveNodeRect.right && + right > currentActiveNodeRect.left + } + if (match) { + checkNodeDis(rect, node) + } + }) + } + + /** + * javascript comment + * @Author: 王林25 + * @Date: 2022-12-13 16:15:36 + * @Desc: 3.区域算法 + */ + getFocusNodeByAreaAlgorithm({ + currentActiveNode, + currentActiveNodeRect, + dir, + checkNodeDis + }) { + // 当前聚焦节点的中心点 + let cX = (currentActiveNodeRect.right + currentActiveNodeRect.left) / 2 + let cY = (currentActiveNodeRect.bottom + currentActiveNodeRect.top) / 2 + bfsWalk(this.mindMap.renderer.root, node => { + if (node === currentActiveNode) return + let rect = this.getNodeRect(node) + let { left, top, right, bottom } = rect + // 遍历到的节点的中心点 + let ccX = (right + left) / 2 + let ccY = (bottom + top) / 2 + // 节点的中心点坐标和当前聚焦节点的中心点坐标的差值 + let offsetX = ccX - cX + let offsetY = ccY - cY + if (offsetX === 0 && offsetY === 0) return + let match = false + if (dir === 'Left') { + match = offsetX <= 0 && offsetX <= offsetY && offsetX <= -offsetY + } else if (dir === 'Right') { + match = offsetX > 0 && offsetX >= -offsetY && offsetX >= offsetY + } else if (dir === 'Up') { + match = offsetY <= 0 && offsetY < offsetX && offsetY < -offsetX + } else if (dir === 'Down') { + match = offsetY > 0 && -offsetY < offsetX && offsetY > offsetX + } + if (match) { + checkNodeDis(rect, node) + } + }) + } + /** * javascript comment * @Author: 王林25