mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-17 22:08:25 +08:00
Feat:新增鼠标移入概要时高亮其所属的节点
This commit is contained in:
@@ -224,5 +224,10 @@ export const defaultOpt = {
|
||||
// 多少时间内只允许添加一次历史记录,避免添加没有必要的中间状态,单位:ms
|
||||
addHistoryTime: 100,
|
||||
// 是否禁止拖动画布
|
||||
isDisableDrag: false
|
||||
isDisableDrag: false,
|
||||
// 鼠标移入概要高亮所属节点时的高亮框样式
|
||||
highlightNodeBoxStyle: {
|
||||
stroke: 'rgb(94, 200, 248)',
|
||||
fill: 'transparent'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
import { shapeList } from './node/Shape'
|
||||
import { lineStyleProps } from '../../themes/default'
|
||||
import { CONSTANTS, ERROR_TYPES } from '../../constants/constant'
|
||||
import { Polygon } from '@svgdotjs/svg.js'
|
||||
|
||||
// 布局列表
|
||||
const layouts = {
|
||||
@@ -84,6 +85,8 @@ class Render {
|
||||
this.beingPasteText = ''
|
||||
this.beingPasteImgSize = 0
|
||||
this.currentBeingPasteType = ''
|
||||
// 节点高亮框
|
||||
this.highlightBoxNode = null
|
||||
// 布局
|
||||
this.setLayout()
|
||||
// 绑定事件
|
||||
@@ -1065,6 +1068,7 @@ class Render {
|
||||
this.mindMap.execCommand('SET_NODE_DATA', targetNode, {
|
||||
generalization
|
||||
})
|
||||
this.closeHighlightNode()
|
||||
}
|
||||
|
||||
// 仅删除当前节点
|
||||
@@ -1408,7 +1412,9 @@ class Render {
|
||||
}
|
||||
const nodeList = this.activeNodeList.filter(node => {
|
||||
return (
|
||||
!node.isRoot && !node.isGeneralization && !node.checkHasSelfGeneralization()
|
||||
!node.isRoot &&
|
||||
!node.isGeneralization &&
|
||||
!node.checkHasSelfGeneralization()
|
||||
)
|
||||
})
|
||||
const list = parseAddGeneralizationNodeList(nodeList)
|
||||
@@ -1458,6 +1464,7 @@ class Render {
|
||||
})
|
||||
})
|
||||
this.mindMap.render()
|
||||
this.closeHighlightNode()
|
||||
}
|
||||
|
||||
// 设置节点自定义位置
|
||||
@@ -1599,6 +1606,60 @@ class Render {
|
||||
emitNodeActiveEvent() {
|
||||
this.mindMap.emit('node_active', null, [...this.activeNodeList])
|
||||
}
|
||||
|
||||
// 高亮节点或子节点
|
||||
highlightNode(node, range) {
|
||||
const { highlightNodeBoxStyle = {} } = this.mindMap.opt
|
||||
if (!this.highlightBoxNode) {
|
||||
this.highlightBoxNode = new Polygon()
|
||||
.stroke({
|
||||
color: highlightNodeBoxStyle.stroke || 'transparent'
|
||||
})
|
||||
.fill({
|
||||
color: highlightNodeBoxStyle.fill || 'transparent'
|
||||
})
|
||||
}
|
||||
let minx = Infinity,
|
||||
miny = Infinity,
|
||||
maxx = -Infinity,
|
||||
maxy = -Infinity
|
||||
if (range) {
|
||||
const children = node.children.slice(range[0], range[1] + 1)
|
||||
children.forEach(child => {
|
||||
if (child.left < minx) {
|
||||
minx = child.left
|
||||
}
|
||||
if (child.top < miny) {
|
||||
miny = child.top
|
||||
}
|
||||
const right = child.left + child.width
|
||||
const bottom = child.top + child.height
|
||||
if (right > maxx) {
|
||||
maxx = right
|
||||
}
|
||||
if (bottom > maxy) {
|
||||
maxy = bottom
|
||||
}
|
||||
})
|
||||
} else {
|
||||
minx = node.left
|
||||
miny = node.top
|
||||
maxx = node.left + node.width
|
||||
maxy = node.top + node.height
|
||||
}
|
||||
this.highlightBoxNode.plot([
|
||||
[minx, miny],
|
||||
[maxx, miny],
|
||||
[maxx, maxy],
|
||||
[minx, maxy]
|
||||
])
|
||||
this.mindMap.otherDraw.add(this.highlightBoxNode)
|
||||
}
|
||||
|
||||
// 关闭高亮
|
||||
closeHighlightNode() {
|
||||
this.highlightBoxNode.remove()
|
||||
}
|
||||
}
|
||||
|
||||
export default Render
|
||||
|
||||
@@ -458,12 +458,18 @@ class Node {
|
||||
this._isMouseenter = true
|
||||
// 显示展开收起按钮
|
||||
this.showExpandBtn()
|
||||
if (this.isGeneralization) {
|
||||
this.handleGeneralizationMouseenter()
|
||||
}
|
||||
this.mindMap.emit('node_mouseenter', this, e)
|
||||
})
|
||||
this.group.on('mouseleave', e => {
|
||||
if (!this._isMouseenter) return
|
||||
this._isMouseenter = false
|
||||
this.hideExpandBtn()
|
||||
if (this.isGeneralization) {
|
||||
this.handleGeneralizationMouseleave()
|
||||
}
|
||||
this.mindMap.emit('node_mouseleave', this, e)
|
||||
})
|
||||
// 双击事件
|
||||
@@ -1002,10 +1008,29 @@ class Node {
|
||||
return this.style.hasCustomStyle()
|
||||
}
|
||||
|
||||
// 获取节点的尺寸和位置信息,位置信息相对于页面
|
||||
// 获取节点的尺寸和位置信息,宽高是应用了缩放效果后的实际宽高,位置是相对于浏览器窗口左上角的位置
|
||||
getRect() {
|
||||
return this.group.rbox()
|
||||
}
|
||||
|
||||
// 获取节点的尺寸和位置信息,宽高是应用了缩放效果后的实际宽高,位置信息相对于画布
|
||||
getRectInSvg() {
|
||||
let { scaleX, scaleY, translateX, translateY } =
|
||||
this.mindMap.draw.transform()
|
||||
let { left, top, width, height } = this
|
||||
let right = (left + width) * scaleX + translateX
|
||||
let bottom = (top + height) * scaleY + translateY
|
||||
left = left * scaleX + translateX
|
||||
top = top * scaleY + translateY
|
||||
return {
|
||||
left,
|
||||
right,
|
||||
top,
|
||||
bottom,
|
||||
width: width * scaleX,
|
||||
height: height * scaleY
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Node
|
||||
|
||||
@@ -177,6 +177,29 @@ function setGeneralizationOpacity(val) {
|
||||
})
|
||||
}
|
||||
|
||||
// 处理概要节点鼠标移入事件
|
||||
function handleGeneralizationMouseenter() {
|
||||
const belongNode = this.generalizationBelongNode
|
||||
const list = belongNode.formatGetGeneralization()
|
||||
const index = belongNode.getGeneralizationNodeIndex(this)
|
||||
const generalizationData = list[index]
|
||||
// 区间概要,框子节点
|
||||
if (
|
||||
Array.isArray(generalizationData.range) &&
|
||||
generalizationData.range.length > 0
|
||||
) {
|
||||
this.mindMap.renderer.highlightNode(belongNode, generalizationData.range)
|
||||
} else {
|
||||
// 否则框自己
|
||||
this.mindMap.renderer.highlightNode(belongNode)
|
||||
}
|
||||
}
|
||||
|
||||
// 处理概要节点鼠标移出事件
|
||||
function handleGeneralizationMouseleave() {
|
||||
this.mindMap.renderer.closeHighlightNode()
|
||||
}
|
||||
|
||||
export default {
|
||||
formatGetGeneralization,
|
||||
checkHasGeneralization,
|
||||
@@ -189,5 +212,7 @@ export default {
|
||||
removeGeneralization,
|
||||
hideGeneralization,
|
||||
showGeneralization,
|
||||
setGeneralizationOpacity
|
||||
setGeneralizationOpacity,
|
||||
handleGeneralizationMouseenter,
|
||||
handleGeneralizationMouseleave
|
||||
}
|
||||
|
||||
@@ -154,15 +154,12 @@ export const handleNodeImageToXmind = async (
|
||||
try {
|
||||
let imgName = ''
|
||||
let imgData = node.data.image
|
||||
console.log(1, imgData)
|
||||
// base64之外的其他图片要先转换成data:url
|
||||
if (!/^data:/.test(node.data.image)) {
|
||||
imgData = await imgToDataUrl(node.data.image)
|
||||
console.log(2, imgData)
|
||||
}
|
||||
// 从data:url中解析出图片类型和ase64
|
||||
let dataUrlRes = parseDataUrl(imgData)
|
||||
console.log(3, dataUrlRes)
|
||||
imgName = 'image_' + imageList.length + '.' + dataUrlRes.type
|
||||
imageList.push({
|
||||
name: imgName,
|
||||
|
||||
@@ -408,6 +408,11 @@ export default {
|
||||
// console.log('销毁')
|
||||
// this.mindMap.destroy()
|
||||
// }, 10000)
|
||||
// 测试
|
||||
// setTimeout(() => {
|
||||
// console.log(this.mindMap.renderer.root.getRect())
|
||||
// console.log(this.mindMap.renderer.root.getRectInSvg())
|
||||
// }, 5000);
|
||||
},
|
||||
|
||||
// url中是否存在要打开的文件
|
||||
|
||||
Reference in New Issue
Block a user