feat: auto-hide top-bar and cursor after 3s idle, restore on mouse move
This commit is contained in:
41
src/App.vue
41
src/App.vue
@@ -43,6 +43,8 @@ const showIntro = ref(false)
|
||||
const introWatched = ref(false)
|
||||
const introVideoRef = ref<HTMLVideoElement | null>(null)
|
||||
const menuVideoRef = ref<HTMLVideoElement | null>(null)
|
||||
const showTopBar = ref(true)
|
||||
let hideTopBarTimer: ReturnType<typeof setTimeout> | null = null
|
||||
|
||||
const { loadGame, start, resumeAutoSave, makeChoice, clickHotspot, startChapter,
|
||||
skipScene, setSpeed, getSpeed, isSceneWatched,
|
||||
@@ -113,6 +115,15 @@ watch([() => store.qteTimeRelax, () => store.qteSingleKey], () => {
|
||||
applyQteParams()
|
||||
})
|
||||
|
||||
watch(
|
||||
() => [
|
||||
showPauseMenu.value, showMenu.value, showChapterSelect.value,
|
||||
showAchievements.value, showEndingGallery.value, recapChapterId.value,
|
||||
paused.value, store.showSettings,
|
||||
],
|
||||
() => { resetTopBarTimer() },
|
||||
)
|
||||
|
||||
function onVideoReady(elA: HTMLVideoElement, elB: HTMLVideoElement) {
|
||||
videoElA.value = elA
|
||||
videoElB.value = elB
|
||||
@@ -243,6 +254,21 @@ function onQuitToMenu() {
|
||||
|
||||
function onGlobalMouseMove() {
|
||||
store.setInputMode('mouse')
|
||||
resetTopBarTimer()
|
||||
}
|
||||
|
||||
function anyOverlayOpen(): boolean {
|
||||
return showPauseMenu.value || showMenu.value || showChapterSelect.value
|
||||
|| showAchievements.value || showEndingGallery.value || !!recapChapterId.value
|
||||
|| paused.value || store.showSettings
|
||||
}
|
||||
|
||||
function resetTopBarTimer() {
|
||||
showTopBar.value = true
|
||||
if (hideTopBarTimer) clearTimeout(hideTopBarTimer)
|
||||
if (!anyOverlayOpen()) {
|
||||
hideTopBarTimer = setTimeout(() => { showTopBar.value = false }, 3000)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
@@ -253,6 +279,7 @@ onMounted(() => {
|
||||
onUnmounted(() => {
|
||||
document.removeEventListener('keydown', onGlobalKeydown)
|
||||
document.removeEventListener('mousemove', onGlobalMouseMove)
|
||||
if (hideTopBarTimer) clearTimeout(hideTopBarTimer)
|
||||
})
|
||||
|
||||
init()
|
||||
@@ -271,7 +298,7 @@ init()
|
||||
<video ref="menuVideoRef" :src="store.menuVideo" class="menu-bg-video" autoplay loop muted></video>
|
||||
</div>
|
||||
|
||||
<div class="game-screen" v-show="started && !store.gameEnded">
|
||||
<div class="game-screen" :class="{ idle: !showTopBar }" v-show="started && !store.gameEnded">
|
||||
<GamePlayer v-show="!store.isImageScene" @video-ready="onVideoReady" />
|
||||
<HotspotLayer
|
||||
:hotspots="store.hotspots"
|
||||
@@ -305,7 +332,7 @@ init()
|
||||
<Transition name="prompt-toast">
|
||||
<div v-if="showPromptToast" class="prompt-toast">{{ promptToast }}</div>
|
||||
</Transition>
|
||||
<div v-if="started && !store.gameEnded" class="top-bar">
|
||||
<div v-if="started && !store.gameEnded" class="top-bar" :class="{ hidden: !showTopBar }">
|
||||
<PlaybackBar
|
||||
:can-skip="canSkip"
|
||||
:current-speed="currentSpeed"
|
||||
@@ -438,6 +465,16 @@ html, body {
|
||||
z-index: 20;
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.top-bar.hidden {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.game-screen.idle {
|
||||
cursor: none;
|
||||
}
|
||||
|
||||
.top-btn {
|
||||
|
||||
Reference in New Issue
Block a user