feat: 增强上下文菜单位置计算逻辑,添加视口边界检测,确保菜单和子菜单不超出可视区域

This commit is contained in:
xudan 2025-09-08 14:31:07 +08:00
parent 1c41c73cd2
commit 6599216e38
2 changed files with 73 additions and 9 deletions

View File

@ -30,12 +30,13 @@
</template>
<script setup lang="ts">
import { computed, ref, watch, nextTick } from 'vue';
import StorageMenu from './storage-menu.vue';
import RobotMenu from './robot-menu.vue';
import DefaultMenu from './default-menu.vue';
import { computed, nextTick,ref, watch } from 'vue';
import type { StorageLocationInfo } from '../../services/context-menu';
import type { RobotInfo } from '../../services/context-menu';
import DefaultMenu from './default-menu.vue';
import RobotMenu from './robot-menu.vue';
import StorageMenu from './storage-menu.vue';
interface Props {
visible: boolean;
@ -80,9 +81,40 @@ watch(mainMenuRef, async (newRef) => {
//
const menuStyle = computed(() => {
//
const menuWidth = mainMenuWidth.value || 200;
const menuHeight = 300; //
//
const viewportWidth = window.innerWidth;
const viewportHeight = window.innerHeight;
let left = props.x;
let top = props.y;
//
if (left + menuWidth > viewportWidth) {
left = viewportWidth - menuWidth - 10; // 10px
}
//
if (top + menuHeight > viewportHeight) {
top = viewportHeight - menuHeight - 10; // 10px
}
//
if (top < 0) {
top = 10; // 10px
}
//
if (left < 0) {
left = 10; // 10px
}
const style = {
left: `${props.x}px`,
top: `${props.y}px`,
left: `${left}px`,
top: `${top}px`,
};
return style;
});

View File

@ -138,11 +138,43 @@ const subMenuStyle = computed(() => {
const menuItemHeight = 60; //
const headerHeight = 40; //
const itemIndex = props.storageLocations.findIndex(loc => loc.id === showSubMenu.value);
const offsetY = headerHeight + (itemIndex * menuItemHeight);
const offsetY = headerHeight + (itemIndex * menuItemHeight) - 10; // 10px
//
const subMenuWidth = 180; //
const subMenuHeight = 300; //
//
let left = props.menuX + props.mainMenuWidth;
let top = props.menuY + offsetY;
//
const viewportWidth = window.innerWidth;
const viewportHeight = window.innerHeight;
//
if (left + subMenuWidth > viewportWidth) {
left = props.menuX - subMenuWidth; //
}
//
if (top + subMenuHeight > viewportHeight) {
top = viewportHeight - subMenuHeight - 50; // 10px
}
//
if (top < 0) {
top = 10; // 10px
}
//
if (left < 0) {
left = 10; // 10px
}
const style = {
left: `${props.menuX + props.mainMenuWidth}px`, //
top: `${props.menuY + offsetY}px`, //
left: `${left}px`,
top: `${top}px`,
};
return style;
});