Feat:拖拽节点时鼠标移到画布边缘时画布自动移动

This commit is contained in:
wanglin2 2023-09-14 18:24:10 +08:00
parent e53d1b1948
commit 21564445d6
4 changed files with 80 additions and 32 deletions

View File

@ -185,4 +185,6 @@ export const defaultOpt = {
selectTextOnEnterEditText: false, selectTextOnEnterEditText: false,
// 删除节点后激活相邻节点 // 删除节点后激活相邻节点
deleteNodeActive: true, deleteNodeActive: true,
// 拖拽节点时鼠标移动到画布边缘是否开启画布自动移动
autoMoveWhenMouseInEdgeOnDrag: true
} }

View File

@ -841,8 +841,9 @@ class Render {
} else { } else {
// 如果只选中了一个节点,删除后激活其兄弟节点或者父节点 // 如果只选中了一个节点,删除后激活其兄弟节点或者父节点
if ( if (
this.activeNodeList.length === 1 && this.activeNodeList.length === 1 &&
!this.activeNodeList[0].isGeneralization&&this.mindMap.opt.deleteNodeActive !this.activeNodeList[0].isGeneralization &&
this.mindMap.opt.deleteNodeActive
) { ) {
const node = this.activeNodeList[0] const node = this.activeNodeList[0]
const broList = node.parent.children const broList = node.parent.children
@ -1123,7 +1124,13 @@ class Render {
// 设置节点图片 // 设置节点图片
setNodeImage(node, data) { setNodeImage(node, data) {
const { url, title, width, height, custom = false } = data || { url: '', title: '', width: 0, height: 0, custom: false } const {
url,
title,
width,
height,
custom = false
} = data || { url: '', title: '', width: 0, height: 0, custom: false }
this.setNodeDataRender(node, { this.setNodeDataRender(node, {
image: url, image: url,
imageTitle: title || '', imageTitle: title || '',

View File

@ -186,6 +186,8 @@ class Drag extends Base {
if (!this.isMousedown) { if (!this.isMousedown) {
return return
} }
let originX = x
let originY = y
this.createCloneNode() this.createCloneNode()
let { scaleX, scaleY, translateX, translateY } = this.drawTransform let { scaleX, scaleY, translateX, translateY } = this.drawTransform
this.cloneNodeLeft = x - this.offsetX this.cloneNodeLeft = x - this.offsetX
@ -205,6 +207,12 @@ class Drag extends Base {
) )
) )
this.checkOverlapNode() this.checkOverlapNode()
// 如果注册了多选节点插件,那么复用它的边缘自动移动画布功能
if (this.mindMap.opt.autoMoveWhenMouseInEdgeOnDrag && this.mindMap.select) {
this.drawTransform = this.mindMap.draw.transform()
this.mindMap.select.clearAutoMoveTimer()
this.mindMap.select.onMove(originX, originY)
}
} }
// 检测重叠节点 // 检测重叠节点

View File

@ -54,8 +54,40 @@ class Select {
) { ) {
return return
} }
clearTimeout(this.autoMoveTimer) this.clearAutoMoveTimer()
this.onMove(e.clientX, e.clientY) 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.mindMap.on('mouseup', () => { this.mindMap.on('mouseup', () => {
if (this.mindMap.opt.readonly) { if (this.mindMap.opt.readonly) {
@ -78,79 +110,78 @@ class Select {
// 如果激活节点改变了,那么触发事件 // 如果激活节点改变了,那么触发事件
checkTriggerNodeActiveEvent() { checkTriggerNodeActiveEvent() {
let isNumChange = this.cacheActiveList.length !== this.mindMap.renderer.activeNodeList.length let isNumChange =
this.cacheActiveList.length !==
this.mindMap.renderer.activeNodeList.length
let isNodeChange = false let isNodeChange = false
if (!isNumChange) { if (!isNumChange) {
for(let i = 0; i < this.cacheActiveList.length; i++) { for (let i = 0; i < this.cacheActiveList.length; i++) {
let cur = this.cacheActiveList[i] let cur = this.cacheActiveList[i]
if (!this.mindMap.renderer.activeNodeList.find((item) => { if (
return item.nodeData.data.uid === cur.nodeData.data.uid !this.mindMap.renderer.activeNodeList.find(item => {
})){ return item.nodeData.data.uid === cur.nodeData.data.uid
})
) {
isNodeChange = true isNodeChange = true
break break
} }
} }
} }
if (isNumChange || isNodeChange) { if (isNumChange || isNodeChange) {
this.mindMap.emit( this.mindMap.emit('node_active', null, [
'node_active', ...this.mindMap.renderer.activeNodeList
null, ])
[...this.mindMap.renderer.activeNodeList]
)
} }
} }
// 鼠标移动事件 // 鼠标移动事件
onMove(x, y) { onMove(x, y, callback = () => {}, handle = () => {}) {
this.isSelecting = true callback()
// 绘制矩形
this.rect.plot([
[this.mouseDownX, this.mouseDownY],
[this.mouseMoveX, this.mouseDownY],
[this.mouseMoveX, this.mouseMoveY],
[this.mouseDownX, this.mouseMoveY]
])
this.checkInNodes()
// 检测边缘移动 // 检测边缘移动
let step = this.mindMap.opt.selectTranslateStep let step = this.mindMap.opt.selectTranslateStep
let limit = this.mindMap.opt.selectTranslateLimit let limit = this.mindMap.opt.selectTranslateLimit
let count = 0 let count = 0
// 左边缘 // 左边缘
if (x <= this.mindMap.elRect.left + limit) { if (x <= this.mindMap.elRect.left + limit) {
this.mouseDownX += step handle('left', step)
this.mindMap.view.translateX(step) this.mindMap.view.translateX(step)
count++ count++
} }
// 右边缘 // 右边缘
if (x >= this.mindMap.elRect.right - limit) { if (x >= this.mindMap.elRect.right - limit) {
this.mouseDownX -= step handle('right', step)
this.mindMap.view.translateX(-step) this.mindMap.view.translateX(-step)
count++ count++
} }
// 上边缘 // 上边缘
if (y <= this.mindMap.elRect.top + limit) { if (y <= this.mindMap.elRect.top + limit) {
this.mouseDownY += step handle('top', step)
this.mindMap.view.translateY(step) this.mindMap.view.translateY(step)
count++ count++
} }
// 下边缘 // 下边缘
if (y >= this.mindMap.elRect.bottom - limit) { if (y >= this.mindMap.elRect.bottom - limit) {
this.mouseDownY -= step handle('bottom', step)
this.mindMap.view.translateY(-step) this.mindMap.view.translateY(-step)
count++ count++
} }
if (count > 0) { if (count > 0) {
this.startAutoMove(x, y) this.startAutoMove(x, y, callback, handle)
} }
} }
// 开启自动移动 // 开启自动移动
startAutoMove(x, y) { startAutoMove(x, y, callback, handle) {
this.autoMoveTimer = setTimeout(() => { this.autoMoveTimer = setTimeout(() => {
this.onMove(x, y) this.onMove(x, y, callback, handle)
}, 20) }, 20)
} }
// 清除自动移动定时器
clearAutoMoveTimer() {
clearTimeout(this.autoMoveTimer)
}
// 创建矩形 // 创建矩形
createRect(x, y) { createRect(x, y) {
this.rect = this.mindMap.svg this.rect = this.mindMap.svg