282 lines
5.9 KiB
Vue
282 lines
5.9 KiB
Vue
<script setup>
|
||
import { ref, onMounted, computed } from 'vue'
|
||
import VideoPlayButton from './VideoPlayButton.vue'
|
||
import VideoPlayerModal from './VideoPlayerModal.vue'
|
||
|
||
// 组件属性
|
||
const props = defineProps({
|
||
// 是否为活动状态
|
||
active: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
// 滚动位置,用于实现视差效果
|
||
scrollPosition: {
|
||
type: Number,
|
||
default: 0
|
||
},
|
||
// 视频地址
|
||
videoUrl: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
// 全局BGM播放状态
|
||
isMusicPlaying: {
|
||
type: Boolean,
|
||
default: false
|
||
}
|
||
})
|
||
|
||
// 组件事件
|
||
const emit = defineEmits(['collect-seal', 'video-open', 'video-close', 'pause-bgm', 'resume-bgm', 'webview-open', 'webview-close'])
|
||
|
||
// 是否收集福印
|
||
const sealCollected = ref(false)
|
||
|
||
// 福字点击区域状态
|
||
const sq2ImageVisible = ref(false)
|
||
// 视频播放状态
|
||
const showVideoPlayer = ref(false)
|
||
|
||
// 计算视差效果的偏移量
|
||
const parallaxOffset = computed(() => {
|
||
// 滚动位置的1/10作为视差偏移
|
||
return props.scrollPosition * 0.1
|
||
})
|
||
|
||
// 保存BGM状态
|
||
const wasBgPlayingBeforeWebview = ref(false)
|
||
|
||
// 打开webview页面
|
||
const openWebview = () => {
|
||
// 第一次点击查看按钮时收集福印
|
||
if (!sealCollected.value) {
|
||
sealCollected.value = true
|
||
sq2ImageVisible.value = true
|
||
emit('collect-seal')
|
||
}
|
||
|
||
// 保存BGM状态
|
||
wasBgPlayingBeforeWebview.value = props.isMusicPlaying
|
||
|
||
// 通知父组件webview即将打开
|
||
emit('webview-open')
|
||
|
||
// 暂停全局BGM播放
|
||
if (props.isMusicPlaying) {
|
||
emit('pause-bgm', 'webview')
|
||
}
|
||
|
||
// 标记即将打开webview
|
||
uni.setStorageSync('isOpeningWebview', true)
|
||
uni.setStorageSync('wasMusicPlayingBeforeWebview', props.isMusicPlaying)
|
||
|
||
uni.navigateTo({
|
||
url: '/pages/webview/webview',
|
||
success: () => {
|
||
console.log('Webview opened successfully')
|
||
},
|
||
fail: (err) => {
|
||
console.error('Failed to open webview:', err)
|
||
uni.showToast({
|
||
title: '页面打开失败',
|
||
icon: 'none',
|
||
duration: 1500
|
||
})
|
||
// 如果打开失败,恢复BGM状态
|
||
if (wasBgPlayingBeforeWebview.value) {
|
||
emit('resume-bgm')
|
||
}
|
||
// 通知父组件webview打开失败
|
||
emit('webview-close')
|
||
}
|
||
})
|
||
}
|
||
|
||
// 打开视频播放器
|
||
const openVideoPlayer = () => {
|
||
showVideoPlayer.value = true
|
||
emit('video-open')
|
||
}
|
||
|
||
// 关闭视频播放器
|
||
const closeVideoPlayer = () => {
|
||
showVideoPlayer.value = false
|
||
emit('video-close')
|
||
}
|
||
|
||
// 页面挂载时的初始化
|
||
onMounted(() => {
|
||
// 添加动画类,触发入场动画
|
||
const container = document.querySelector('.chongwen-scene-container')
|
||
if (container) {
|
||
container.classList.add('animate-in')
|
||
}
|
||
})
|
||
</script>
|
||
|
||
<template>
|
||
<section class="chongwen-scene-container" :class="{ 'active': active }">
|
||
<!-- 背景图片层 -->
|
||
<div class="background-layer" :style="{ transform: `translateY(${parallaxOffset}px)` }">
|
||
<!-- 使用崇文门商圈背景图片 -->
|
||
<img src="/static/bg/bg2.jpg" alt="崇文门商圈" class="background-image" />
|
||
</div>
|
||
|
||
|
||
|
||
<!-- sq2图片 -->
|
||
<img
|
||
v-if="sq2ImageVisible"
|
||
src="/static/images/sq2.png"
|
||
alt="新春祝福"
|
||
class="sq2-image"
|
||
/>
|
||
|
||
<!-- 查看按钮 -->
|
||
<img
|
||
src="/static/images/btn_view.png"
|
||
alt="查看详情"
|
||
class="btn-view"
|
||
@click="openWebview"
|
||
/>
|
||
|
||
<!-- 热点点击区域 -->
|
||
<div class="hotspot-area">
|
||
<div class="pulse-indicator">
|
||
<div class="pulse-circle"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 视频播放按钮 -->
|
||
<VideoPlayButton @play="openVideoPlayer" />
|
||
|
||
<!-- 视频播放器弹窗 -->
|
||
<VideoPlayerModal
|
||
:video-url="props.videoUrl"
|
||
:visible="showVideoPlayer"
|
||
@close="closeVideoPlayer"
|
||
/>
|
||
|
||
|
||
</section>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.chongwen-scene-container {
|
||
position: relative;
|
||
width: 100%;
|
||
height: auto; /* 高度由内容决定 */
|
||
overflow: hidden;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
background-color: #ff6b35;
|
||
}
|
||
|
||
/* 背景图片层 */
|
||
.background-layer {
|
||
position: relative;
|
||
width: 100%;
|
||
transition: transform 0.1s ease;
|
||
/* 背景图片决定容器高度 */
|
||
height: auto;
|
||
}
|
||
|
||
.background-image {
|
||
width: 100%;
|
||
height: auto;
|
||
display: block;
|
||
/* 确保图片完整显示,决定容器高度 */
|
||
object-fit: contain;
|
||
}
|
||
|
||
/* 入场动画 */
|
||
.chongwen-scene-container.animate-in {
|
||
animation: sceneFadeIn 1s ease-out;
|
||
}
|
||
|
||
@keyframes sceneFadeIn {
|
||
from { opacity: 0; transform: translateY(50px); }
|
||
to { opacity: 1; transform: translateY(0); }
|
||
}
|
||
|
||
/* sq2图片 */
|
||
.sq2-image {
|
||
position: absolute;
|
||
top: 200rpx;
|
||
right: -6rpx;
|
||
width: auto;
|
||
height: auto;
|
||
max-width: 300rpx;
|
||
z-index: 20;
|
||
animation: fadeIn 0.5s ease;
|
||
}
|
||
|
||
/* 查看按钮 */
|
||
.btn-view {
|
||
position: absolute;
|
||
left: 156rpx;
|
||
top: 597rpx;
|
||
width: 479rpx;
|
||
height: 84rpx;
|
||
cursor: pointer;
|
||
z-index: 26;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.btn-view:active {
|
||
transform: scale(0.95);
|
||
}
|
||
|
||
/* 动画效果 */
|
||
@keyframes fadeIn {
|
||
from { opacity: 0; transform: translateY(-20px); }
|
||
to { opacity: 1; transform: translateY(0); }
|
||
}
|
||
|
||
/* 热点点击区域 */
|
||
.hotspot-area {
|
||
position: absolute;
|
||
left: 321rpx;
|
||
top: 570rpx;
|
||
width: 150rpx;
|
||
height: 150rpx;
|
||
cursor: pointer;
|
||
z-index: 25;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
/* 脉冲动效 */
|
||
.pulse-indicator {
|
||
position: relative;
|
||
width: 100rpx;
|
||
height: 100rpx;
|
||
}
|
||
|
||
.pulse-circle {
|
||
position: absolute;
|
||
top: 50%;
|
||
left: 50%;
|
||
transform: translate(-50%, -50%);
|
||
width: 100%;
|
||
height: 100%;
|
||
border-radius: 50%;
|
||
background-color: rgba(255, 215, 0, 0.4);
|
||
border: 3rpx solid rgba(255, 215, 0, 0.8);
|
||
animation: pulse 1.5s infinite;
|
||
}
|
||
|
||
@keyframes pulse {
|
||
0% {
|
||
transform: translate(-50%, -50%) scale(0.8);
|
||
opacity: 0.8;
|
||
}
|
||
100% {
|
||
transform: translate(-50%, -50%) scale(2);
|
||
opacity: 0;
|
||
}
|
||
}
|
||
</style> |