Enhance audio and UI interactions for improved user experience
- Added a prebuild script in package.json to copy audio assets for smoother audio playback. - Updated App.vue to ensure the router is ready before displaying content, addressing issues with hard refreshes. - Introduced a "Tap to start" feature in SplashScreen.vue to comply with browser autoplay policies for audio. - Enhanced playLoopStart function in useLoginSounds.ts to utilize the Web Audio API for better audio control. - Removed unnecessary redirect in router index.ts for cleaner routing logic. - Improved Dashboard.vue and Login.vue styles for better visual hierarchy and user engagement during transitions.
This commit is contained in:
@@ -96,9 +96,20 @@
|
||||
</div>
|
||||
</Transition>
|
||||
|
||||
<!-- Tap to start - required for audio (browser autoplay policy) -->
|
||||
<div
|
||||
v-if="showTapToStart"
|
||||
class="absolute inset-0 z-[100] flex items-center justify-center bg-black/40 cursor-pointer"
|
||||
@click="handleTapToStart"
|
||||
>
|
||||
<p class="font-mono text-white/90 text-lg sm:text-xl px-6 py-4 rounded-lg border border-white/20 bg-black/30 backdrop-blur-sm">
|
||||
Tap to start
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Skip Button -->
|
||||
<button
|
||||
v-if="!alienIntroComplete"
|
||||
v-if="!alienIntroComplete && !showTapToStart"
|
||||
@click="handleSkipClick"
|
||||
class="absolute bottom-8 right-8 z-20 bg-black/60 border border-white/30 text-white/70 font-mono text-xs px-4 py-2 rounded backdrop-blur-[10px] hover:bg-black/80 hover:text-white/90 hover:border-white/50 hover:-translate-y-0.5 active:translate-y-0 transition-all duration-300"
|
||||
>
|
||||
@@ -126,6 +137,7 @@ const MS_PER_CHAR = 55
|
||||
const BLINK_AFTER_TYPING = 1500
|
||||
|
||||
const showSplash = ref(true)
|
||||
const showTapToStart = ref(true)
|
||||
const backgroundOpacity = ref(0)
|
||||
const alienIntroComplete = ref(false)
|
||||
const fadeAlienIntro = ref(false)
|
||||
@@ -213,6 +225,13 @@ watch([showWelcome, showLogo], ([welcome, logo]) => {
|
||||
// Check if user has seen intro
|
||||
const seenIntro = localStorage.getItem('neode_intro_seen') === '1'
|
||||
|
||||
function handleTapToStart() {
|
||||
if (!showTapToStart.value) return
|
||||
resumeAudioContext()
|
||||
showTapToStart.value = false
|
||||
startAlienIntro()
|
||||
}
|
||||
|
||||
function handleSkipClick() {
|
||||
resumeAudioContext()
|
||||
skipIntro()
|
||||
@@ -383,17 +402,8 @@ onMounted(() => {
|
||||
showSplash.value = false
|
||||
document.body.classList.add('splash-complete')
|
||||
emit('complete')
|
||||
} else {
|
||||
startAlienIntro()
|
||||
// Unlock audio on first user interaction (required for autoplay in most browsers)
|
||||
const unlock = () => {
|
||||
resumeAudioContext()
|
||||
document.removeEventListener('click', unlock)
|
||||
document.removeEventListener('touchstart', unlock)
|
||||
}
|
||||
document.addEventListener('click', unlock, { once: true })
|
||||
document.addEventListener('touchstart', unlock, { once: true })
|
||||
}
|
||||
// Typing starts only after user taps "Tap to start" (required for loop-start + music)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
|
||||
Reference in New Issue
Block a user