mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-21 10:27:44 +08:00
Feat:新增将思维导图图形限制在画布内的配置选项
This commit is contained in:
parent
4d9aa1d3c2
commit
3d0b257325
@ -238,5 +238,8 @@ export const defaultOpt = {
|
|||||||
*/
|
*/
|
||||||
createNewNodeBehavior: CONSTANTS.CREATE_NEW_NODE_BEHAVIOR.DEFAULT,
|
createNewNodeBehavior: CONSTANTS.CREATE_NEW_NODE_BEHAVIOR.DEFAULT,
|
||||||
// 当节点图片加载失败时显示的默认图片
|
// 当节点图片加载失败时显示的默认图片
|
||||||
defaultNodeImage: ''
|
defaultNodeImage: '',
|
||||||
|
// 是否将思维导图限制在画布内
|
||||||
|
// 比如向右拖动时,思维导图图形的最左侧到达画布中心时将无法继续向右拖动,其他同理
|
||||||
|
isLimitMindMapInCanvas: false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -194,6 +194,7 @@ class View {
|
|||||||
|
|
||||||
// 应用变换
|
// 应用变换
|
||||||
transform() {
|
transform() {
|
||||||
|
this.limitMindMapInCanvas()
|
||||||
this.mindMap.draw.transform({
|
this.mindMap.draw.transform({
|
||||||
origin: [0, 0],
|
origin: [0, 0],
|
||||||
scale: this.scale,
|
scale: this.scale,
|
||||||
@ -306,6 +307,64 @@ class View {
|
|||||||
}
|
}
|
||||||
this.translateXY(newX, newY)
|
this.translateXY(newX, newY)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 将思维导图限制在画布内
|
||||||
|
limitMindMapInCanvas() {
|
||||||
|
if (!this.mindMap.opt.isLimitMindMapInCanvas) return
|
||||||
|
let { scale, left, top, right, bottom } = this.getPositionLimit()
|
||||||
|
|
||||||
|
// 如果缩放值改变了
|
||||||
|
const scaleRatio = this.scale / scale
|
||||||
|
left *= scaleRatio
|
||||||
|
right *= scaleRatio
|
||||||
|
top *= scaleRatio
|
||||||
|
bottom *= scaleRatio
|
||||||
|
|
||||||
|
// 加上画布中心点距离
|
||||||
|
const centerX = this.mindMap.width / 2
|
||||||
|
const centerY = this.mindMap.height / 2
|
||||||
|
const scaleOffset = this.scale - 1
|
||||||
|
left -= scaleOffset * centerX
|
||||||
|
right -= scaleOffset * centerX
|
||||||
|
top -= scaleOffset * centerY
|
||||||
|
bottom -= scaleOffset * centerY
|
||||||
|
|
||||||
|
// 判断是否超出边界
|
||||||
|
if (this.x > left) {
|
||||||
|
this.x = left
|
||||||
|
}
|
||||||
|
if (this.x < right) {
|
||||||
|
this.x = right
|
||||||
|
}
|
||||||
|
if (this.y > top) {
|
||||||
|
this.y = top
|
||||||
|
}
|
||||||
|
if (this.y < bottom) {
|
||||||
|
this.y = bottom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算图形四个方向的位置边界值
|
||||||
|
getPositionLimit() {
|
||||||
|
const { scaleX, scaleY } = this.mindMap.draw.transform()
|
||||||
|
const drawRect = this.mindMap.draw.rbox()
|
||||||
|
const rootRect = this.mindMap.renderer.root.group.rbox()
|
||||||
|
const rootCenterOffset = this.mindMap.renderer.layout.getRootCenterOffset(
|
||||||
|
rootRect.width,
|
||||||
|
rootRect.height
|
||||||
|
)
|
||||||
|
const left = rootRect.x - drawRect.x - rootCenterOffset.x * scaleX
|
||||||
|
const right = rootRect.x - drawRect.x2 - rootCenterOffset.x * scaleX
|
||||||
|
const top = rootRect.y - drawRect.y - rootCenterOffset.y * scaleY
|
||||||
|
const bottom = rootRect.y - drawRect.y2 - rootCenterOffset.y * scaleY
|
||||||
|
return {
|
||||||
|
scale: scaleX,
|
||||||
|
left,
|
||||||
|
right,
|
||||||
|
top,
|
||||||
|
bottom
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default View
|
export default View
|
||||||
|
|||||||
@ -168,18 +168,21 @@ class Base {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 规范initRootNodePosition配置
|
||||||
|
formatInitRootNodePosition(pos) {
|
||||||
|
const { CENTER } = CONSTANTS.INIT_ROOT_NODE_POSITION
|
||||||
|
if (!pos || !Array.isArray(pos) || pos.length < 2) {
|
||||||
|
pos = [CENTER, CENTER]
|
||||||
|
}
|
||||||
|
return pos
|
||||||
|
}
|
||||||
|
|
||||||
// 定位节点到画布中间
|
// 定位节点到画布中间
|
||||||
setNodeCenter(node, position) {
|
setNodeCenter(node, position) {
|
||||||
let { initRootNodePosition } = this.mindMap.opt
|
let { initRootNodePosition } = this.mindMap.opt
|
||||||
initRootNodePosition = position || initRootNodePosition
|
initRootNodePosition = this.formatInitRootNodePosition(
|
||||||
let { CENTER } = CONSTANTS.INIT_ROOT_NODE_POSITION
|
position || initRootNodePosition
|
||||||
if (
|
)
|
||||||
!initRootNodePosition ||
|
|
||||||
!Array.isArray(initRootNodePosition) ||
|
|
||||||
initRootNodePosition.length < 2
|
|
||||||
) {
|
|
||||||
initRootNodePosition = [CENTER, CENTER]
|
|
||||||
}
|
|
||||||
node.left = this.formatPosition(
|
node.left = this.formatPosition(
|
||||||
initRootNodePosition[0],
|
initRootNodePosition[0],
|
||||||
this.mindMap.width,
|
this.mindMap.width,
|
||||||
@ -192,6 +195,38 @@ class Base {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 当initRootNodePosition配置不为默认的['center','center']时,计算当前配置和默认配置情况下,中心点位置的差值
|
||||||
|
getRootCenterOffset(width, height) {
|
||||||
|
// 如果initRootNodePosition是默认的,那么不需要计算
|
||||||
|
let { initRootNodePosition } = this.mindMap.opt
|
||||||
|
const { CENTER } = CONSTANTS.INIT_ROOT_NODE_POSITION
|
||||||
|
initRootNodePosition = this.formatInitRootNodePosition(initRootNodePosition)
|
||||||
|
if (
|
||||||
|
initRootNodePosition[0] === CENTER &&
|
||||||
|
initRootNodePosition[1] === CENTER
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 否则需要计算当前配置和默认配置的差值
|
||||||
|
const tmpNode = {
|
||||||
|
width: width,
|
||||||
|
height: height
|
||||||
|
}
|
||||||
|
const tmpNode2 = {
|
||||||
|
width: width,
|
||||||
|
height: height
|
||||||
|
}
|
||||||
|
this.setNodeCenter(tmpNode, ['center', 'center'])
|
||||||
|
this.setNodeCenter(tmpNode2)
|
||||||
|
return {
|
||||||
|
x: tmpNode2.left - tmpNode.left,
|
||||||
|
y: tmpNode2.top - tmpNode.top
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 更新子节点属性
|
// 更新子节点属性
|
||||||
updateChildren(children, prop, offset) {
|
updateChildren(children, prop, offset) {
|
||||||
children.forEach(item => {
|
children.forEach(item => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user