Compare commits

..

3 Commits

Author SHA1 Message Date
71acd3814b no message 2025-05-14 17:07:28 +08:00
70dbe5b72b no message 2025-05-14 16:46:13 +08:00
43ea54e0a3 no message 2025-05-14 16:39:15 +08:00
7 changed files with 597 additions and 561 deletions

0
.editorconfig Normal file
View File

0
.prettierrc Normal file
View File

24
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,24 @@
{
"editor.formatOnSave": true,
"editor.defaultFormatter": null,
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"editor.tabSize": 2,
"editor.codeActionsOnSave": {
"source.fixAll": true,
"source.fixAll.eslint": true
}
}

View File

@ -1,325 +1,338 @@
export default MindMap; import { MiniMap } from './src/plugins/MiniMap'
export default MindMap
declare class MindMap { declare class MindMap {
/** /**
* *
* @param {defaultOpt} opt * @param {defaultOpt} opt
*/ */
constructor(opt?:{ constructor(opt?: {
el?:any; el?: any
data?:any; data?: any
viewData?:any; viewData?: any
readonly?:boolean; readonly?: boolean
layout?:string; layout?: string
fishboneDeg?:number; fishboneDeg?: number
theme?:string; theme?: string
themeConfig?:{}; themeConfig?: {}
scaleRatio?:number; scaleRatio?: number
translateRatio?:number; translateRatio?: number
minZoomRatio?:number; minZoomRatio?: number
maxZoomRatio?:number; maxZoomRatio?: number
customCheckIsTouchPad?:any; customCheckIsTouchPad?: any
mouseScaleCenterUseMousePosition?:boolean; mouseScaleCenterUseMousePosition?: boolean
maxTag?:number; maxTag?: number
expandBtnSize?:number; expandBtnSize?: number
imgTextMargin?:number; imgTextMargin?: number
textContentMargin?:number; textContentMargin?: number
customNoteContentShow?:any; customNoteContentShow?: any
textAutoWrapWidth?:number; textAutoWrapWidth?: number
customHandleMousewheel?:any; customHandleMousewheel?: any
mousewheelAction?:string; mousewheelAction?: string
mousewheelMoveStep?:number; mousewheelMoveStep?: number
mousewheelZoomActionReverse?:boolean; mousewheelZoomActionReverse?: boolean
defaultInsertSecondLevelNodeText?:string; defaultInsertSecondLevelNodeText?: string
defaultInsertBelowSecondLevelNodeText?:string; defaultInsertBelowSecondLevelNodeText?: string
expandBtnStyle?:{ expandBtnStyle?: {
color?:string; color?: string
fill?:string; fill?: string
fontSize?:number; fontSize?: number
strokeColor?:string; strokeColor?: string
}; }
expandBtnIcon?:{ expandBtnIcon?: {
open?:string; open?: string
close?:string; close?: string
}; }
expandBtnNumHandler?:any; expandBtnNumHandler?: any
isShowExpandNum?:boolean; isShowExpandNum?: boolean
enableShortcutOnlyWhenMouseInSvg?:boolean; enableShortcutOnlyWhenMouseInSvg?: boolean
customCheckEnableShortcut?:any; customCheckEnableShortcut?: any
initRootNodePosition?:any; initRootNodePosition?: any
nodeTextEditZIndex?:number; nodeTextEditZIndex?: number
nodeNoteTooltipZIndex?:number; nodeNoteTooltipZIndex?: number
isEndNodeTextEditOnClickOuter?:boolean; isEndNodeTextEditOnClickOuter?: boolean
maxHistoryCount?:number; maxHistoryCount?: number
alwaysShowExpandBtn?:boolean; alwaysShowExpandBtn?: boolean
notShowExpandBtn?:boolean; notShowExpandBtn?: boolean
iconList?:any[]; iconList?: any[]
maxNodeCacheCount?:number; maxNodeCacheCount?: number
fitPadding?:number; fitPadding?: number
enableCtrlKeyNodeSelection?:boolean; enableCtrlKeyNodeSelection?: boolean
useLeftKeySelectionRightKeyDrag?:boolean; useLeftKeySelectionRightKeyDrag?: boolean
beforeTextEdit?:any; beforeTextEdit?: any
isUseCustomNodeContent?:boolean; isUseCustomNodeContent?: boolean
customCreateNodeContent?:any; customCreateNodeContent?: any
customInnerElsAppendTo?:any; customInnerElsAppendTo?: any
enableAutoEnterTextEditWhenKeydown?:boolean; enableAutoEnterTextEditWhenKeydown?: boolean
autoEmptyTextWhenKeydownEnterEdit?:boolean; autoEmptyTextWhenKeydownEnterEdit?: boolean
customHandleClipboardText?:any; customHandleClipboardText?: any
disableMouseWheelZoom?:boolean; disableMouseWheelZoom?: boolean
errorHandler?:(code?:any, error?:any) => void; errorHandler?: (code?: any, error?: any) => void
enableDblclickBackToRootNode?:boolean; enableDblclickBackToRootNode?: boolean
hoverRectColor?:string; hoverRectColor?: string
hoverRectPadding?:number; hoverRectPadding?: number
selectTextOnEnterEditText?:boolean; selectTextOnEnterEditText?: boolean
deleteNodeActive?:boolean; deleteNodeActive?: boolean
fit?:boolean; fit?: boolean
tagsColorMap?:{}; tagsColorMap?: {}
cooperateStyle?:{ cooperateStyle?: {
avatarSize?:number; avatarSize?: number
fontSize?:number; fontSize?: number
}; }
onlyOneEnableActiveNodeOnCooperate?:boolean; onlyOneEnableActiveNodeOnCooperate?: boolean
defaultGeneralizationText?:string; defaultGeneralizationText?: string
handleIsSplitByWrapOnPasteCreateNewNode?:any; handleIsSplitByWrapOnPasteCreateNewNode?: any
addHistoryTime?:number; addHistoryTime?: number
isDisableDrag?:boolean; isDisableDrag?: boolean
createNewNodeBehavior?:string; createNewNodeBehavior?: string
defaultNodeImage?:string; defaultNodeImage?: string
isLimitMindMapInCanvas?:boolean; isLimitMindMapInCanvas?: boolean
handleNodePasteImg?:any; handleNodePasteImg?: any
customCreateNodePath?:any; customCreateNodePath?: any
customCreateNodePolygon?:any; customCreateNodePolygon?: any
customTransformNodeLinePath?:any; customTransformNodeLinePath?: any
beforeShortcutRun?:any; beforeShortcutRun?: any
resetScaleOnMoveNodeToCenter?:boolean; resetScaleOnMoveNodeToCenter?: boolean
createNodePrefixContent?:any; createNodePrefixContent?: any
createNodePostfixContent?:any; createNodePostfixContent?: any
disabledClipboard?:boolean; disabledClipboard?: boolean
customHyperlinkJump?:any; customHyperlinkJump?: any
openPerformance?:boolean; openPerformance?: boolean
performanceConfig?:{ performanceConfig?: {
time?:number; time?: number
padding?:number; padding?: number
removeNodeWhenOutCanvas?:boolean; removeNodeWhenOutCanvas?: boolean
}; }
emptyTextMeasureHeightText?:string; emptyTextMeasureHeightText?: string
openRealtimeRenderOnNodeTextEdit?:boolean; openRealtimeRenderOnNodeTextEdit?: boolean
mousedownEventPreventDefault?:boolean; mousedownEventPreventDefault?: boolean
onlyPasteTextWhenHasImgAndText?:boolean; onlyPasteTextWhenHasImgAndText?: boolean
enableDragModifyNodeWidth?:boolean; enableDragModifyNodeWidth?: boolean
minNodeTextModifyWidth?:number; minNodeTextModifyWidth?: number
maxNodeTextModifyWidth?:number; maxNodeTextModifyWidth?: number
customHandleLine?:any; customHandleLine?: any
addHistoryOnInit?:boolean; addHistoryOnInit?: boolean
noteIcon?:{ noteIcon?: {
icon?:string; icon?: string
style?:{}; style?: {}
}; }
hyperlinkIcon?:{ hyperlinkIcon?: {
icon?:string; icon?: string
style?:{}; style?: {}
}; }
attachmentIcon?:{ attachmentIcon?: {
icon?:string; icon?: string
style?:{}; style?: {}
}; }
isShowCreateChildBtnIcon?:boolean; isShowCreateChildBtnIcon?: boolean
quickCreateChildBtnIcon?:{ quickCreateChildBtnIcon?: {
icon?:string; icon?: string
style?:{}; style?: {}
}; }
customQuickCreateChildBtnClick?:any; customQuickCreateChildBtnClick?: any
addCustomContentToNode?:any; addCustomContentToNode?: any
enableInheritAncestorLineStyle?:boolean; enableInheritAncestorLineStyle?: boolean
selectTranslateStep?:number; selectTranslateStep?: number
selectTranslateLimit?:number; selectTranslateLimit?: number
enableFreeDrag?:boolean; enableFreeDrag?: boolean
autoMoveWhenMouseInEdgeOnDrag?:boolean; autoMoveWhenMouseInEdgeOnDrag?: boolean
dragMultiNodeRectConfig?:{ dragMultiNodeRectConfig?: {
width?:number; width?: number
height?:number; height?: number
fill?:string; fill?: string
}; }
dragPlaceholderRectFill?:string; dragPlaceholderRectFill?: string
dragPlaceholderLineConfig?:{ dragPlaceholderLineConfig?: {
color?:string; color?: string
width?:number; width?: number
}; }
dragOpacityConfig?:{ dragOpacityConfig?: {
cloneNodeOpacity?:number; cloneNodeOpacity?: number
beingDragNodeOpacity?:number; beingDragNodeOpacity?: number
}; }
handleDragCloneNode?:any; handleDragCloneNode?: any
beforeDragEnd?:any; beforeDragEnd?: any
beforeDragStart?:any; beforeDragStart?: any
watermarkConfig?:{ watermarkConfig?: {
onlyExport?:boolean; onlyExport?: boolean
text?:string; text?: string
lineSpacing?:number; lineSpacing?: number
textSpacing?:number; textSpacing?: number
angle?:number; angle?: number
textStyle?:{ textStyle?: {
color?:string; color?: string
opacity?:number; opacity?: number
fontSize?:number; fontSize?: number
}; }
belowNode?:boolean; belowNode?: boolean
}; }
exportPaddingX?:number; exportPaddingX?: number
exportPaddingY?:number; exportPaddingY?: number
resetCss?:string; resetCss?: string
minExportImgCanvasScale?:number; minExportImgCanvasScale?: number
addContentToHeader?:any; addContentToHeader?: any
addContentToFooter?:any; addContentToFooter?: any
handleBeingExportSvg?:any; handleBeingExportSvg?: any
maxCanvasSize?:number; maxCanvasSize?: number
defaultAssociativeLineText?:string; defaultAssociativeLineText?: string
associativeLineIsAlwaysAboveNode?:boolean; associativeLineIsAlwaysAboveNode?: boolean
associativeLineInitPointsPosition?:{ associativeLineInitPointsPosition?: {
from?:string; from?: string
to?:string; to?: string
}; }
enableAdjustAssociativeLinePoints?:boolean; enableAdjustAssociativeLinePoints?: boolean
beforeAssociativeLineConnection?:any; beforeAssociativeLineConnection?: any
disableTouchZoom?:boolean; disableTouchZoom?: boolean
minTouchZoomScale?:number; minTouchZoomScale?: number
maxTouchZoomScale?:number; maxTouchZoomScale?: number
isLimitMindMapInCanvasWhenHasScrollbar?:boolean; isLimitMindMapInCanvasWhenHasScrollbar?: boolean
isOnlySearchCurrentRenderNodes?:boolean; isOnlySearchCurrentRenderNodes?: boolean
beforeCooperateUpdate?:any; beforeCooperateUpdate?: any
rainbowLinesConfig?:{ rainbowLinesConfig?: {
open?:boolean; open?: boolean
colorsList?:any[]; colorsList?: any[]
}; }
demonstrateConfig?:any; demonstrateConfig?: any
enableEditFormulaInRichTextEdit?:boolean; enableEditFormulaInRichTextEdit?: boolean
katexFontPath?:string; katexFontPath?: string
getKatexOutputType?:any; getKatexOutputType?: any
transformRichTextOnEnterEdit?:any; transformRichTextOnEnterEdit?: any
beforeHideRichTextEdit?:any; beforeHideRichTextEdit?: any
outerFramePaddingX?:number; outerFramePaddingX?: number
outerFramePaddingY?:number; outerFramePaddingY?: number
defaultOuterFrameText?:string; defaultOuterFrameText?: string
onlyPainterNodeCustomStyles?:boolean; onlyPainterNodeCustomStyles?: boolean
beforeDeleteNodeImg?:any; beforeDeleteNodeImg?: any
imgResizeBtnSize?:number; imgResizeBtnSize?: number
minImgResizeWidth?:number; minImgResizeWidth?: number
minImgResizeHeight?:number; minImgResizeHeight?: number
maxImgResizeWidthInheritTheme?:boolean; maxImgResizeWidthInheritTheme?: boolean
maxImgResizeWidth?:number; maxImgResizeWidth?: number
maxImgResizeHeight?:number; maxImgResizeHeight?: number
customDeleteBtnInnerHTML?:string; customDeleteBtnInnerHTML?: string
customResizeBtnInnerHTML?:string; customResizeBtnInnerHTML?: string
}); })
opt?:any; opt?: any
el?:any; el?: any
initWidth?:any; initWidth?: any
initHeight?:any; initHeight?: any
cssEl?:HTMLStyleElement; cssEl?: HTMLStyleElement
cssTextMap?:{}; cssTextMap?: {}
nodeInnerPrefixList?:any[]; nodeInnerPrefixList?: any[]
nodeInnerPostfixList?:any[]; nodeInnerPostfixList?: any[]
editNodeClassList?:any[]; editNodeClassList?: any[]
extendShapeList?:any[]; extendShapeList?: any[]
event?:Event; event?: Event
keyCommand?:KeyCommand; keyCommand?: KeyCommand
command?:Command; command?: Command
renderer?:Render; renderer?: Render
view?:View; view?: View
batchExecution?:BatchExecution; batchExecution?: BatchExecution
handleOpt(opt?:any):any; handleOpt(opt?: any): any
handleData(data?:any):any; handleData(data?: any): any
initContainer():void; initContainer(): void
associativeLineDraw?:any; associativeLineDraw?: any
svg?:any; svg?: any
draw?:any; draw?: any
lineDraw?:any; lineDraw?: any
nodeDraw?:any; nodeDraw?: any
otherDraw?:any; otherDraw?: any
clearDraw():void; clearDraw(): void
appendCss(key?:any, str?:any):void; appendCss(key?: any, str?: any): void
removeAppendCss(key?:any):void; removeAppendCss(key?: any): void
joinCss():string; joinCss(): string
addCss():void; addCss(): void
removeCss():void; removeCss(): void
checkEditNodeClassIndex(className?:any):number; checkEditNodeClassIndex(className?: any): number
addEditNodeClass(className?:any):void; addEditNodeClass(className?: any): void
deleteEditNodeClass(className?:any):void; deleteEditNodeClass(className?: any): void
render(callback?:any, source?:string):void; render(callback?: any, source?: string): void
reRender(callback?:any, source?:string):void; reRender(callback?: any, source?: string): void
getElRectInfo():void; getElRectInfo(): void
elRect?:any; elRect?: any
width?:any; width?: any
height?:any; height?: any
resize():void; resize(): void
on(event?:any, fn?:any):void; on(event?: any, fn?: any): void
emit(event?:any, ...args?:any[]):void; emit(event?: any, ...args: any[]): void
off(event?:any, fn?:any):void; off(event?: any, fn?: any): void
initCache():void; initCache(): void
commonCaches?:{ commonCaches?: {
measureCustomNodeContentSizeEl?:any; measureCustomNodeContentSizeEl?: any
measureRichtextNodeTextSizeEl?:any; measureRichtextNodeTextSizeEl?: any
}; }
initTheme():void; initTheme(): void
themeConfig?:any; themeConfig?: any
setTheme(theme?:any, notRender?:boolean):void; setTheme(theme?: any, notRender?: boolean): void
getTheme():any; getTheme(): any
setThemeConfig(config?:any, notRender?:boolean):void; setThemeConfig(config?: any, notRender?: boolean): void
getCustomThemeConfig():any; getCustomThemeConfig(): any
getThemeConfig(prop?:any):any; getThemeConfig(prop?: any): any
getConfig(prop?:any):any; getConfig(prop?: any): any
updateConfig(opt?:{}):void; updateConfig(opt?: {}): void
getLayout():any; getLayout(): any
setLayout(layout?:any, notRender?:boolean):void; setLayout(layout?: any, notRender?: boolean): void
execCommand(...args?:any[]):void; execCommand(...args: any[]): void
updateData(data?:any):void; updateData(data?: any): void
setData(data?:any):void; setData(data?: any): void
setFullData(data?:any):void; setFullData(data?: any): void
getData(withConfig?:any):any; getData(withConfig?: any): any
export(...args?:any[]):Promise<any>; export(...args: any[]): Promise<any>
toPos(x?:any, y?:any):{ toPos(
x?:number; x?: any,
y?:number; y?: any
}; ): {
setMode(mode?:any):void; x?: number
getSvgData({ paddingX, paddingY, ignoreWatermark, addContentToHeader, addContentToFooter, node }?:{ y?: number
paddingX?:number; }
paddingY?:number; setMode(mode?: any): void
ignoreWatermark?:boolean; getSvgData({
}):{ paddingX,
svg?:any; paddingY,
svgHTML?:any; ignoreWatermark,
clipData?:any; addContentToHeader,
rect?:any; addContentToFooter,
origWidth?:any; node
origHeight?:any; }?: {
scaleX?:any; paddingX?: number
scaleY?:any; paddingY?: number
}; ignoreWatermark?: boolean
addShape(shape?:any):void; }): {
removeShape(name?:any):void; svg?: any
getSvgObjects():{ svgHTML?: any
SVG?:any; clipData?: any
G?:any; rect?: any
Rect?:any; origWidth?: any
}; origHeight?: any
addPlugin(plugin?:any, opt?:any):void; scaleX?: any
removePlugin(plugin?:any):void; scaleY?: any
initPlugin(plugin?:any):void; }
destroy():void; addShape(shape?: any): void
removeShape(name?: any): void
getSvgObjects(): {
SVG?: any
G?: any
Rect?: any
}
addPlugin(plugin?: any, opt?: any): void
removePlugin(plugin?: any): void
initPlugin(plugin?: any): void
destroy(): void
miniMap?: MiniMap
} }
declare namespace MindMap { declare namespace MindMap {
function extendNodeDataNoStylePropList(list?:any[]):void; function extendNodeDataNoStylePropList(list?: any[]): void
function resetNodeDataNoStylePropList():void; function resetNodeDataNoStylePropList(): void
let pluginList:any[]; let pluginList: any[]
function usePlugin(plugin?:any, opt?:{}):typeof MindMap; function usePlugin(plugin?: any, opt?: {}): typeof MindMap
function hasPlugin(plugin?:any):number; function hasPlugin(plugin?: any): number
let instanceCount:number; let instanceCount: number
function defineTheme(name?:any, config?:{}):Error; function defineTheme(name?: any, config?: {}): Error
function removeTheme(name?:any):void; function removeTheme(name?: any): void
} }
import Event from './src/core/event/Event'; import Event from './src/core/event/Event'
import KeyCommand from './src/core/command/KeyCommand'; import KeyCommand from './src/core/command/KeyCommand'
import Command from './src/core/command/Command'; import Command from './src/core/command/Command'
import Render from './src/core/render/Render'; import Render from './src/core/render/Render'
import View from './src/core/view/View'; import View from './src/core/view/View'
import BatchExecution from './src/utils/BatchExecution'; import BatchExecution from './src/utils/BatchExecution'

