|
|
@@ -52,6 +52,7 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
<div v-else-if="isShowMenu == 0" class="menu-show-icon" :style="iconStyle" @mousedown="onDragStart">
|
|
|
+ <!-- <div v-else-if="isShowMenu == 0" class="menu-show-icon"> -->
|
|
|
<div class="icon" :class="themeIcon == 'styleTwo' ? 'icon-2' : 'icon-1'" @click="openMenu"></div>
|
|
|
</div>
|
|
|
</template>
|
|
|
@@ -88,50 +89,68 @@
|
|
|
// const appStore = useAppStore();
|
|
|
// const themeIcon = appStore.getDarkMode;
|
|
|
const themeIcon = ref('styleTwo');
|
|
|
+ const appStore = useAppStore();
|
|
|
|
|
|
const ICON_SIZE = 60;
|
|
|
const iconTop = ref(0);
|
|
|
const isDragging = ref(false);
|
|
|
|
|
|
+ function getLayoutHeight() {
|
|
|
+ const el = document.getElementById('adaptive-container');
|
|
|
+ return el ? el.clientHeight : window.innerHeight;
|
|
|
+ }
|
|
|
+
|
|
|
+ function getScale() {
|
|
|
+ return appStore.getHeightScale || 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ function clampTop(val: number) {
|
|
|
+ return Math.max(0, Math.min(getLayoutHeight() - ICON_SIZE - 5, val));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 视口坐标 → 布局坐标
|
|
|
+ function viewportToLayout(viewportVal: number) {
|
|
|
+ return viewportVal / getScale();
|
|
|
+ }
|
|
|
+
|
|
|
const iconStyle = computed(() => {
|
|
|
+ const top = clampTop(iconTop.value);
|
|
|
if (isDragging.value) {
|
|
|
- return { left: '5px', top: iconTop.value + 'px', transition: 'none' };
|
|
|
+ return { left: '5px', top: top + 'px', transition: 'none' };
|
|
|
}
|
|
|
- return { left: '5px', top: iconTop.value + 'px', transition: 'top 0.3s ease' };
|
|
|
+ return { left: '5px', top: top + 'px', transition: 'top 0.3s ease' };
|
|
|
});
|
|
|
|
|
|
onMounted(() => {
|
|
|
- iconTop.value = document.documentElement.clientHeight - ICON_SIZE - 5;
|
|
|
+ iconTop.value = clampTop(getLayoutHeight() - ICON_SIZE - 5);
|
|
|
});
|
|
|
|
|
|
const DRAG_THRESHOLD = 5;
|
|
|
|
|
|
function onDragStart(e: MouseEvent) {
|
|
|
e.preventDefault();
|
|
|
- const startY = e.clientY;
|
|
|
const startX = e.clientX;
|
|
|
+ const startY = e.clientY;
|
|
|
const rect = (e.target as HTMLElement).closest('.menu-show-icon')!.getBoundingClientRect();
|
|
|
- const dragOffsetY = e.clientY - rect.top;
|
|
|
+ const startTop = rect.top;
|
|
|
let dragged = false;
|
|
|
|
|
|
const onMove = (ev: MouseEvent) => {
|
|
|
ev.preventDefault();
|
|
|
- if (!dragged && (Math.abs(ev.clientX - startX) > DRAG_THRESHOLD || Math.abs(ev.clientY - startY) > DRAG_THRESHOLD)) {
|
|
|
+ const deltaY = ev.clientY - startY;
|
|
|
+ const layoutTop = viewportToLayout(startTop + deltaY);
|
|
|
+ if (!dragged && (Math.abs(ev.clientX - startX) > DRAG_THRESHOLD || Math.abs(deltaY) > DRAG_THRESHOLD)) {
|
|
|
dragged = true;
|
|
|
isDragging.value = true;
|
|
|
- iconTop.value = rect.top;
|
|
|
}
|
|
|
if (dragged) {
|
|
|
- const clientH = document.documentElement.clientHeight;
|
|
|
- iconTop.value = Math.max(0, Math.min(clientH - ICON_SIZE, ev.clientY - dragOffsetY));
|
|
|
+ iconTop.value = clampTop(layoutTop);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
const onUp = (ev: MouseEvent) => {
|
|
|
if (dragged) {
|
|
|
isDragging.value = false;
|
|
|
- const clientH = document.documentElement.clientHeight;
|
|
|
- iconTop.value = Math.max(0, Math.min(clientH - ICON_SIZE, iconTop.value));
|
|
|
ev.preventDefault();
|
|
|
ev.stopPropagation();
|
|
|
}
|