mirror of
https://github.com/Powerful-517/yys-editor.git
synced 2026-03-05 15:05:27 +00:00
fix(embed): adapt toolbar and canvas sizing inside modal
This commit is contained in:
@@ -16,14 +16,14 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 主内容区 -->
|
<!-- 主内容区 -->
|
||||||
<div class="editor-content" :style="{ height: contentHeight }">
|
<div class="editor-content">
|
||||||
<!-- 左侧组件库 -->
|
<!-- 左侧组件库 -->
|
||||||
<ComponentsPanel v-if="showComponentPanel" />
|
<ComponentsPanel v-if="showComponentPanel" />
|
||||||
|
|
||||||
<!-- 中间画布 + 右侧属性面板 -->
|
<!-- 中间画布 + 右侧属性面板 -->
|
||||||
<FlowEditor
|
<FlowEditor
|
||||||
ref="flowEditorRef"
|
ref="flowEditorRef"
|
||||||
:height="contentHeight"
|
height="100%"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, watch, onMounted, onBeforeUnmount } from 'vue'
|
import { ref, computed, watch, onMounted, onBeforeUnmount, nextTick } from 'vue'
|
||||||
import { createPinia, setActivePinia } from 'pinia'
|
import { createPinia, setActivePinia } from 'pinia'
|
||||||
import LogicFlow from '@logicflow/core'
|
import LogicFlow from '@logicflow/core'
|
||||||
import '@logicflow/core/lib/style/index.css'
|
import '@logicflow/core/lib/style/index.css'
|
||||||
@@ -151,14 +151,11 @@ const containerHeight = computed(() => {
|
|||||||
return typeof props.height === 'number' ? `${props.height}px` : props.height
|
return typeof props.height === 'number' ? `${props.height}px` : props.height
|
||||||
})
|
})
|
||||||
|
|
||||||
const contentHeight = computed(() => {
|
const triggerEditorResize = () => {
|
||||||
if (props.showToolbar) {
|
nextTick(() => {
|
||||||
const toolbarHeight = 48
|
(flowEditorRef.value as any)?.resizeCanvas?.()
|
||||||
const totalHeight = typeof props.height === 'number' ? props.height : 600
|
|
||||||
return `${totalHeight - toolbarHeight}px`
|
|
||||||
}
|
|
||||||
return containerHeight.value
|
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const destroyPreviewMode = () => {
|
const destroyPreviewMode = () => {
|
||||||
if (previewLf.value) {
|
if (previewLf.value) {
|
||||||
@@ -243,7 +240,8 @@ const setGraphData = (data: GraphData) => {
|
|||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
getGraphData,
|
getGraphData,
|
||||||
setGraphData
|
setGraphData,
|
||||||
|
resizeCanvas: triggerEditorResize
|
||||||
})
|
})
|
||||||
|
|
||||||
// 监听 data 变化
|
// 监听 data 变化
|
||||||
@@ -262,6 +260,7 @@ watch(() => props.mode, (newMode) => {
|
|||||||
}, 100)
|
}, 100)
|
||||||
} else {
|
} else {
|
||||||
destroyPreviewMode()
|
destroyPreviewMode()
|
||||||
|
triggerEditorResize()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -277,17 +276,28 @@ watch(
|
|||||||
{ deep: true }
|
{ deep: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
[() => props.width, () => props.height, () => props.showToolbar, () => props.showComponentPanel],
|
||||||
|
() => {
|
||||||
|
if (props.mode === 'edit') {
|
||||||
|
triggerEditorResize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (props.mode === 'preview') {
|
if (props.mode === 'preview') {
|
||||||
initPreviewMode()
|
initPreviewMode()
|
||||||
} else if (props.mode === 'edit') {
|
} else if (props.mode === 'edit') {
|
||||||
|
triggerEditorResize()
|
||||||
// 编辑模式由 FlowEditor 组件初始化
|
// 编辑模式由 FlowEditor 组件初始化
|
||||||
// 等待 FlowEditor 初始化完成后加载数据
|
// 等待 FlowEditor 初始化完成后加载数据
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (props.data) {
|
if (props.data) {
|
||||||
setGraphData(props.data)
|
setGraphData(props.data)
|
||||||
}
|
}
|
||||||
|
triggerEditorResize()
|
||||||
}, 500)
|
}, 500)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -311,6 +321,7 @@ onBeforeUnmount(() => {
|
|||||||
.editor-content {
|
.editor-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="toolbar">
|
<div class="toolbar" :class="{ 'toolbar--embed': props.isEmbed }">
|
||||||
<div>
|
<div>
|
||||||
<el-button icon="Upload" type="primary" @click="handleImport">{{ t('import') }}</el-button>
|
<el-button icon="Upload" type="primary" @click="handleImport">{{ t('import') }}</el-button>
|
||||||
<el-button icon="Download" type="primary" @click="handleExport">{{ t('export') }}</el-button>
|
<el-button icon="Download" type="primary" @click="handleExport">{{ t('export') }}</el-button>
|
||||||
@@ -486,6 +486,13 @@ const handleClose = (done) => {
|
|||||||
z-index: 100;
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.toolbar--embed {
|
||||||
|
position: relative;
|
||||||
|
top: auto;
|
||||||
|
left: auto;
|
||||||
|
right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.toolbar-controls {
|
.toolbar-controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -58,7 +58,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch, onMounted, onBeforeUnmount } from 'vue';
|
import { ref, watch, onMounted, onBeforeUnmount, nextTick } from 'vue';
|
||||||
import LogicFlow, { EventType } from '@logicflow/core';
|
import LogicFlow, { EventType } from '@logicflow/core';
|
||||||
import type { Position, NodeData, EdgeData, BaseNodeModel, GraphModel, GraphData } from '@logicflow/core';
|
import type { Position, NodeData, EdgeData, BaseNodeModel, GraphModel, GraphData } from '@logicflow/core';
|
||||||
import '@logicflow/core/lib/style/index.css';
|
import '@logicflow/core/lib/style/index.css';
|
||||||
@@ -116,6 +116,23 @@ const selectedNode = ref<any>(null);
|
|||||||
const copyBuffer = ref<GraphData | null>(null);
|
const copyBuffer = ref<GraphData | null>(null);
|
||||||
let nextPasteDistance = COPY_TRANSLATION;
|
let nextPasteDistance = COPY_TRANSLATION;
|
||||||
|
|
||||||
|
const resizeCanvas = () => {
|
||||||
|
const lfInstance = lf.value as any;
|
||||||
|
const container = containerRef.value;
|
||||||
|
if (!lfInstance || !container || typeof lfInstance.resize !== 'function') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const width = container.clientWidth;
|
||||||
|
const height = container.clientHeight;
|
||||||
|
if (width > 0 && height > 0) {
|
||||||
|
lfInstance.resize(width, height);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleWindowResize = () => {
|
||||||
|
resizeCanvas();
|
||||||
|
};
|
||||||
|
|
||||||
function isInputLike(event?: KeyboardEvent) {
|
function isInputLike(event?: KeyboardEvent) {
|
||||||
const target = event?.target as HTMLElement | null;
|
const target = event?.target as HTMLElement | null;
|
||||||
if (!target) return false;
|
if (!target) return false;
|
||||||
@@ -969,6 +986,11 @@ onMounted(() => {
|
|||||||
|
|
||||||
lfInstance.on('selection:selected', () => updateSelectedCount());
|
lfInstance.on('selection:selected', () => updateSelectedCount());
|
||||||
lfInstance.on('selection:drop', () => updateSelectedCount());
|
lfInstance.on('selection:drop', () => updateSelectedCount());
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
resizeCanvas();
|
||||||
|
});
|
||||||
|
window.addEventListener('resize', handleWindowResize);
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(selectionEnabled, (enabled) => {
|
watch(selectionEnabled, (enabled) => {
|
||||||
@@ -987,8 +1009,22 @@ watch(snaplineEnabled, (enabled) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.height,
|
||||||
|
() => {
|
||||||
|
nextTick(() => {
|
||||||
|
resizeCanvas();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
resizeCanvas
|
||||||
|
});
|
||||||
|
|
||||||
// 销毁 LogicFlow
|
// 销毁 LogicFlow
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
|
window.removeEventListener('resize', handleWindowResize);
|
||||||
lf.value?.destroy();
|
lf.value?.destroy();
|
||||||
lf.value = null;
|
lf.value = null;
|
||||||
destroyLogicFlowInstance();
|
destroyLogicFlowInstance();
|
||||||
|
|||||||
Reference in New Issue
Block a user