Compare commits

..

2 Commits

Author SHA1 Message Date
Wenzhe e7cc71d841 v1.2.9
1、结束页按钮间隔位置样式调整
2、首页滑动提示修改
3、bgm播放、鼓声播放、视频播放需要相互停止,保证同一时间内只有一种声音在播放
2026-02-04 21:27:25 +08:00
Wenzhe 3ed1978442 v1.2.8
1、loading页增加背景颜色,同时压缩loading_bg图片
2、点击开始按钮时,检测并进行音乐播放
3、调整视频播放关闭按钮位置
2026-02-04 14:54:29 +08:00
11 changed files with 268 additions and 72 deletions

View File

@ -23,7 +23,7 @@ const props = defineProps({
}) })
// //
const emit = defineEmits(['collect-seal']) const emit = defineEmits(['collect-seal', 'video-open', 'video-close'])
// //
const sealCollected = ref(false) const sealCollected = ref(false)
@ -67,11 +67,13 @@ const openWebview = () => {
// //
const openVideoPlayer = () => { const openVideoPlayer = () => {
showVideoPlayer.value = true showVideoPlayer.value = true
emit('video-open')
} }
// //
const closeVideoPlayer = () => { const closeVideoPlayer = () => {
showVideoPlayer.value = false showVideoPlayer.value = false
emit('video-close')
} }
// //

View File

@ -23,7 +23,7 @@ const props = defineProps({
} }
}) })
const emit = defineEmits(['collect-seal']) const emit = defineEmits(['collect-seal', 'video-open', 'video-close'])
// sq3 // sq3
const sq3ImageVisible = ref(false) const sq3ImageVisible = ref(false)
@ -478,11 +478,13 @@ const resetDuckPosition = () => {
// //
const openVideoPlayer = () => { const openVideoPlayer = () => {
showVideoPlayer.value = true showVideoPlayer.value = true
emit('video-open')
} }
// //
const closeVideoPlayer = () => { const closeVideoPlayer = () => {
showVideoPlayer.value = false showVideoPlayer.value = false
emit('video-close')
} }
// //

View File

@ -293,11 +293,14 @@ onMounted(() => {
.end-buttons { .end-buttons {
display: flex; display: flex;
gap: 20px;
justify-content: center; justify-content: center;
margin-bottom: 60px; margin-bottom: 60px;
} }
.end-buttons .function-image:not(:last-child) {
margin-right: 20px;
}
.function-btn { .function-btn {
cursor: pointer; cursor: pointer;
width: 306rpx; width: 306rpx;

View File

@ -137,6 +137,7 @@ onMounted(() => {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
z-index: 9999; z-index: 9999;
background-color: #fd4336;
} }
.loading-bg { .loading-bg {

View File

@ -25,7 +25,7 @@ const props = defineProps({
}) })
// //
const emit = defineEmits(['collect-seal']) const emit = defineEmits(['collect-seal', 'video-open', 'video-close'])
// sq3 // sq3
const sq3ImageVisible = ref(false) const sq3ImageVisible = ref(false)
@ -108,11 +108,13 @@ const closeGallery = () => {
// //
const openVideoPlayer = () => { const openVideoPlayer = () => {
showVideoPlayer.value = true showVideoPlayer.value = true
emit('video-open')
} }
// //
const closeVideoPlayer = () => { const closeVideoPlayer = () => {
showVideoPlayer.value = false showVideoPlayer.value = false
emit('video-close')
} }
// //

View File

@ -19,19 +19,28 @@ const props = defineProps({
videoUrl: { videoUrl: {
type: String, type: String,
default: '' default: ''
},
// BGM
isMusicPlaying: {
type: Boolean,
default: false
} }
}) })
// //
const emit = defineEmits(['collect-seal', 'height-changed']) const emit = defineEmits(['collect-seal', 'height-changed', 'video-open', 'video-close', 'pause-bgm', 'resume-bgm'])
// //
const sealCollected = ref(false) const sealCollected = ref(false)
// //
const isMusicPlaying = ref(false)
const musicPlayer = ref(null) const musicPlayer = ref(null)
//
const isDrumPlaying = ref(false)
const drumPlayer = ref(null)
const wasBgPlayingBeforeDrum = ref(false)
// //
const sq1ImageVisible = ref(false) const sq1ImageVisible = ref(false)
// //
@ -79,7 +88,7 @@ const parallaxOffset = computed(() => {
return offset return offset
}) })
// / // /
const toggleMusic = () => { const toggleMusic = () => {
// //
if (!sealCollected.value) { if (!sealCollected.value) {
@ -88,38 +97,48 @@ const toggleMusic = () => {
emit('collect-seal') emit('collect-seal')
} }
if (!musicPlayer.value) { if (!drumPlayer.value) {
// //
musicPlayer.value = uni.createInnerAudioContext() drumPlayer.value = uni.createInnerAudioContext()
const bgmUrl = new URL('/static/music/bgm1.mp3', import.meta.url) const drumUrl = new URL('/static/music/bgm1.mp3', import.meta.url)
musicPlayer.value.src = bgmUrl.href drumPlayer.value.src = drumUrl.href
musicPlayer.value.loop = false drumPlayer.value.loop = false
// //
musicPlayer.value.onEnded(() => { drumPlayer.value.onEnded(() => {
isMusicPlaying.value = false isDrumPlaying.value = false
// BGM
emit('resume-bgm')
}) })
// //
musicPlayer.value.onError((err) => { drumPlayer.value.onError((err) => {
console.error('音乐播放失败:', err) console.error('鼓声播放失败:', err)
isMusicPlaying.value = false isDrumPlaying.value = false
showToast({ // BGM
message: '音乐播放失败', emit('resume-bgm')
icon: 'error', uni.showToast({
title: '鼓声播放失败',
icon: 'none',
duration: 1500 duration: 1500
}) })
}) })
} }
if (isMusicPlaying.value) { if (isDrumPlaying.value) {
// //
musicPlayer.value.stop() drumPlayer.value.stop()
isMusicPlaying.value = false isDrumPlaying.value = false
// BGM
emit('resume-bgm')
} else { } else {
// // BGM
musicPlayer.value.play() wasBgPlayingBeforeDrum.value = props.isMusicPlaying
isMusicPlaying.value = true // BGM
emit('pause-bgm')
//
drumPlayer.value.play()
isDrumPlaying.value = true
} }
} }
@ -155,12 +174,23 @@ const calculateHeight = () => {
// //
const openVideoPlayer = () => { const openVideoPlayer = () => {
//
if (isDrumPlaying.value && drumPlayer.value) {
drumPlayer.value.stop()
isDrumPlaying.value = false
drumPlayer.value.destroy()
drumPlayer.value = null
// BGM
emit('resume-bgm')
}
showVideoPlayer.value = true showVideoPlayer.value = true
emit('video-open')
} }
// //
const closeVideoPlayer = () => { const closeVideoPlayer = () => {
showVideoPlayer.value = false showVideoPlayer.value = false
emit('video-close')
} }
// //
@ -170,6 +200,11 @@ onUnmounted(() => {
musicPlayer.value.destroy() musicPlayer.value.destroy()
musicPlayer.value = null musicPlayer.value = null
} }
if (drumPlayer.value) {
drumPlayer.value.stop()
drumPlayer.value.destroy()
drumPlayer.value = null
}
}) })
</script> </script>
@ -180,23 +215,14 @@ onUnmounted(() => {
<!-- 使用复制到public目录的背景图片 --> <!-- 使用复制到public目录的背景图片 -->
<img src="/static/bg/bg1.jpg" alt="前门商圈" class="background-image" /> <img src="/static/bg/bg1.jpg" alt="前门商圈" class="background-image" />
</div> </div>
<!-- 增强动效层 -->
<div class="enhancement-layer">
<!-- 灯笼增强动效 -->
<div class="lanterns">
<div class="lantern left-lantern">🏮</div>
<div class="lantern right-lantern">🏮</div>
</div>
</div>
<!-- 音乐控制按钮 --> <!-- 音乐控制按钮 -->
<div class="music-control" @click="toggleMusic"> <div class="music-control" @click="toggleMusic">
<img <img
:src="isMusicPlaying ? '/static/images/icon_music2.png' : '/static/images/icon_music1.png'" :src="isDrumPlaying ? '/static/images/icon_music2.png' : '/static/images/icon_music1.png' "
alt="音乐控制" alt="音乐控制"
class="music-icon" class="music-icon"
:class="{ 'playing': isMusicPlaying }" :class="{ 'playing': isDrumPlaying }"
/> />
</div> </div>

View File

@ -117,6 +117,10 @@ const scenes = ref([
const sceneInteractiveStates = ref(scenes.value.map(() => false)) const sceneInteractiveStates = ref(scenes.value.map(() => false))
// //
const sealCollectedStates = ref(scenes.value.map(() => false)) const sealCollectedStates = ref(scenes.value.map(() => false))
//
const isVideoPlaying = ref(false)
//
const isDrumPlaying = ref(false)
// //
const collectedItems = computed(() => { const collectedItems = computed(() => {
@ -140,6 +144,11 @@ const collectionProgress = computed(() => {
return Math.round((collected / total) * 100) return Math.round((collected / total) * 100)
}) })
// BGM
const isBgmButtonDisabled = computed(() => {
return isVideoPlaying.value || isDrumPlaying.value
})
// EndPage // EndPage
const collectedSeals = computed(() => { const collectedSeals = computed(() => {
return { return {
@ -234,6 +243,12 @@ const handleStart = () => {
hasScrolled.value = false hasScrolled.value = false
console.log('点击开始按钮hasScrolled:', hasScrolled.value) console.log('点击开始按钮hasScrolled:', hasScrolled.value)
//
if (!isMusicPlaying.value) {
console.log('背景音乐未播放,开始播放')
toggleMusic()
}
// //
initPage() initPage()
} }
@ -319,6 +334,9 @@ const initMusicPlayer = () => {
// / // /
const toggleMusic = () => { const toggleMusic = () => {
//
if (isBgmButtonDisabled.value) return
if (!audioPlayer.value) { if (!audioPlayer.value) {
initMusicPlayer() initMusicPlayer()
} }
@ -330,9 +348,27 @@ const toggleMusic = () => {
console.log('音乐已暂停') console.log('音乐已暂停')
} else { } else {
// //
audioPlayer.value.play() try {
isMusicPlaying.value = true const result = audioPlayer.value.play()
console.log('音乐已开始播放') // play()PromiseWeb
if (result && typeof result.then === 'function') {
// Web使Promise
result.then(() => {
isMusicPlaying.value = true
console.log('音乐已开始播放')
}).catch(error => {
console.error('音乐播放失败(需要用户交互):', error)
// isMusicPlayingfalse
})
} else {
//
isMusicPlaying.value = true
console.log('音乐已开始播放')
}
} catch (error) {
console.error('音乐播放失败(需要用户交互):', error)
// isMusicPlayingfalse
}
} }
} }
@ -343,10 +379,8 @@ onMounted(() => {
// //
initMusicPlayer() initMusicPlayer()
// //
setTimeout(() => { //
toggleMusic()
}, 1000)
}) })
// //
@ -577,6 +611,105 @@ const handleQianmenHeightChanged = (height) => {
console.log('当前CSS变量:', getComputedStyle(document.documentElement).getPropertyValue('--scene-height')) console.log('当前CSS变量:', getComputedStyle(document.documentElement).getPropertyValue('--scene-height'))
} }
// BGM
const wasMusicPlayingBeforeVideo = ref(false)
// BGM
const wasMusicPlayingBeforeDrum = ref(false)
//
const handleVideoOpen = () => {
//
isVideoPlaying.value = true
// BGM
wasMusicPlayingBeforeVideo.value = isMusicPlaying.value
// BGM
if (audioPlayer.value && isMusicPlaying.value) {
audioPlayer.value.pause()
isMusicPlaying.value = false
console.log('全局BGM已停止视频播放中')
}
}
//
const handleVideoClose = () => {
//
isVideoPlaying.value = false
// BGM
if (audioPlayer.value && wasMusicPlayingBeforeVideo.value && !isMusicPlaying.value) {
try {
const result = audioPlayer.value.play()
// play()PromiseWeb
if (result && typeof result.then === 'function') {
// Web使Promise
result.then(() => {
isMusicPlaying.value = true
console.log('全局BGM已恢复播放视频已关闭')
}).catch(error => {
console.error('BGM恢复播放失败需要用户交互:', error)
// isMusicPlayingfalse
})
} else {
//
isMusicPlaying.value = true
console.log('全局BGM已恢复播放视频已关闭')
}
} catch (error) {
console.error('BGM恢复播放失败需要用户交互:', error)
// isMusicPlayingfalse
}
}
}
// BGM
const pauseBgm = () => {
//
isDrumPlaying.value = true
// BGM
wasMusicPlayingBeforeDrum.value = isMusicPlaying.value
if (audioPlayer.value && isMusicPlaying.value) {
audioPlayer.value.pause()
isMusicPlaying.value = false
console.log('全局BGM已暂停鼓声播放中')
}
}
// BGM
const resumeBgm = () => {
//
isDrumPlaying.value = false
// BGM
if (audioPlayer.value && wasMusicPlayingBeforeDrum.value && !isMusicPlaying.value) {
try {
const result = audioPlayer.value.play()
// play()PromiseWeb
if (result && typeof result.then === 'function') {
// Web使Promise
result.then(() => {
isMusicPlaying.value = true
console.log('全局BGM已恢复播放鼓声已结束')
}).catch(error => {
console.error('BGM恢复播放失败需要用户交互:', error)
// isMusicPlayingfalse
})
} else {
//
isMusicPlaying.value = true
console.log('全局BGM已恢复播放鼓声已结束')
}
} catch (error) {
console.error('BGM恢复播放失败需要用户交互:', error)
// isMusicPlayingfalse
}
}
}
// 使scroll-view // 使scroll-view
// scroll-view // scroll-view
@ -591,7 +724,7 @@ onUnmounted(() => {
<!-- 音乐控制按钮 --> <!-- 音乐控制按钮 -->
<div <div
class="music-control" class="music-control"
:class="{ 'music-playing': isMusicPlaying }" :class="{ 'music-playing': isMusicPlaying, 'disabled': isBgmButtonDisabled }"
@click="toggleMusic" @click="toggleMusic"
> >
<img src="/static/images/music_on.png" alt="音乐" class="music-icon" /> <img src="/static/images/music_on.png" alt="音乐" class="music-icon" />
@ -639,6 +772,8 @@ onUnmounted(() => {
:scroll-position="scrollContainer && scrollContainer.value ? scrollContainer.value.scrollTop : 0" :scroll-position="scrollContainer && scrollContainer.value ? scrollContainer.value.scrollTop : 0"
:video-url="scenes[1].videoUrl" :video-url="scenes[1].videoUrl"
@collect-seal="collectSeal(1)" @collect-seal="collectSeal(1)"
@video-open="handleVideoOpen"
@video-close="handleVideoClose"
/> />
<!-- 隆福寺商圈 --> <!-- 隆福寺商圈 -->
@ -647,6 +782,8 @@ onUnmounted(() => {
:scroll-position="scrollContainer && scrollContainer.value ? scrollContainer.value.scrollTop : 0" :scroll-position="scrollContainer && scrollContainer.value ? scrollContainer.value.scrollTop : 0"
:video-url="scenes[2].videoUrl" :video-url="scenes[2].videoUrl"
@collect-seal="collectSeal(2)" @collect-seal="collectSeal(2)"
@video-open="handleVideoOpen"
@video-close="handleVideoClose"
/> />
<!-- 王府井商圈 --> <!-- 王府井商圈 -->
@ -655,6 +792,8 @@ onUnmounted(() => {
:scroll-position="scrollContainer?.value?.scrollTop || 0" :scroll-position="scrollContainer?.value?.scrollTop || 0"
:video-url="scenes[3].videoUrl" :video-url="scenes[3].videoUrl"
@collect-seal="collectSeal(3)" @collect-seal="collectSeal(3)"
@video-open="handleVideoOpen"
@video-close="handleVideoClose"
/> />
<!-- 崇文门商圈 --> <!-- 崇文门商圈 -->
@ -663,6 +802,8 @@ onUnmounted(() => {
:scroll-position="scrollContainer?.value?.scrollTop || 0" :scroll-position="scrollContainer?.value?.scrollTop || 0"
:video-url="scenes[4].videoUrl" :video-url="scenes[4].videoUrl"
@collect-seal="collectSeal(4)" @collect-seal="collectSeal(4)"
@video-open="handleVideoOpen"
@video-close="handleVideoClose"
/> />
<!-- 前门商圈 --> <!-- 前门商圈 -->
@ -670,8 +811,13 @@ onUnmounted(() => {
:active="activeSceneIndex === 5" :active="activeSceneIndex === 5"
:scroll-position="scrollContainer?.value?.scrollTop || 0" :scroll-position="scrollContainer?.value?.scrollTop || 0"
:video-url="scenes[5].videoUrl" :video-url="scenes[5].videoUrl"
:is-music-playing="isMusicPlaying"
@collect-seal="collectSeal(5)" @collect-seal="collectSeal(5)"
@height-changed="handleQianmenHeightChanged" @height-changed="handleQianmenHeightChanged"
@video-open="handleVideoOpen"
@video-close="handleVideoClose"
@pause-bgm="pauseBgm"
@resume-bgm="resumeBgm"
/> />
<!-- 新年文案模块 --> <!-- 新年文案模块 -->
@ -707,7 +853,7 @@ onUnmounted(() => {
<!-- 向上滑动提示 --> <!-- 向上滑动提示 -->
<div class="scroll-tip-bottom" v-if="!hasScrolled"> <div class="scroll-tip-bottom" v-if="!hasScrolled">
<img src="/static/images/icon_hand1.png" class="tip-icon" alt="滑动提示" /> <img src="/static/images/icon_hand1.png" class="tip-icon" alt="滑动提示" />
<p>滑动探索商圈</p> <p>滑动探索商圈</p>
</div> </div>
<!-- 抽奖留资弹窗 --> <!-- 抽奖留资弹窗 -->
@ -943,6 +1089,20 @@ onUnmounted(() => {
justify-content: center; justify-content: center;
z-index: 1000; z-index: 1000;
cursor: pointer; cursor: pointer;
transition: all 0.3s ease;
}
.music-control:hover:not(.disabled) {
transform: scale(1.1);
}
.music-control:active:not(.disabled) {
transform: scale(0.95);
}
.music-control.disabled {
opacity: 0.5;
cursor: not-allowed;
} }

View File

@ -63,7 +63,7 @@ const handlePlayClick = () => {
/* 鼠标悬停效果 */ /* 鼠标悬停效果 */
.video-play-button-container:hover .video-play-button-bg { .video-play-button-container:hover .video-play-button-bg {
background-color: rgba(0, 0, 0, 0.9); background-color: rgba(0, 0, 0, 0.4);
transform: scale(1.05); transform: scale(1.05);
animation: none; animation: none;
} }

View File

@ -37,9 +37,6 @@ const handleContentClick = (e) => {
<template> <template>
<div v-if="visible" class="video-modal"> <div v-if="visible" class="video-modal">
<div class="video-modal-content" @click="handleContentClick"> <div class="video-modal-content" @click="handleContentClick">
<div class="video-close-button" @click="handleClose">
<span>×</span>
</div>
<video <video
:src="videoUrl" :src="videoUrl"
class="video-player" class="video-player"
@ -48,6 +45,10 @@ const handleContentClick = (e) => {
loop loop
></video> ></video>
</div> </div>
<!-- 关闭按钮放在视频下方 -->
<div class="video-close-button" @click="handleClose">
<img src="/static/images/btn_close.png" alt="关闭" class="close-icon" />
</div>
</div> </div>
</template> </template>
@ -63,6 +64,7 @@ const handleContentClick = (e) => {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
flex-direction: column;
z-index: 999; z-index: 999;
} }
@ -70,18 +72,22 @@ const handleContentClick = (e) => {
position: relative; position: relative;
border-radius: 20rpx; border-radius: 20rpx;
overflow: hidden; overflow: hidden;
width: 720rpx;
display: flex;
flex-direction: column;
align-items: center;
}
.video-player {
width: 720rpx; width: 720rpx;
height: 405rpx; height: 405rpx;
background-color: #000;
} }
.video-close-button { .video-close-button {
position: absolute; margin-top: 30rpx;
top: 10rpx; width: 68rpx;
right: 10rpx; height: 68rpx;
width: 40rpx;
height: 40rpx;
background-color: rgba(0, 0, 0, 0.7);
border-radius: 50%;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -89,17 +95,9 @@ const handleContentClick = (e) => {
z-index: 10; z-index: 10;
} }
.video-close-button span { .close-icon {
color: white; width: 68rpx;
font-size: 30rpx; height: 68rpx;
font-weight: bold; object-fit: contain;
line-height: 30rpx;
height: 30rpx;
}
.video-player {
width: 100%;
height: 100%;
background-color: #000;
} }
</style> </style>

View File

@ -25,7 +25,7 @@ const props = defineProps({
}) })
// //
const emit = defineEmits(['collect-seal']) const emit = defineEmits(['collect-seal', 'video-open', 'video-close'])
// //
const sq3ImageVisible = ref(false) const sq3ImageVisible = ref(false)
@ -106,11 +106,13 @@ const closeGallery = () => {
// //
const openVideoPlayer = () => { const openVideoPlayer = () => {
showVideoPlayer.value = true showVideoPlayer.value = true
emit('video-open')
} }
// //
const closeVideoPlayer = () => { const closeVideoPlayer = () => {
showVideoPlayer.value = false showVideoPlayer.value = false
emit('video-close')
} }
// //

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 41 KiB