mind-map/simple-mind-map/src/MiniMap.js
2022-10-10 14:31:43 +08:00

176 lines
5.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 小地图类
class MiniMap {
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-10-10 14:00:45
* @Desc: 构造函数
*/
constructor(opt) {
this.mindMap = opt.mindMap;
this.isMousedown = false;
this.mousedownPos = {
x: 0,
y: 0,
};
this.startViewPos = {
x: 0,
y: 0,
};
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-10-10 14:00:43
* @Desc: 获取小地图相关数据
*/
getMiniMap() {
const svg = this.mindMap.svg;
const draw = this.mindMap.draw;
// 保存原始信息
const origWidth = svg.width();
const origHeight = svg.height();
const origTransform = draw.transform();
const elRect = this.mindMap.el.getBoundingClientRect();
// 去除放大缩小的变换效果
draw.scale(1 / origTransform.scaleX, 1 / origTransform.scaleY);
// 获取变换后的位置尺寸信息其实是getBoundingClientRect方法的包装方法
const rect = draw.rbox();
// 将svg设置为实际内容的宽高
svg.size(rect.width, rect.height);
// 把实际内容变换
draw.translate(-rect.x + elRect.left, -rect.y + elRect.top);
// 克隆一份数据
const clone = svg.clone();
// 恢复原先的大小和变换信息
svg.size(origWidth, origHeight);
draw.transform(origTransform);
return {
svg: clone, // 思维导图图形的整体svg元素包括svg画布容器、g实际的思维导图组
svgHTML: clone.svg(), // svg字符串
rect: {
...rect, // 思维导图图形未缩放时的位置尺寸等信息
ratio: rect.width / rect.height, // 思维导图图形的宽高比
},
origWidth, // 画布宽度
origHeight, // 画布高度
scaleX: origTransform.scaleX, // 思维导图图形的水平缩放值
scaleY: origTransform.scaleY, // 思维导图图形的垂直缩放值
};
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-10-10 14:05:51
* @Desc: 计算小地图的渲染数据
* boxWidth小地图容器的宽度
* boxHeight小地图容器的高度
*/
calculationMiniMap(boxWidth, boxHeight) {
let { svgHTML, rect, origWidth, origHeight, scaleX, scaleY } =
this.getMiniMap();
// 计算数据
let boxRatio = boxWidth / boxHeight;
let actWidth = 0;
let actHeight = 0;
if (boxRatio > rect.ratio) {
// 高度以box为准缩放宽度
actHeight = boxHeight;
actWidth = rect.ratio * actHeight;
} else {
// 宽度以box为准缩放高度
actWidth = boxWidth;
actHeight = actWidth / rect.ratio;
}
// svg图形的缩放及位置
let miniMapBoxScale = actWidth / rect.width;
let miniMapBoxLeft = (boxWidth - actWidth) / 2;
let miniMapBoxTop = (boxHeight - actHeight) / 2;
// 视口框大小及位置
let _rectX = rect.x - (rect.width * scaleX - rect.width) / 2;
let _rectX2 = rect.x2 + (rect.width * scaleX - rect.width) / 2;
let _rectY = rect.y - (rect.height * scaleY - rect.height) / 2;
let _rectY2 = rect.y2 + (rect.height * scaleY - rect.height) / 2;
let _rectWidth = rect.width * scaleX;
let _rectHeight = rect.height * scaleY;
let viewBoxStyle = {
left: 0,
top: 0,
right: 0,
bottom: 0,
};
viewBoxStyle.left =
Math.max(0, (-_rectX / _rectWidth) * actWidth) + miniMapBoxLeft + "px";
viewBoxStyle.right =
Math.max(0, ((_rectX2 - origWidth) / _rectWidth) * actWidth) +
miniMapBoxLeft +
"px";
viewBoxStyle.top =
Math.max(0, (-_rectY / _rectHeight) * actHeight) + miniMapBoxTop + "px";
viewBoxStyle.bottom =
Math.max(0, ((_rectY2 - origHeight) / _rectHeight) * actHeight) +
miniMapBoxTop +
"px";
return {
svgHTML, // 小地图html
viewBoxStyle, // 视图框的位置信息
miniMapBoxScale, // 视图框的缩放值
miniMapBoxLeft, // 视图框的left值
miniMapBoxTop, // 视图框的top值
};
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-10-10 14:22:40
* @Desc: 小地图鼠标按下事件
*/
onMousedown(e) {
this.isMousedown = true;
this.mousedownPos = {
x: e.clientX,
y: e.clientY,
};
// 保存视图当前的偏移量
let transformData = this.mindMap.view.getTransformData();
this.startViewPos = {
x: transformData.state.x,
y: transformData.state.y,
};
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-10-10 14:22:55
* @Desc: 小地图鼠标移动事件
*/
onMousemove(e, sensitivityNum = 5) {
if (!this.isMousedown) {
return;
}
let ox = e.clientX - this.mousedownPos.x;
let oy = e.clientY - this.mousedownPos.y;
// 在视图最初偏移量上累加更新量
this.mindMap.view.translateXTo(ox * sensitivityNum + this.startViewPos.x);
this.mindMap.view.translateYTo(oy * sensitivityNum + this.startViewPos.y);
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-10-10 14:23:01
* @Desc: 小地图鼠标松开事件
*/
onMouseup() {
this.isMousedown = false;
}
}
export default MiniMap;