防止鼠标穿透

This commit is contained in:
tianmo
2026-09-05 18:52:45 +08:00
parent 79ce3165c1
commit 0a0ab592a4
7 changed files with 77 additions and 44 deletions
+7 -1
View File
@@ -1,5 +1,10 @@
<template>
<div class="layout" :class="{ 'panel-right': store.settings.parameterPanelOnRight }">
<div
class="layout"
:class="{ 'panel-right': store.settings.parameterPanelOnRight }"
:inert="transferProgress.visible ? true : undefined"
:aria-hidden="transferProgress.visible ? 'true' : undefined"
>
<!-- 参数面板可在系统设置中切换左右位置宽度可拖 -->
<div class="parameter-panel" :style="{ width: panelW + 'px' }">
<ParticlePanel />
@@ -26,6 +31,7 @@ import Stage from './views/Stage.vue'
import ParticlePanel from './views/ParticlePanel.vue'
import Timeline from './views/Timeline.vue'
import TransferProgressOverlay from './views/TransferProgressOverlay.vue'
import { transferProgress } from './editor/transferProgress'
const store = useParticleStore()
installSystemSettingsCache(store)
+30 -3
View File
@@ -1,6 +1,21 @@
<template>
<Transition name="transfer-fade">
<div v-if="transferProgress.visible" class="transfer-overlay" role="status" aria-live="polite">
<div
v-if="transferProgress.visible"
ref="overlayElement"
class="transfer-overlay"
role="dialog"
aria-modal="true"
aria-live="polite"
tabindex="-1"
@pointerdown.stop.prevent
@pointerup.stop.prevent
@click.stop.prevent
@dblclick.stop.prevent
@contextmenu.stop.prevent
@wheel.stop.prevent
@keydown.stop.prevent
>
<div class="transfer-dialog" :class="{ failed: transferProgress.failed }">
<div class="transfer-heading">
<span>{{ transferProgress.title }}</span>
@@ -16,11 +31,24 @@
</template>
<script setup lang="ts">
import { nextTick, ref, watch } from 'vue'
import { transferProgress } from '../editor/transferProgress'
const overlayElement = ref<HTMLElement | null>(null)
watch(
() => transferProgress.visible,
async (visible) => {
if (!visible) return
await nextTick()
overlayElement.value?.focus({ preventScroll: true })
},
{ flush: 'post' },
)
</script>
<style scoped>
.transfer-overlay { position: fixed; z-index: 2000; inset: 0; display: grid; place-items: center; pointer-events: none; background: rgba(5, 8, 15, 0.26); backdrop-filter: blur(1px); }
.transfer-overlay { position: fixed; z-index: 2000; inset: 0; display: grid; place-items: center; pointer-events: auto; cursor: wait; overscroll-behavior: contain; background: rgba(5, 8, 15, 0.26); backdrop-filter: blur(1px); }
.transfer-dialog { width: min(420px, calc(100vw - 40px)); padding: 18px 20px 16px; border: 1px solid #414b66; border-radius: 10px; box-shadow: 0 18px 55px rgba(0, 0, 0, 0.46); background: #171d2b; color: #e7ebf5; }
.transfer-heading { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 12px; font-size: 14px; font-weight: 700; }
.transfer-heading strong { color: #a8a6ff; font-size: 12px; font-variant-numeric: tabular-nums; }
@@ -35,4 +63,3 @@ import { transferProgress } from '../editor/transferProgress'
.transfer-fade-enter-from, .transfer-fade-leave-to { opacity: 0; }
@keyframes transfer-slide { from { transform: translateX(-110%); } to { transform: translateX(250%); } }
</style>