docs: update progress for minimap control and toolbar toggles

This commit is contained in:
2025-12-28 16:30:09 +08:00
parent c65c880ad8
commit 9e64df5e33
6 changed files with 238 additions and 12 deletions

View File

@@ -21,6 +21,13 @@ const toolbarHeight = 48; // 工具栏的高度
const windowHeight = ref(window.innerHeight);
const contentHeight = computed(() => `${windowHeight.value - toolbarHeight}px`);
const normalizeGraphData = (data: any) => {
if (data && Array.isArray((data as any).nodes) && Array.isArray((data as any).edges)) {
return data;
}
return { nodes: [], edges: [] };
};
const handleTabsEdit = (
targetName: string | undefined,
action: 'remove' | 'add'
@@ -56,7 +63,7 @@ watch(
if (logicFlowInstance && currentTab?.graphRawData) {
try {
logicFlowInstance.render(currentTab.graphRawData);
logicFlowInstance.render(normalizeGraphData(currentTab.graphRawData));
logicFlowInstance.zoom(
currentTab.transform?.SCALE_X ?? 1,
[currentTab.transform?.TRANSLATE_X ?? 0, currentTab.transform?.TRANSLATE_Y ?? 0]
@@ -79,7 +86,7 @@ watch(
if (logicFlowInstance && currentTab?.graphRawData) {
try {
logicFlowInstance.render(currentTab.graphRawData);
logicFlowInstance.render(normalizeGraphData(currentTab.graphRawData));
logicFlowInstance.zoom(
currentTab.transform?.SCALE_X ?? 1,
[currentTab.transform?.TRANSLATE_X ?? 0, currentTab.transform?.TRANSLATE_Y ?? 0]

View File

@@ -9,6 +9,30 @@
<el-button type="info" @click="showUpdateLog">{{ t('updateLog') }}</el-button>
<el-button type="warning" @click="showFeedbackForm">{{ t('feedback') }}</el-button>
<el-button type="danger" @click="handleResetWorkspace">重置工作区</el-button>
<el-button type="warning" plain @click="handleClearCanvas">清空画布</el-button>
</div>
<div class="toolbar-controls">
<el-switch
v-model="selectionEnabled"
size="small"
inline-prompt
active-text="框选开"
inactive-text="框选关"
/>
<el-switch
v-model="snapGridEnabled"
size="small"
inline-prompt
active-text="吸附开"
inactive-text="吸附关"
/>
<el-switch
v-model="snaplineEnabled"
size="small"
inline-prompt
active-text="对齐线开"
inactive-text="对齐线关"
/>
</div>
<!-- 更新日志对话框 -->
@@ -84,9 +108,11 @@ import { useFilesStore } from "@/ts/useStore";
import { ElMessageBox } from "element-plus";
import { useGlobalMessage } from "@/ts/useGlobalMessage";
import { getLogicFlowInstance } from "@/ts/useLogicFlow";
import { useCanvasSettings } from '@/ts/useCanvasSettings';
const filesStore = useFilesStore();
const { showMessage } = useGlobalMessage();
const { selectionEnabled, snapGridEnabled, snaplineEnabled } = useCanvasSettings();
// 获取当前的 i18n 实例
const {t} = useI18n();
@@ -228,6 +254,39 @@ const handleResetWorkspace = () => {
});
};
const handleClearCanvas = () => {
ElMessageBox.confirm('仅清空当前画布,不影响其他文件,确定继续?', '提示', {
confirmButtonText: '清空',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
const lfInstance = getLogicFlowInstance();
const activeId = filesStore.activeFileId;
const activeFile = filesStore.getTab(activeId);
if (lfInstance) {
lfInstance.clearData();
lfInstance.render({ nodes: [], edges: [] });
lfInstance.zoom(1, [0, 0]);
}
if (activeFile) {
activeFile.graphRawData = { nodes: [], edges: [] };
activeFile.transform = {
SCALE_X: 1,
SCALE_Y: 1,
TRANSLATE_X: 0,
TRANSLATE_Y: 0
};
filesStore.updateTab(activeId);
}
showMessage('success', '当前画布已清空');
}).catch(() => {
// 用户取消
});
};
const watermark = reactive({
text: localStorage.getItem('watermark.text') || '示例水印',
fontSize: Number(localStorage.getItem('watermark.fontSize')) || 30,
@@ -363,6 +422,13 @@ const handleClose = (done) => {
z-index: 100;
}
.toolbar-controls {
display: flex;
align-items: center;
gap: 12px;
margin-top: 6px;
}
.title {
flex-grow: 1;
text-align: center;

View File

@@ -1,7 +1,7 @@
<template>
<div class="editor-layout" :style="{ height }">
<!-- 中间流程图区域 -->
<div class="flow-container">
<div class="flow-container" :class="{ 'snapline-disabled': !snaplineEnabled }">
<div class="flow-controls">
<div class="control-row toggles">
<label class="control-toggle">
@@ -12,7 +12,10 @@
<input type="checkbox" v-model="snapGridEnabled" />
<span>吸附网格</span>
</label>
<span class="control-hint">对齐线已开启</span>
<label class="control-toggle">
<input type="checkbox" v-model="snaplineEnabled" />
<span>对齐线</span>
</label>
<span class="control-hint">已选 {{ selectedCount }}</span>
<button class="control-button" type="button" @click="showAllNodes">显示全部</button>
</div>
@@ -59,7 +62,7 @@ import { ref, watch, onMounted, onBeforeUnmount } from 'vue';
import LogicFlow, { EventType } from '@logicflow/core';
import type { Position, NodeData, EdgeData, BaseNodeModel, GraphModel, GraphData } from '@logicflow/core';
import '@logicflow/core/lib/style/index.css';
import { Menu, Label, Snapshot, SelectionSelect } from '@logicflow/extension';
import { Menu, Label, Snapshot, SelectionSelect, MiniMap, Control } from '@logicflow/extension';
import '@logicflow/extension/lib/style/index.css';
import '@logicflow/core/es/index.css';
import '@logicflow/extension/es/index.css';
@@ -75,6 +78,7 @@ import PropertyPanel from './PropertyPanel.vue';
import { useGlobalMessage } from '@/ts/useGlobalMessage';
import { setLogicFlowInstance, destroyLogicFlowInstance } from '@/ts/useLogicFlow';
import { normalizePropertiesWithStyle, normalizeNodeStyle, styleEquals } from '@/ts/nodeStyle';
import { useCanvasSettings } from '@/ts/useCanvasSettings';
type AlignType = 'left' | 'right' | 'top' | 'bottom' | 'hcenter' | 'vcenter';
type DistributeType = 'horizontal' | 'vertical';
@@ -90,8 +94,7 @@ const props = defineProps<{
const containerRef = ref<HTMLElement | null>(null);
const lf = ref<LogicFlow | null>(null);
const selectedCount = ref(0);
const selectionEnabled = ref(true);
const snapGridEnabled = ref(true);
const { selectionEnabled, snapGridEnabled, snaplineEnabled } = useCanvasSettings();
const alignmentButtons: { key: AlignType; label: string }[] = [
{ key: 'left', label: '左对齐' },
{ key: 'right', label: '右对齐' },
@@ -578,11 +581,11 @@ onMounted(() => {
allowResize: true,
allowRotate: true,
overlapMode: -1,
snapline: true,
snapline: snaplineEnabled.value,
keyboard: {
enabled: true
},
plugins: [Menu, Label, Snapshot, SelectionSelect],
plugins: [Menu, Label, Snapshot, SelectionSelect, MiniMap, Control],
pluginsOptions: {
label: {
isMultiple: true,
@@ -591,6 +594,14 @@ onMounted(() => {
// textOverflowMode -> 'ellipsis' | 'wrap' | 'clip' | 'nowrap' | 'default'
textOverflowMode: 'wrap',
},
miniMap: {
isShowHeader: false,
isShowCloseIcon: true,
width: 200,
height: 140,
rightPosition: 16,
bottomPosition: 16
}
},
});
@@ -665,8 +676,10 @@ onMounted(() => {
registerNodes(lfInstance);
setLogicFlowInstance(lfInstance);
lfInstance.render({
// 渲染的数据
nodes: [],
edges: []
});
lfInstance.extension.miniMap.show();
normalizeAllNodes();
lfInstance.updateEditConfig({
multipleSelectKey: 'shift',
@@ -723,6 +736,14 @@ watch(snapGridEnabled, (enabled) => {
applySnapGrid(enabled);
});
watch(snaplineEnabled, (enabled) => {
const lfInstance = lf.value as any;
if (!lfInstance) return;
if (!enabled) {
lfInstance.snaplineModel?.clearSnapline?.();
}
});
// 销毁 LogicFlow
onBeforeUnmount(() => {
lf.value?.destroy();
@@ -830,4 +851,8 @@ onBeforeUnmount(() => {
background-color: #f5f7fa;
color: #409eff;
}
.snapline-disabled .lf-snapline {
display: none;
}
</style>

View File

@@ -0,0 +1,14 @@
import { ref } from 'vue';
// Shared canvas control state between FlowEditor and Toolbar.
const selectionEnabled = ref(true);
const snapGridEnabled = ref(true);
const snaplineEnabled = ref(true);
export function useCanvasSettings() {
return {
selectionEnabled,
snapGridEnabled,
snaplineEnabled
};
}