View File

@ -148,6 +148,15 @@ export default {
getImgUrl(img => { getImgUrl(img => {
this.mindMapImg = img this.mindMapImg = img
}) })
console.log('viewBoxStyle', {
getImgUrl,
viewBoxStyle,
miniMapBoxScale,
miniMapBoxLeft,
miniMapBoxTop
})
this.viewBoxStyle = viewBoxStyle this.viewBoxStyle = viewBoxStyle
this.svgBoxScale = miniMapBoxScale this.svgBoxScale = miniMapBoxScale
this.svgBoxLeft = miniMapBoxLeft this.svgBoxLeft = miniMapBoxLeft

View File

@ -1,3 +1,225 @@
<script setup lang="ts">
import { ref, onMounted, onUnmounted, nextTick, Ref } from "vue";
import { useMindMapStore } from "../index";
import { storeToRefs } from "pinia";
import { debounce } from "simple-mind-map/src/utils";
const mindMapStore = useMindMapStore();
const { getMindMapInstance } = mindMapStore;
const { isDark, showMiniMap } = storeToRefs(mindMapStore);
const debouncedDrawMiniMap = debounce(
() => {
drawMiniMap();
},
500,
null
);
// 使
const debouncedSetSize = debounce(
() => {
width.value = Math.min(window.innerWidth - 80, 370);
nextTick(() => {
if (showMiniMap.value && navigatorBoxRef.value) {
drawMiniMap();
}
});
},
300,
null
);
const svgBoxScale = ref(1);
const svgBoxLeft = ref(0);
const svgBoxTop = ref(0);
const viewBoxStyle = ref({
left: "0px",
top: "0px",
bottom: "0px",
right: "0px",
});
const mindMapImg = ref("");
const width = ref(0);
const withTransition = ref(true);
const navigatorBoxRef: Ref<HTMLElement | null> = ref(null);
const svgBoxRef = ref(null);
async function init() {
await nextTick();
const mindMapInstance = getMindMapInstance();
// mini_map_view_box_position_change
mindMapInstance?.on(
"mini_map_view_box_position_change",
(e: { left: string; right: string; top: string; bottom: string }) => {
onViewBoxPositionChange(e);
}
);
// view_data_change
mindMapInstance?.on("view_data_change", dataChange);
//node_tree_render_end
mindMapInstance?.on("node_tree_render_end", dataChange);
// toggle_mini_map
mindMapInstance?.on("toggle_mini_map", (show: boolean) => {
showMiniMap.value = show;
});
// data_change
mindMapInstance?.on("data_change", dataChange);
}
function drawMiniMap() {
const mindMapInstance = getMindMapInstance();
if (!mindMapInstance || !mindMapInstance?.miniMap) return;
if (!navigatorBoxRef.value) return;
const rect = navigatorBoxRef.value.getBoundingClientRect();
const calculationResult = mindMapInstance?.miniMap?.calculationMiniMap(
rect.width,
rect.height
);
if (!calculationResult) return;
const {
getImgUrl,
viewBoxStyle: __viewBoxStyle,
miniMapBoxScale,
miniMapBoxLeft,
miniMapBoxTop,
} = calculationResult;
getImgUrl &&
getImgUrl((img: string) => {
mindMapImg.value = img;
});
viewBoxStyle.value = __viewBoxStyle;
svgBoxScale.value = miniMapBoxScale;
svgBoxLeft.value = miniMapBoxLeft;
svgBoxTop.value = miniMapBoxTop;
}
function dataChange() {
if (!showMiniMap.value) return;
debouncedDrawMiniMap();
}
function setSize() {
debouncedSetSize();
}
function onMousedown(e: MouseEvent) {
const mindMapInstance = getMindMapInstance();
if (
mindMapInstance &&
mindMapInstance?.miniMap &&
typeof mindMapInstance?.miniMap?.onMousedown === "function"
) {
mindMapInstance?.miniMap?.onMousedown(e);
}
}
function onMousemove(e: MouseEvent) {
const mindMapInstance = getMindMapInstance();
if (
mindMapInstance &&
mindMapInstance?.miniMap &&
typeof mindMapInstance?.miniMap?.onMousemove === "function"
) {
mindMapInstance?.miniMap?.onMousemove(e);
}
}
function onMouseup(e: MouseEvent) {
if (!withTransition.value) withTransition.value = true;
const mindMapInstance = getMindMapInstance();
if (
mindMapInstance &&
mindMapInstance?.miniMap &&
typeof mindMapInstance?.miniMap?.onMouseup === "function"
) {
mindMapInstance?.miniMap?.onMouseup(e);
}
}
function onViewBoxMousedown(e: MouseEvent) {
const mindMapInstance = getMindMapInstance();
if (
mindMapInstance &&
mindMapInstance?.miniMap &&
typeof mindMapInstance?.miniMap?.onViewBoxMousedown === "function"
) {
mindMapInstance?.miniMap?.onViewBoxMousedown(e);
}
}
function onViewBoxMousemove(e: MouseEvent) {
const mindMapInstance = getMindMapInstance();
if (
mindMapInstance &&
mindMapInstance?.miniMap &&
typeof mindMapInstance?.miniMap?.onViewBoxMousemove === "function"
) {
mindMapInstance?.miniMap?.onViewBoxMousemove(e);
}
}
function onViewBoxPositionChange({
left,
right,
top,
bottom,
}: {
left: string;
right: string;
top: string;
bottom: string;
}) {
withTransition.value = false;
viewBoxStyle.value.left = left;
viewBoxStyle.value.right = right;
viewBoxStyle.value.top = top;
viewBoxStyle.value.bottom = bottom;
}
onMounted(async () => {
await init();
setSize();
window.addEventListener("resize", setSize);
window.addEventListener("mouseup", onMouseup);
});
onUnmounted(() => {
window.removeEventListener("resize", setSize);
window.removeEventListener("mouseup", onMouseup);
const mindMapInstance = getMindMapInstance();
if (mindMapInstance && typeof mindMapInstance?.off === "function") {
mindMapInstance?.off("data_change", dataChange);
mindMapInstance?.off(
"mini_map_view_box_position_change",
onViewBoxPositionChange
);
}
});
</script>
<template> <template>
<div <div
v-if="showMiniMap" v-if="showMiniMap"
@ -8,9 +230,9 @@
@mousedown="onMousedown" @mousedown="onMousedown"
@mousemove="onMousemove" @mousemove="onMousemove"
> >
<span>svgBoxScale:{{ svgBoxScale }}</span> <!-- <span>svgBoxScale:{{ svgBoxScale }}</span>
<span>svgBoxLeft:{{ svgBoxLeft }}</span> <span>svgBoxLeft:{{ svgBoxLeft }}</span>
<span>svgBoxTop:{{ svgBoxTop }}</span> <span>svgBoxTop:{{ svgBoxTop }}</span> -->
<div <div
class="svgBox" class="svgBox"
ref="svgBoxRef" ref="svgBoxRef"
@ -32,239 +254,11 @@
</div> </div>
</template> </template>
<script setup>
import { ref, onMounted, onUnmounted, computed, nextTick, watch } from "vue";
import { useMindMapStore } from "../index";
import { storeToRefs } from "pinia";
import { throttle, debounce } from 'simple-mind-map/src/utils';
const mindMapStore = useMindMapStore();
const { getMindMapInstance } = mindMapStore;
const { isDark, showMiniMap } = storeToRefs(mindMapStore);
// 使
const debouncedDrawMiniMap = debounce(() => {
drawMiniMap();
}, 500);
// 使
const debouncedSetSize = debounce(() => {
width.value = Math.min(window.innerWidth - 80, 370);
nextTick(() => {
if (showMiniMap.value && navigatorBoxRef.value) {
init();
drawMiniMap();
}
});
}, 300);
const boxWidth = ref(0);
const boxHeight = ref(0);
const svgBoxScale = ref(1);
const svgBoxLeft = ref(0);
const svgBoxTop = ref(0);
const viewBoxStyle = ref({
left: "0px", //
top: "0px",
bottom: "0px",
right: "0px",
});
const mindMapImg = ref("");
const width = ref(0);
const withTransition = ref(true);
const navigatorBoxRef = ref(null);
const svgBoxRef = ref(null);
async function init() {
if (!navigatorBoxRef.value) return;
const rect = navigatorBoxRef.value.getBoundingClientRect();
// console.log("rect", rect);
boxWidth.value = rect.width;
boxHeight.value = rect.height;
await nextTick();
const mindMapInstance = getMindMapInstance();
// data_change
mindMapInstance.on("data_change", data_change);
// mini_map_view_box_position_change
mindMapInstance.on("mini_map_view_box_position_change", (e) => {
onViewBoxPositionChange(e);
});
// view_data_change
mindMapInstance.on("view_data_change", data_change);
//node_tree_render_end
mindMapInstance.on("node_tree_render_end", data_change);
// data_change
mindMapInstance.on("data_change", data_change);
// toggle_mini_map
mindMapInstance.on("toggle_mini_map", (show) => {
showMiniMap.value = show;
});
}
function drawMiniMap() {
const mindMapInstance = getMindMapInstance();
if (
!mindMapInstance ||
!mindMapInstance.miniMap ||
!boxWidth.value ||
!boxHeight.value
)
return;
const calculationResult = mindMapInstance.miniMap.calculationMiniMap(
boxWidth.value,
boxHeight.value
);
if (!calculationResult) return;
const {
getImgUrl,
viewBoxStyle: newViewBoxStyle,
miniMapBoxScale,
miniMapBoxLeft,
miniMapBoxTop,
} = calculationResult;
getImgUrl &&
getImgUrl((img) => {
mindMapImg.value = img;
});
viewBoxStyle.value = newViewBoxStyle;
svgBoxScale.value = miniMapBoxScale;
svgBoxLeft.value = miniMapBoxLeft;
svgBoxTop.value = miniMapBoxTop;
}
watch(
() => showMiniMap.value,
(isShown) => {
if (!isShown) return;
nextTick(() => {
navigatorBoxRef.value && init();
svgBoxRef.value && drawMiniMap();
});
},
{ immediate: true }
);
function data_change() {
if (!showMiniMap.value) return;
debouncedDrawMiniMap();
}
function setSize() {
debouncedSetSize();
}
function onMousedown(e) {
const mindMapInstance = getMindMapInstance();
if (
mindMapInstance &&
mindMapInstance.miniMap &&
typeof mindMapInstance.miniMap.onMousedown === "function"
) {
mindMapInstance.miniMap.onMousedown(e);
}
}
function onMousemove(e) {
const mindMapInstance = getMindMapInstance();
if (
mindMapInstance &&
mindMapInstance.miniMap &&
typeof mindMapInstance.miniMap.onMousemove === "function"
) {
mindMapInstance.miniMap.onMousemove(e);
}
}
function onMouseup(e) {
if (!withTransition.value) withTransition.value = true;
const mindMapInstance = getMindMapInstance();
if (
mindMapInstance &&
mindMapInstance.miniMap &&
typeof mindMapInstance.miniMap.onMouseup === "function"
) {
mindMapInstance.miniMap.onMouseup(e);
}
}
function onViewBoxMousedown(e) {
const mindMapInstance = getMindMapInstance();
if (
mindMapInstance &&
mindMapInstance.miniMap &&
typeof mindMapInstance.miniMap.onViewBoxMousedown === "function"
) {
mindMapInstance.miniMap.onViewBoxMousedown(e);
}
}
function onViewBoxMousemove(e) {
const mindMapInstance = getMindMapInstance();
if (
mindMapInstance &&
mindMapInstance.miniMap &&
typeof mindMapInstance.miniMap.onViewBoxMousemove === "function"
) {
mindMapInstance.miniMap.onViewBoxMousemove(e);
}
}
function onViewBoxPositionChange({ left, right, top, bottom }) {
withTransition.value = false;
viewBoxStyle.value.left = left;
viewBoxStyle.value.right = right;
viewBoxStyle.value.top = top;
viewBoxStyle.value.bottom = bottom;
}
onMounted(() => {
setSize();
window.addEventListener("resize", setSize);
window.addEventListener("mouseup", onMouseup);
});
onUnmounted(() => {
window.removeEventListener("resize", setSize);
window.removeEventListener("mouseup", onMouseup);
const mindMapInstance = getMindMapInstance();
if (mindMapInstance && typeof mindMapInstance.off === "function") {
mindMapInstance.off("data_change", data_change);
mindMapInstance.off(
"mini_map_view_box_position_change",
onViewBoxPositionChange
);
}
debouncedDrawMiniMap.cancel && debouncedDrawMiniMap.cancel();
debouncedSetSize.cancel && debouncedSetSize.cancel();
});
</script>
<style lang="scss" scoped> <style lang="scss" scoped>
.navigatorBox * {
margin: 0;
padding: 0;
}
.navigatorBox { .navigatorBox {
position: absolute; position: absolute;
height: 220px; height: 220px;
@ -284,13 +278,12 @@ onUnmounted(() => {
.svgBox { .svgBox {
position: absolute; position: absolute;
left: 0; left: 0;
top: 0;
transform-origin: left top; transform-origin: left top;
} }
.windowBox { .windowBox {
position: absolute; position: absolute;
border: 2px solid #ee4545; border: 2px solid rgb(238, 69, 69);
background-color: rgba(238, 69, 69, 0.2); background-color: rgba(238, 69, 69, 0.2);
&.withTransition { &.withTransition {

View File

@ -31,14 +31,11 @@ import { layoutGroupList } from "../../store/helpers/layoutGroupList";
import { useMindMapStore } from "../../index"; import { useMindMapStore } from "../../index";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
// 使store
const store = useMindMapStore(); const store = useMindMapStore();
const { useLayout } = store; const { useLayout } = store;
const { currentLayout } = storeToRefs(store); const { currentLayout } = storeToRefs(store);
onMounted(() => {});
onMounted(() => {
});
</script> </script>
<style scoped></style> <style scoped></style>