qs_xinchun2026_h5/components/WangfujingScene.vue

433 lines
8.1 KiB
Vue

<script setup>
import { ref, onMounted, computed } from 'vue'
import FuClickArea from './FuClickArea.vue'
// 组件属性
const props = defineProps({
// 是否为活动状态
active: {
type: Boolean,
default: false
},
// 滚动位置,用于实现视差效果
scrollPosition: {
type: Number,
default: 0
}
})
// 组件事件
const emit = defineEmits(['collect-seal'])
// 是否收集福印
const sealCollected = ref(false)
// 福字点击区域状态
const fuClickAreaVisible = ref(true)
const sq3ImageVisible = ref(false)
// 计算视差效果的偏移量
const parallaxOffset = computed(() => {
// 滚动位置的1/10作为视差偏移
return props.scrollPosition * 0.1
})
// 点击福字区域
const handleFuClick = () => {
fuClickAreaVisible.value = false
sq3ImageVisible.value = true
emit('collect-seal')
}
// 图片浏览数据
const images = [
{ src: '/static/wfj/img1.png', title: '' },
{ src: '/static/wfj/img2.png', title: '' },
{ src: '/static/wfj/img3.png', title: '' },
{ src: '/static/wfj/img4.png', title: '' }
]
const currentImageIndex = ref(0)
// 切换图片
const prevImage = () => {
currentImageIndex.value = (currentImageIndex.value - 1 + images.length) % images.length
}
const nextImage = () => {
currentImageIndex.value = (currentImageIndex.value + 1) % images.length
}
// 页面挂载时的初始化
onMounted(() => {
// 添加动画类,触发入场动画
const container = document.querySelector('.wangfujing-scene-container')
if (container) {
container.classList.add('animate-in')
}
})
</script>
<template>
<section class="wangfujing-scene-container" :class="{ 'active': active }">
<!-- 背景图片层 -->
<div class="background-layer" :style="{ transform: `translateY(${parallaxOffset}px)` }">
<!-- 使用王府井商圈背景图片 -->
<img src="/static/bg/bg3.jpg" alt="王府井商圈" class="background-image" />
</div>
<!-- 福字点击区域 -->
<FuClickArea
:visible="fuClickAreaVisible"
:x-range="630"
:y-range="900"
:y-start="150"
:fu-width="100"
:fu-height="100"
@click="handleFuClick"
/>
<!-- sq3图片 -->
<img
v-if="sq3ImageVisible"
src="/static/images/sq3.png"
alt="新春祝福"
class="sq3-image"
/>
<!-- 图片浏览组件 -->
<div class="image-gallery">
<div class="gallery-image-wrapper">
<div class="nav-btn prev-btn" @click="prevImage">
<img src="/static/images/btn_prev.png" alt="上一张" class="nav-icon" />
</div>
<img :src="images[currentImageIndex].src" :alt="images[currentImageIndex].title" mode="widthFit" class="gallery-image" />
<div class="nav-btn next-btn" @click="nextImage">
<img src="/static/images/btn_next.png" alt="下一张" class="nav-icon" />
</div>
</div>
</div>
</section>
</template>
<style scoped>
.wangfujing-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;
}
/* 增强动效层 */
.enhancement-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 10;
}
/* 灯笼增强动效 */
.lanterns {
position: absolute;
top: 15%;
width: 100%;
display: flex;
justify-content: space-between;
padding: 0 30px;
box-sizing: border-box;
}
.lantern {
font-size: 2.5rem;
animation: swing 3s infinite ease-in-out;
opacity: 0.9;
filter: drop-shadow(0 0 15px rgba(255, 215, 0, 0.8));
color: #ffd700;
}
.left-lantern {
animation-delay: 0s;
}
.right-lantern {
animation-delay: 1.5s;
}
@keyframes swing {
0%, 100% { transform: rotate(-10deg); }
50% { transform: rotate(10deg); }
}
/* 福字增强动效 */
.fu-word {
position: absolute;
top: 30%;
left: 65%;
transform: translateX(-50%) rotate(15deg);
font-size: 2rem;
color: #ffd700;
text-shadow: 2px 2px 10px rgba(255, 215, 0, 0.9);
animation: float 4s infinite ease-in-out;
}
@keyframes float {
0%, 100% { transform: translateX(-50%) rotate(15deg) translateY(0); }
50% { transform: translateX(-50%) rotate(15deg) translateY(-15px); }
}
/* 点击指示器 */
.click-indicator {
position: absolute;
top: 55%;
left: 75%;
transform: translate(-50%, -50%);
width: 60px;
height: 60px;
pointer-events: none;
}
.pulse-circle {
width: 100%;
height: 100%;
border-radius: 50%;
background-color: rgba(255, 215, 0, 0.3);
border: 2px solid rgba(255, 215, 0, 0.6);
animation: pulse 2s infinite;
}
@keyframes pulse {
0% {
transform: scale(0.8);
opacity: 0.8;
}
100% {
transform: scale(2);
opacity: 0;
}
}
.click-indicator.animate-pulse {
display: block;
}
/* 交互区域 */
.interaction-area {
position: absolute;
top: 55%;
right: 15%;
width: 120px;
height: 100px;
cursor: pointer;
z-index: 20;
}
/* 响应式调整交互区域位置 */
@media (max-width: 640px) {
.interaction-area {
top: 52%;
right: 10%;
width: 100px;
height: 80px;
}
}
/* 烟花效果 */
.fireworks {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 20;
}
.firework {
position: absolute;
font-size: 2rem;
opacity: 0;
animation: firework 3s infinite;
}
.firework-1 {
top: 10%;
left: 20%;
animation-delay: 0s;
}
.firework-2 {
top: 15%;
right: 25%;
animation-delay: 1s;
}
.firework-3 {
top: 8%;
right: 15%;
animation-delay: 2s;
}
.firework-4 {
top: 12%;
left: 25%;
animation-delay: 3s;
}
@keyframes firework {
0%, 100% { opacity: 0; transform: scale(0); }
50% { opacity: 1; transform: scale(1.5); }
}
/* 福印收集标记 */
.seal-collected-mark {
position: absolute;
top: 20px;
right: 20px;
background-color: rgba(255, 107, 53, 0.9);
color: #fff;
padding: 10px 15px;
border-radius: 20px;
font-size: 14px;
display: flex;
align-items: center;
gap: 5px;
animation: fadeIn 0.5s ease;
z-index: 30;
}
.seal-icon {
font-size: 20px;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(-20px); }
to { opacity: 1; transform: translateY(0); }
}
/* 入场动画 */
.wangfujing-scene-container.animate-in {
animation: sceneFadeIn 1s ease-out;
}
@keyframes sceneFadeIn {
from { opacity: 0; transform: translateY(50px); }
to { opacity: 1; transform: translateY(0); }
}
/* sq3图片 */
.sq3-image {
position: absolute;
top: 220rpx;
right: -6rpx;
width: auto;
height: auto;
max-width: 300rpx;
z-index: 20;
animation: fadeIn 0.5s ease;
}
/* 图片浏览组件 */
.image-gallery {
position: absolute;
left: 50%;
top: 1400rpx;
transform: translateX(-50%);
width: 653rpx;
height: 453rpx;
background-image: url('/static/wfj/gallery-bg.png');
background-size: 653rpx 453rpx;
background-repeat: no-repeat;
background-position: center;
border-radius: 20rpx;
padding: 20rpx;
box-sizing: border-box;
z-index: 30;
overflow: hidden;
}
/* 上方图片区域 */
.gallery-image-wrapper {
position: relative;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: 20rpx;
box-sizing: border-box;
}
.gallery-image {
width: 613rpx;
object-fit: cover;
border-radius: 12rpx;
display: block;
}
.nav-btn {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
z-index: 10;
}
.prev-btn {
left: -18rpx;
}
.next-btn {
right: -18rpx;
}
.nav-icon {
width: 100%;
height: 100%;
object-fit: contain;
}
/* 响应式设计 */
@media (max-width: 640px) {
.fu-word {
font-size: 1.5rem;
}
.lantern {
font-size: 2rem;
}
.interaction-area {
width: 100px;
height: 80px;
}
}
</style>