v1.0.5
1、崇文门模块初步完成 2、增加特色主题区展示页面,设置对应的导航条颜色 3、福字点击区域封装为组件
This commit is contained in:
parent
5debfabc01
commit
3dcc2df0c1
|
|
@ -1,5 +1,6 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, computed } from 'vue'
|
import { ref, onMounted, computed } from 'vue'
|
||||||
|
import FuClickArea from './FuClickArea.vue'
|
||||||
|
|
||||||
// 组件属性
|
// 组件属性
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|
@ -21,34 +22,39 @@ const emit = defineEmits(['collect-seal', 'play-drum'])
|
||||||
// 是否收集福印
|
// 是否收集福印
|
||||||
const sealCollected = ref(false)
|
const sealCollected = ref(false)
|
||||||
|
|
||||||
|
// 福字点击区域状态
|
||||||
|
const fuClickAreaVisible = ref(true)
|
||||||
|
const sq2ImageVisible = ref(false)
|
||||||
|
|
||||||
// 计算视差效果的偏移量
|
// 计算视差效果的偏移量
|
||||||
const parallaxOffset = computed(() => {
|
const parallaxOffset = computed(() => {
|
||||||
// 滚动位置的1/10作为视差偏移
|
// 滚动位置的1/10作为视差偏移
|
||||||
return props.scrollPosition * 0.1
|
return props.scrollPosition * 0.1
|
||||||
})
|
})
|
||||||
|
|
||||||
// 收集福印
|
// 点击福字区域
|
||||||
const collectSeal = () => {
|
const handleFuClick = () => {
|
||||||
if (!sealCollected.value) {
|
fuClickAreaVisible.value = false
|
||||||
sealCollected.value = true
|
sq2ImageVisible.value = true
|
||||||
emit('collect-seal')
|
emit('collect-seal')
|
||||||
showToast({
|
|
||||||
message: '恭喜获得国潮福字!',
|
|
||||||
icon: 'success',
|
|
||||||
duration: 2000
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 播放音效
|
// 打开webview页面
|
||||||
const playDrum = () => {
|
const openWebview = () => {
|
||||||
emit('play-drum')
|
uni.navigateTo({
|
||||||
collectSeal()
|
url: '/pages/webview/webview',
|
||||||
|
success: () => {
|
||||||
|
console.log('Webview opened successfully')
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error('Failed to open webview:', err)
|
||||||
showToast({
|
showToast({
|
||||||
message: '滑动探索商圈,收集国潮福字!',
|
message: '页面打开失败',
|
||||||
icon: 'info',
|
icon: 'error',
|
||||||
duration: 1500
|
duration: 1500
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 页面挂载时的初始化
|
// 页面挂载时的初始化
|
||||||
|
|
@ -69,41 +75,33 @@ onMounted(() => {
|
||||||
<img src="/static/bg/bg2.jpg" alt="崇文门商圈" class="background-image" />
|
<img src="/static/bg/bg2.jpg" alt="崇文门商圈" class="background-image" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 增强动效层 -->
|
<!-- 福字点击区域 -->
|
||||||
<div class="enhancement-layer">
|
<FuClickArea
|
||||||
<!-- 灯笼增强动效 -->
|
:visible="fuClickAreaVisible"
|
||||||
<div class="lanterns">
|
:x-range="630"
|
||||||
<div class="lantern left-lantern">🏮</div>
|
:y-range="400"
|
||||||
<div class="lantern right-lantern">🏮</div>
|
:y-start="150"
|
||||||
</div>
|
:fu-width="100"
|
||||||
|
:fu-height="100"
|
||||||
|
@click="handleFuClick"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- 福字增强动效 -->
|
<!-- sq2图片 -->
|
||||||
<div class="fu-word">福</div>
|
<img
|
||||||
|
v-if="sq2ImageVisible"
|
||||||
|
src="/static/images/sq2.png"
|
||||||
|
alt="新春祝福"
|
||||||
|
class="sq2-image"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- 点击提示 -->
|
<!-- 查看按钮 -->
|
||||||
<div class="click-indicator" :class="{ 'animate-pulse': !sealCollected }">
|
<img
|
||||||
<div class="pulse-circle"></div>
|
src="/static/images/btn_view.png"
|
||||||
</div>
|
alt="查看详情"
|
||||||
</div>
|
class="btn-view"
|
||||||
|
@click="openWebview"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- 交互区域 -->
|
|
||||||
<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>
|
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -335,6 +333,34 @@ onMounted(() => {
|
||||||
to { opacity: 1; transform: translateY(0); }
|
to { opacity: 1; transform: translateY(0); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* sq2图片 */
|
||||||
|
.sq2-image {
|
||||||
|
position: absolute;
|
||||||
|
top: 220rpx;
|
||||||
|
right: -5rpx;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
max-width: 300rpx;
|
||||||
|
z-index: 20;
|
||||||
|
animation: fadeIn 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 查看按钮 */
|
||||||
|
.btn-view {
|
||||||
|
position: absolute;
|
||||||
|
left: 156rpx;
|
||||||
|
top: 597rpx;
|
||||||
|
width: 439rpx;
|
||||||
|
height: 84rpx;
|
||||||
|
cursor: pointer;
|
||||||
|
z-index: 25;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-view:active {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
|
||||||
/* 响应式设计 */
|
/* 响应式设计 */
|
||||||
@media (max-width: 640px) {
|
@media (max-width: 640px) {
|
||||||
.fu-word {
|
.fu-word {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,168 @@
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
|
||||||
|
// 组件属性
|
||||||
|
const props = defineProps({
|
||||||
|
// 是否可见
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// x范围(总宽度)
|
||||||
|
xRange: {
|
||||||
|
type: Number,
|
||||||
|
default: 630
|
||||||
|
},
|
||||||
|
// y范围(总高度)
|
||||||
|
yRange: {
|
||||||
|
type: Number,
|
||||||
|
default: 400
|
||||||
|
},
|
||||||
|
// y起始位置
|
||||||
|
yStart: {
|
||||||
|
type: Number,
|
||||||
|
default: 350
|
||||||
|
},
|
||||||
|
// 福字宽度
|
||||||
|
fuWidth: {
|
||||||
|
type: Number,
|
||||||
|
default: 100
|
||||||
|
},
|
||||||
|
// 福字高度
|
||||||
|
fuHeight: {
|
||||||
|
type: Number,
|
||||||
|
default: 100
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 组件事件
|
||||||
|
const emit = defineEmits(['click'])
|
||||||
|
|
||||||
|
// 福字位置
|
||||||
|
const position = ref({
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
// 计算随机位置
|
||||||
|
const calculateRandomPosition = () => {
|
||||||
|
position.value = {
|
||||||
|
x: Math.random() * (props.xRange - props.fuWidth),
|
||||||
|
y: Math.random() * (props.yRange - props.fuHeight) + props.yStart
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点击处理
|
||||||
|
const handleClick = () => {
|
||||||
|
emit('click')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 组件挂载时计算位置
|
||||||
|
onMounted(() => {
|
||||||
|
calculateRandomPosition()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
v-if="visible"
|
||||||
|
class="fu-click-area"
|
||||||
|
:style="{
|
||||||
|
left: `${position.x}rpx`,
|
||||||
|
top: `${position.y}rpx`,
|
||||||
|
width: `${fuWidth}rpx`,
|
||||||
|
height: `${fuHeight}rpx`
|
||||||
|
}"
|
||||||
|
@click="handleClick"
|
||||||
|
>
|
||||||
|
<img src="/static/images/icon_fu.png" alt="福字" class="fu-icon" />
|
||||||
|
<img src="/static/images/icon_hand.png" alt="点击手势" class="hand-icon" />
|
||||||
|
<div class="click-indicator">
|
||||||
|
<div class="pulse-circle"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 福字点击区域 */
|
||||||
|
.fu-click-area {
|
||||||
|
position: absolute;
|
||||||
|
cursor: pointer;
|
||||||
|
z-index: 25;
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fu-icon {
|
||||||
|
position: absolute;
|
||||||
|
width: 94rpx;
|
||||||
|
height: 74rpx;
|
||||||
|
top: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
animation: sway 3s infinite ease-in-out;
|
||||||
|
transform-origin: center center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes sway {
|
||||||
|
0%, 100% {
|
||||||
|
transform: translateX(-50%) rotate(0deg);
|
||||||
|
}
|
||||||
|
25% {
|
||||||
|
transform: translateX(-50%) rotate(-3deg);
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
transform: translateX(-50%) rotate(3deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hand-icon {
|
||||||
|
position: absolute;
|
||||||
|
width: 38rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
top: 70%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
animation: clickUp 2s infinite ease-in-out;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes clickUp {
|
||||||
|
0%, 100% {
|
||||||
|
transform: translate(-50%, -50%) scale(1.2);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: translate(-50%, -50%) scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.click-indicator {
|
||||||
|
position: absolute;
|
||||||
|
top: 30rpx;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pulse-circle {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: rgba(255, 215, 0, 0.3);
|
||||||
|
border: 2rpx solid rgba(255, 215, 0, 0.6);
|
||||||
|
animation: pulse 2s infinite;
|
||||||
|
animation-delay: 1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
0% {
|
||||||
|
transform: scale(0.8);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(2);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, onUnmounted, computed, watch } from 'vue'
|
import { ref, onMounted, onUnmounted, computed, watch } from 'vue'
|
||||||
|
import FuClickArea from './FuClickArea.vue'
|
||||||
|
|
||||||
// 组件属性
|
// 组件属性
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|
@ -29,12 +30,6 @@ const musicPlayer = ref(null)
|
||||||
const fuClickAreaVisible = ref(true)
|
const fuClickAreaVisible = ref(true)
|
||||||
const sq1ImageVisible = ref(false)
|
const sq1ImageVisible = ref(false)
|
||||||
|
|
||||||
// 福字点击区域随机位置(限制在y>350的630*400区域内,福字大小100*100)
|
|
||||||
const fuClickPosition = ref({
|
|
||||||
x: Math.random() * 530, // x范围: 0-530rpx(总宽度630rpx - 福字宽度100rpx)
|
|
||||||
y: Math.random() * 300 + 350 // y范围: 350-650rpx(从y>350开始,总高度400rpx - 福字高度100rpx)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 场景高度
|
// 场景高度
|
||||||
const sceneHeight = ref(0)
|
const sceneHeight = ref(0)
|
||||||
|
|
||||||
|
|
@ -77,30 +72,11 @@ const parallaxOffset = computed(() => {
|
||||||
return offset
|
return offset
|
||||||
})
|
})
|
||||||
|
|
||||||
// 收集福印
|
|
||||||
const collectSeal = () => {
|
|
||||||
if (!sealCollected.value) {
|
|
||||||
sealCollected.value = true
|
|
||||||
emit('collect-seal')
|
|
||||||
showToast({
|
|
||||||
message: '恭喜获得非遗福印!',
|
|
||||||
icon: 'success',
|
|
||||||
duration: 2000
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 点击福字区域
|
// 点击福字区域
|
||||||
const handleFuClick = () => {
|
const handleFuClick = () => {
|
||||||
if (fuClickAreaVisible.value) {
|
|
||||||
fuClickAreaVisible.value = false
|
fuClickAreaVisible.value = false
|
||||||
sq1ImageVisible.value = true
|
sq1ImageVisible.value = true
|
||||||
showToast({
|
emit('collect-seal')
|
||||||
message: '恭喜获得新春祝福!',
|
|
||||||
icon: 'success',
|
|
||||||
duration: 2000
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 控制音乐播放/暂停
|
// 控制音乐播放/暂停
|
||||||
|
|
@ -207,21 +183,15 @@ onUnmounted(() => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 福字点击区域 -->
|
<!-- 福字点击区域 -->
|
||||||
<div
|
<FuClickArea
|
||||||
v-if="fuClickAreaVisible"
|
:visible="fuClickAreaVisible"
|
||||||
class="fu-click-area"
|
:x-range="630"
|
||||||
:style="{
|
:y-range="400"
|
||||||
left: `${fuClickPosition.x}rpx`,
|
:y-start="350"
|
||||||
top: `${fuClickPosition.y}rpx`
|
:fu-width="100"
|
||||||
}"
|
:fu-height="100"
|
||||||
@click="handleFuClick"
|
@click="handleFuClick"
|
||||||
>
|
/>
|
||||||
<img src="/static/images/icon_fu.png" alt="福字" class="fu-icon" />
|
|
||||||
<img src="/static/images/icon_hand.png" alt="点击手势" class="hand-icon" />
|
|
||||||
<div class="click-indicator">
|
|
||||||
<div class="pulse-circle"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- sq1图片 -->
|
<!-- sq1图片 -->
|
||||||
<img
|
<img
|
||||||
|
|
@ -480,78 +450,6 @@ onUnmounted(() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 福字点击区域 */
|
|
||||||
.fu-click-area {
|
|
||||||
position: absolute;
|
|
||||||
width: 100rpx;
|
|
||||||
height: 100rpx;
|
|
||||||
cursor: pointer;
|
|
||||||
z-index: 25;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
pointer-events: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fu-icon {
|
|
||||||
width: 94rpx;
|
|
||||||
height: 74rpx;
|
|
||||||
margin-bottom: 20rpx;
|
|
||||||
animation: sway 3s infinite ease-in-out;
|
|
||||||
transform-origin: center center;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes sway {
|
|
||||||
0%, 100% {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
25% {
|
|
||||||
transform: rotate(-3deg);
|
|
||||||
}
|
|
||||||
75% {
|
|
||||||
transform: rotate(3deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.hand-icon {
|
|
||||||
position: absolute;
|
|
||||||
width: 38rpx;
|
|
||||||
height: 40rpx;
|
|
||||||
top: 70%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
animation: clickUp 2s infinite ease-in-out;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes clickUp {
|
|
||||||
0%, 100% {
|
|
||||||
transform: translateY(0) scale(1.2);
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
transform: translateY(-10rpx) scale(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.fu-click-area .click-indicator {
|
|
||||||
position: absolute;
|
|
||||||
top: 40rpx;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
width: 60rpx;
|
|
||||||
height: 60rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fu-click-area .pulse-circle {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border-radius: 50%;
|
|
||||||
background-color: rgba(255, 215, 0, 0.3);
|
|
||||||
border: 2rpx solid rgba(255, 215, 0, 0.6);
|
|
||||||
animation: pulse 2s infinite;
|
|
||||||
animation-delay: 1s; /* hand-icon播放到50%(1秒)后再开始 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* sq1图片 */
|
/* sq1图片 */
|
||||||
.sq1-image {
|
.sq1-image {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
||||||
11
pages.json
11
pages.json
|
|
@ -7,12 +7,19 @@
|
||||||
"navigationStyle": "custom",
|
"navigationStyle": "custom",
|
||||||
"disableScroll": true
|
"disableScroll": true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/webview/webview",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "四大特色主题区",
|
||||||
|
"navigationStyle": "default"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"globalStyle": {
|
"globalStyle": {
|
||||||
"navigationBarTextStyle": "black",
|
"navigationBarTextStyle": "white",
|
||||||
"navigationBarTitleText": "2026新春H5",
|
"navigationBarTitleText": "2026新春H5",
|
||||||
"navigationBarBackgroundColor": "#F8F8F8",
|
"navigationBarBackgroundColor": "#fa4333",
|
||||||
"backgroundColor": "#F8F8F8"
|
"backgroundColor": "#F8F8F8"
|
||||||
},
|
},
|
||||||
"uniIdRouter": {}
|
"uniIdRouter": {}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
<template>
|
||||||
|
<view class="webview-container">
|
||||||
|
<web-view :src="url"></web-view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const url = ref('')
|
||||||
|
|
||||||
|
// 页面加载时获取参数
|
||||||
|
onLoad((options) => {
|
||||||
|
if (options && options.url) {
|
||||||
|
// 解码URL参数
|
||||||
|
url.value = decodeURIComponent(options.url)
|
||||||
|
console.log('Webview loading URL:', url.value)
|
||||||
|
} else {
|
||||||
|
// 默认URL
|
||||||
|
url.value = 'https://www.720yun.com/t/1dvktq8b0fl?scene_id=74010726'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// onLoad 需要从 @dcloudio/uni-app 导入
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.webview-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue