1、福印图片次序调整,bg4背景图片调整
2、调整福印收集事件,增加福印收集点击组件
3、调整结束页排版及福印显示逻辑,福印没有收集情况下,福印以灰色形式展示
This commit is contained in:
Wenzhe 2026-01-30 22:32:23 +08:00
parent 3dcc2df0c1
commit de856a1372
11 changed files with 373 additions and 240 deletions

View File

@ -17,7 +17,7 @@ const props = defineProps({
})
//
const emit = defineEmits(['collect-seal', 'play-drum'])
const emit = defineEmits(['collect-seal'])
//
const sealCollected = ref(false)
@ -79,7 +79,7 @@ onMounted(() => {
<FuClickArea
:visible="fuClickAreaVisible"
:x-range="630"
:y-range="400"
:y-range="300"
:y-start="150"
:fu-width="100"
:fu-height="100"
@ -337,7 +337,7 @@ onMounted(() => {
.sq2-image {
position: absolute;
top: 220rpx;
right: -5rpx;
right: -6rpx;
width: auto;
height: auto;
max-width: 300rpx;

View File

@ -1,5 +1,6 @@
<script setup>
import { ref, onMounted, computed } from 'vue'
import FuClickArea from './FuClickArea.vue'
//
const props = defineProps({
@ -16,39 +17,26 @@ const props = defineProps({
})
//
const emit = defineEmits(['collect-seal', 'play-drum'])
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 collectSeal = () => {
if (!sealCollected.value) {
sealCollected.value = true
emit('collect-seal')
showToast({
message: '恭喜获得团圆福筷!',
icon: 'success',
duration: 2000
})
}
}
//
const playDrum = () => {
emit('play-drum')
collectSeal()
showToast({
message: '移动烤鸭,领取团圆福筷!',
icon: 'info',
duration: 1500
})
//
const handleFuClick = () => {
fuClickAreaVisible.value = false
sq3ImageVisible.value = true
emit('collect-seal')
}
//
@ -69,41 +57,25 @@ onMounted(() => {
<img src="/static/bg/bg5.jpg" alt="东直门商圈" class="background-image" />
</div>
<!-- 增强动效层 -->
<div class="enhancement-layer">
<!-- 灯笼增强动效 -->
<div class="lanterns">
<div class="lantern left-lantern">🏮</div>
<div class="lantern right-lantern">🏮</div>
</div>
<!-- 福字增强动效 -->
<div class="fu-word"></div>
<!-- 点击提示 -->
<div class="click-indicator" :class="{ 'animate-pulse': !sealCollected }">
<div class="pulse-circle"></div>
</div>
</div>
<!-- 福字点击区域 -->
<FuClickArea
:visible="fuClickAreaVisible"
:x-range="630"
:y-range="400"
:y-start="150"
:fu-width="100"
:fu-height="100"
@click="handleFuClick"
/>
<!-- 交互区域 -->
<div class="interaction-area" @click="playDrum">
<!-- 覆盖在图片上的点击区域 -->
</div>
<!-- 烟花效果 -->
<div class="fireworks">
<div class="firework firework-1">🎆</div>
<div class="firework firework-2">🎇</div>
<div class="firework firework-3">🎆</div>
<div class="firework firework-4">🎇</div>
</div>
<!-- 福印收集标记 -->
<div v-if="sealCollected" class="seal-collected-mark">
<div class="seal-icon">🏮</div>
<div class="seal-text">已收集团圆福筷</div>
</div>
<!-- sq3图片 -->
<img
v-if="sq3ImageVisible"
src="/static/images/sq5.png"
alt="新春祝福"
class="sq-image"
/>
</section>
</template>
@ -335,6 +307,18 @@ onMounted(() => {
to { opacity: 1; transform: translateY(0); }
}
/* sq图片 */
.sq-image {
position: absolute;
top: 220rpx;
right: -6rpx;
width: auto;
height: auto;
max-width: 300rpx;
z-index: 20;
animation: fadeIn 0.5s ease;
}
/* 响应式设计 */
@media (max-width: 640px) {
.fu-word {

View File

@ -8,11 +8,83 @@
<!-- 内容层 -->
<div class="content-layer">
<div class="end-page-content">
<h1 class="end-title">🎉 {{ title }} 🎉</h1>
<div class="end-buttons">
<button class="function-btn lottery-btn" @click="handleLottery">🎁 参与抽奖</button>
<button class="function-btn couplet-btn" @click="handleCouplet"> AI春联</button>
<!-- 上方标题图片 -->
<image
src="/static/images/finish_title2.png"
mode="widthFix"
class="finish-title-top"
></image>
<!-- 福印收集展示区域 -->
<div class="seal-collection-display">
<!-- 前门 - 左上角 -->
<div class="gift-item gift-pos-1" :class="{ collected: collectedSeals.qianmen }">
<image
src="/static/images/gift1.png"
mode="widthFit"
class="gift-image"
></image>
</div>
<!-- 崇文门 - 右上角 -->
<div class="gift-item gift-pos-2" :class="{ collected: collectedSeals.chongwen }">
<image
src="/static/images/gift2.png"
mode="widthFit"
class="gift-image"
></image>
</div>
<!-- 王府井 - 左下角 -->
<div class="gift-item gift-pos-3" :class="{ collected: collectedSeals.wangfujing }">
<image
src="/static/images/gift3.png"
mode="widthFit"
class="gift-image"
></image>
</div>
<!-- 隆福寺 - 底部中间 -->
<div class="gift-item gift-pos-4" :class="{ collected: collectedSeals.longfusi }">
<image
src="/static/images/gift4.png"
mode="widthFit"
class="gift-image"
></image>
</div>
<!-- 东直门 - 右下角 -->
<div class="gift-item gift-pos-5" :class="{ collected: collectedSeals.dongzhimen }">
<image
src="/static/images/gift5.png"
mode="widthFit"
class="gift-image"
></image>
</div>
</div>
<!-- 功能按钮区域 -->
<div class="end-buttons">
<image
src="/static/images/btn_lottery.png"
mode="aspectFit"
class="function-image lottery-image"
@click="handleLottery"
></image>
<image
src="/static/images/btn_ai.png"
mode="aspectFit"
class="function-image couplet-image"
@click="handleCouplet"
></image>
</div>
<!-- 下方标题图片 -->
<image
src="/static/images/finish_title.png"
mode="widthFix"
class="finish-title-bottom"
></image>
</div>
</div>
@ -39,7 +111,17 @@ const props = defineProps({
},
totalCount: {
type: Number,
default: 1
default: 5
},
collectedSeals: {
type: Object,
default: () => ({
qianmen: false,
chongwen: false,
wangfujing: false,
longfusi: false,
dongzhimen: false
})
}
})
@ -62,10 +144,6 @@ const handleRestart = () => {
.scene-section {
position: relative;
width: 100%;
height: 100vh; /* 直接使用 100vh 确保完整一屏显示 */
min-height: 100vh; /* 确保最小高度 */
max-height: 100vh; /* 确保最大高度 */
overflow: hidden; /* 防止出现滚动条 */
}
.scene-section.active {
@ -96,16 +174,19 @@ const handleRestart = () => {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
justify-content: flex-start;
padding-top: 40px;
}
.end-page-content {
width: 100%;
max-width: 640px;
padding: 20px;
box-sizing: border-box;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
}
.end-title {
@ -153,18 +234,13 @@ const handleRestart = () => {
display: flex;
gap: 20px;
justify-content: center;
margin-bottom: 30px;
margin-bottom: 60px;
}
.function-btn {
padding: 15px 30px;
font-size: 18px;
border: none;
border-radius: 25px;
cursor: pointer;
font-weight: bold;
transition: all 0.3s ease;
min-width: 150px;
width: 306rpx;
height: 97rpx;
}
.lottery-btn {
@ -206,19 +282,118 @@ const handleRestart = () => {
background-color: #777;
}
/* 响应式设计 */
@media (max-width: 480px) {
.end-title {
font-size: 28px;
}
.end-buttons {
flex-direction: column;
align-items: center;
}
.function-btn {
width: 200px;
}
/* 福印收集展示区域 - 绝对定位布局 */
.seal-collection-display {
position: relative;
width: 100%;
height: 600rpx;
margin: 80rpx 0;
}
/* 福印基础样式 */
.gift-item {
position: absolute;
transition: all 0.3s ease;
opacity: 0.4;
filter: grayscale(100%);
}
.gift-item.collected {
opacity: 1;
filter: grayscale(0%);
transform: scale(1.05);
}
.gift-image {
width: 100%;
height: 100%;
}
/* 前门 - 左上位置 */
.gift-pos-1 {
width: 237rpx;
height: 233rpx;
left: 80rpx;
top: 0;
}
/* 崇文门 - 右上位置 */
.gift-pos-2 {
width: 344rpx;
height: 343rpx;
right: 80rpx;
top: -64rpx;
}
/* 王府井 - 左下位置 */
.gift-pos-3 {
width: 268rpx;
height: 254rpx;
left: 40rpx;
bottom: 0rpx;
}
/* 隆福寺 - 底部中间位置 */
.gift-pos-4 {
width: 153rpx;
height: 350rpx;
left: calc(50% + 20rpx);
bottom: 0;
transform: translateX(-50%);
}
.gift-pos-4.collected {
transform: translateX(-50%) scale(1.05);
}
/* 东直门 - 右下位置 */
.gift-pos-5 {
width: 238rpx;
height: 282rpx;
right: 40rpx;
bottom: 0;
}
.gift-label {
font-size: 12px;
color: #333;
margin: 0;
font-weight: bold;
}
.collection-status {
font-size: 16px;
color: #FF6B35;
font-weight: bold;
text-align: center;
margin: 0;
}
/* 标题图片 */
.finish-title-top {
width: 747rpx;
margin-top: 110rpx;
display: block;
}
.finish-title-bottom {
width: 733rpx;
margin-top: 30rpx;
display: block;
}
/* 功能按钮图片假设原图约400px*120px使用rpx单位 */
.function-image {
cursor: pointer;
transition: all 0.3s ease;
width: 306rpx;
height: 97rpx;
}
.function-image:active {
transform: scale(0.95);
}
/* 响应式相关样式已移除 - 本页面仅用于手机端 */
/* 如需调整各元素位置,请直接修改对应选择器的样式 */
</style>

View File

@ -1,5 +1,6 @@
<script setup>
import { ref, onMounted, computed } from 'vue'
import FuClickArea from './FuClickArea.vue'
//
const props = defineProps({
@ -16,39 +17,26 @@ const props = defineProps({
})
//
const emit = defineEmits(['collect-seal', 'play-drum'])
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 collectSeal = () => {
if (!sealCollected.value) {
sealCollected.value = true
emit('collect-seal')
showToast({
message: '恭喜获得文化福灯!',
icon: 'success',
duration: 2000
})
}
}
//
const playDrum = () => {
emit('play-drum')
collectSeal()
showToast({
message: '点击文创物品,点亮文化福灯!',
icon: 'info',
duration: 1500
})
//
const handleFuClick = () => {
fuClickAreaVisible.value = false
sq3ImageVisible.value = true
emit('collect-seal')
}
//
@ -69,41 +57,25 @@ onMounted(() => {
<img src="/static/bg/bg4.jpg" alt="隆福寺商圈" class="background-image" />
</div>
<!-- 增强动效层 -->
<div class="enhancement-layer">
<!-- 灯笼增强动效 -->
<div class="lanterns">
<div class="lantern left-lantern">🏮</div>
<div class="lantern right-lantern">🏮</div>
</div>
<!-- 福字增强动效 -->
<div class="fu-word"></div>
<!-- 点击提示 -->
<div class="click-indicator" :class="{ 'animate-pulse': !sealCollected }">
<div class="pulse-circle"></div>
</div>
</div>
<!-- 福字点击区域 -->
<FuClickArea
:visible="fuClickAreaVisible"
:x-range="630"
:y-range="400"
:y-start="150"
:fu-width="100"
:fu-height="100"
@click="handleFuClick"
/>
<!-- 交互区域 -->
<div class="interaction-area" @click="playDrum">
<!-- 覆盖在图片上的点击区域 -->
</div>
<!-- sq3图片 -->
<img
v-if="sq3ImageVisible"
src="/static/images/sq4.png"
alt="新春祝福"
class="sq-image"
/>
<!-- 烟花效果 -->
<div class="fireworks">
<div class="firework firework-1">🎆</div>
<div class="firework firework-2">🎇</div>
<div class="firework firework-3">🎆</div>
<div class="firework firework-4">🎇</div>
</div>
<!-- 福印收集标记 -->
<div v-if="sealCollected" class="seal-collected-mark">
<div class="seal-icon">🏮</div>
<div class="seal-text">已收集文化福灯</div>
</div>
</section>
</template>
@ -335,6 +307,18 @@ onMounted(() => {
to { opacity: 1; transform: translateY(0); }
}
/* sq图片 */
.sq-image {
position: absolute;
top: 220rpx;
right: -6rpx;
width: auto;
height: auto;
max-width: 300rpx;
z-index: 20;
animation: fadeIn 0.5s ease;
}
/* 响应式设计 */
@media (max-width: 640px) {
.fu-word {

View File

@ -17,7 +17,7 @@ const props = defineProps({
})
//
const emit = defineEmits(['collect-seal', 'play-drum', 'height-changed'])
const emit = defineEmits(['collect-seal', 'height-changed'])
//
const sealCollected = ref(false)
@ -454,7 +454,7 @@ onUnmounted(() => {
.sq1-image {
position: absolute;
top: 220rpx;
right: -5rpx;
right: -6rpx;
width: auto;
height: auto;
max-width: 300rpx;

View File

@ -63,7 +63,6 @@ const scenes = ref([
name: '东直门商圈',
description: '京城东部的交通枢纽和商业中心',
image: 'https://picsum.photos/id/1019/750/1600',
thumbnail: 'https://picsum.photos/id/1019/200/100',
interactionTip: '移动烤鸭,领取团圆福筷',
collectedItem: '团圆福筷'
},
@ -72,7 +71,6 @@ const scenes = ref([
name: '隆福寺商圈',
description: '传统文化与现代艺术融合的潮流地标',
image: 'https://picsum.photos/id/1018/750/1600',
thumbnail: 'https://picsum.photos/id/1018/200/100',
interactionTip: '点击文创物品,点亮文化福灯',
collectedItem: '文化福灯'
},
@ -81,7 +79,6 @@ const scenes = ref([
name: '王府井商圈',
description: '北京最繁华的商业中心之一',
image: 'https://picsum.photos/id/1018/750/1600',
thumbnail: 'https://picsum.photos/id/1018/200/100',
interactionTip: '双指放大,收集金袋福卡',
collectedItem: '金袋福卡'
},
@ -90,7 +87,6 @@ const scenes = ref([
name: '崇文门商圈',
description: '融合传统文化与现代商业的活力区域',
image: 'https://picsum.photos/id/1016/750/1600',
thumbnail: 'https://picsum.photos/id/1016/200/100',
interactionTip: '滑动探索商圈,收集国潮福字',
collectedItem: '国潮福字'
},
@ -137,6 +133,17 @@ const collectionProgress = computed(() => {
return Math.round((collected / total) * 100)
})
// EndPage
const collectedSeals = computed(() => {
return {
qianmen: sealCollectedStates.value[5] || false, // ( 5)
chongwen: sealCollectedStates.value[4] || false, // ( 4)
wangfujing: sealCollectedStates.value[3] || false, // ( 3)
longfusi: sealCollectedStates.value[2] || false, // ( 2)
dongzhimen: sealCollectedStates.value[1] || false // ( 1)
}
})
//
onMounted(() => {
//
@ -309,18 +316,6 @@ const scrollToScene = (index) => {
}, 1000)
}
//
const handleSceneInteraction = (index) => {
if (sceneInteractiveStates.value[index]) return
sceneInteractiveStates.value[index] = true
//
setTimeout(() => {
collectSeal(index)
}, 500)
}
//
const collectSeal = (index) => {
if (index < 1 || index >= scenes.value.length - 1) return
@ -498,6 +493,7 @@ onUnmounted(() => {
:collection-progress="collectionProgress"
:collected-count="collectedItems.length"
:total-count="scenes.length - 1"
:collected-seals="collectedSeals"
@lottery="openLotteryForm"
@couplet="openAICoupletForm"
@restart="scrollToTop"
@ -508,7 +504,6 @@ onUnmounted(() => {
:active="activeSceneIndex === 1"
:scroll-position="scrollContainer && scrollContainer.value ? scrollContainer.value.scrollTop : 0"
@collect-seal="collectSeal(1)"
@play-drum="handleSceneInteraction(1)"
/>
<!-- 隆福寺商圈 -->
@ -516,7 +511,6 @@ onUnmounted(() => {
:active="activeSceneIndex === 2"
:scroll-position="scrollContainer && scrollContainer.value ? scrollContainer.value.scrollTop : 0"
@collect-seal="collectSeal(2)"
@play-drum="handleSceneInteraction(2)"
/>
<!-- 王府井商圈 -->
@ -524,7 +518,6 @@ onUnmounted(() => {
:active="activeSceneIndex === 3"
:scroll-position="scrollContainer?.value?.scrollTop || 0"
@collect-seal="collectSeal(3)"
@play-drum="handleSceneInteraction(3)"
/>
<!-- 崇文门商圈 -->
@ -532,7 +525,6 @@ onUnmounted(() => {
:active="activeSceneIndex === 4"
:scroll-position="scrollContainer?.value?.scrollTop || 0"
@collect-seal="collectSeal(4)"
@play-drum="handleSceneInteraction(4)"
/>
<!-- 前门商圈 -->
@ -540,7 +532,6 @@ onUnmounted(() => {
:active="activeSceneIndex === 5"
:scroll-position="scrollContainer?.value?.scrollTop || 0"
@collect-seal="collectSeal(5)"
@play-drum="handleSceneInteraction(5)"
@height-changed="handleQianmenHeightChanged"
/>
@ -714,10 +705,9 @@ onUnmounted(() => {
position: relative;
width: 100%;
height: 100%;
overflow-y: auto;
overflow-y: scroll; /* 改为 scroll 确保可以滚动 */
overflow-x: hidden;
-webkit-overflow-scrolling: touch; /* 启用iOS平滑滚动 */
scrollbar-width: thin; /* Firefox滚动条样式 */
/* 使用 visibility 而不是 opacity确保完全不可见且不可交互 */
visibility: hidden;
touch-action: pan-y; /* 允许垂直方向的触摸滚动 */
@ -735,24 +725,40 @@ onUnmounted(() => {
to { opacity: 1; }
}
/* 隐藏滚动条样式 */
/* ========== 隐藏滚动条样式(所有浏览器)========== */
/* WebKit 浏览器Chrome、Safari、新版 Edge*/
.single-page-container::-webkit-scrollbar {
width: 0;
display: none; /* 隐藏滚动条 */
width: 0 !important;
height: 0 !important;
display: none !important;
}
.single-page-container::-webkit-scrollbar-track {
background: transparent; /* 轨道透明 */
background: transparent !important;
}
.single-page-container::-webkit-scrollbar-thumb {
background: transparent; /* 滑块透明 */
background: transparent !important;
}
/* Firefox 滚动条样式 */
.single-page-container::-webkit-scrollbar-corner {
background: transparent !important;
}
/* Firefox */
.single-page-container {
scrollbar-width: none; /* 隐藏滚动条 */
-ms-overflow-style: none; /* IE 和 Edge 隐藏滚动条 */
scrollbar-width: none !important;
}
/* IE 和旧版 Edge */
.single-page-container {
-ms-overflow-style: none !important;
}
/* 通用样式 */
.single-page-container {
scrollbar-color: transparent transparent !important;
}
/* 场景部分样式 */

View File

@ -1,5 +1,6 @@
<script setup>
import { ref, onMounted, computed } from 'vue'
import FuClickArea from './FuClickArea.vue'
//
const props = defineProps({
@ -16,39 +17,26 @@ const props = defineProps({
})
//
const emit = defineEmits(['collect-seal', 'play-drum'])
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 collectSeal = () => {
if (!sealCollected.value) {
sealCollected.value = true
emit('collect-seal')
showToast({
message: '恭喜获得金袋福卡!',
icon: 'success',
duration: 2000
})
}
}
//
const playDrum = () => {
emit('play-drum')
collectSeal()
showToast({
message: '双指放大,收集金袋福卡!',
icon: 'info',
duration: 1500
})
//
const handleFuClick = () => {
fuClickAreaVisible.value = false
sq3ImageVisible.value = true
emit('collect-seal')
}
//
@ -69,41 +57,25 @@ onMounted(() => {
<img src="/static/bg/bg3.jpg" alt="王府井商圈" class="background-image" />
</div>
<!-- 增强动效层 -->
<div class="enhancement-layer">
<!-- 灯笼增强动效 -->
<div class="lanterns">
<div class="lantern left-lantern">🏮</div>
<div class="lantern right-lantern">🏮</div>
</div>
<!-- 福字增强动效 -->
<div class="fu-word"></div>
<!-- 点击提示 -->
<div class="click-indicator" :class="{ 'animate-pulse': !sealCollected }">
<div class="pulse-circle"></div>
</div>
</div>
<!-- 福字点击区域 -->
<FuClickArea
:visible="fuClickAreaVisible"
:x-range="630"
:y-range="900"
:y-start="150"
:fu-width="100"
:fu-height="100"
@click="handleFuClick"
/>
<!-- 交互区域 -->
<div class="interaction-area" @click="playDrum">
<!-- 覆盖在图片上的点击区域 -->
</div>
<!-- 烟花效果 -->
<div class="fireworks">
<div class="firework firework-1">🎆</div>
<div class="firework firework-2">🎇</div>
<div class="firework firework-3">🎆</div>
<div class="firework firework-4">🎇</div>
</div>
<!-- 福印收集标记 -->
<div v-if="sealCollected" class="seal-collected-mark">
<div class="seal-icon">🏮</div>
<div class="seal-text">已收集金袋福卡</div>
</div>
<!-- sq3图片 -->
<img
v-if="sq3ImageVisible"
src="/static/images/sq3.png"
alt="新春祝福"
class="sq3-image"
/>
</section>
</template>
@ -335,6 +307,18 @@ onMounted(() => {
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;
}
/* 响应式设计 */
@media (max-width: 640px) {
.fu-word {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 392 KiB

After

Width:  |  Height:  |  Size: 448 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 107 KiB