修改抽奖动画

This commit is contained in:
xiaoaojiao
2025-09-17 16:38:42 +08:00
parent 427bdfc0ed
commit 1b89cc367b
4 changed files with 112 additions and 62 deletions

View File

@@ -25,22 +25,22 @@ const initGlobalAudio = () => {
globalStore.globalAudio = new Audio(faceFamily);
globalStore.globalAudio.loop = true; // 设置循环播放
globalStore.globalAudio.preload = 'auto';
// 监听音频事件
globalStore.globalAudio.addEventListener('play', () => {
isMusicOn.value = true;
});
globalStore.globalAudio.addEventListener('pause', () => {
isMusicOn.value = false;
});
globalStore.globalAudio.addEventListener('ended', () => {
isMusicOn.value = false;
});
}
audioElement.value = globalStore.globalAudio;
// 同步当前音乐状态
isMusicOn.value = !globalStore.globalAudio.paused;
};
@@ -54,21 +54,21 @@ onMounted(() => {
// 检查并播放音频
const checkAndPlayAudio = () => {
if (!audioElement.value) return;
// 如果用户曾经手动静音,则不自动播放
if (globalStore.userMutedMusic) {
console.log('用户曾经手动静音,不自动播放音乐');
isMusicOn.value = false;
return;
}
// 检查音频是否已在播放
if (!audioElement.value.paused) {
console.log('音频已在播放,跳过重复播放');
isMusicOn.value = true;
return;
}
// 只在首次访问或音乐没有被用户手动静音时才尝试自动播放
if (globalStore.isFirstVisitHomePage || !globalStore.userMutedMusic) {
const playPromise = audioElement.value.play();
@@ -79,12 +79,12 @@ const checkAndPlayAudio = () => {
globalStore.isFirstVisitHomePage = false;
console.log('自动播放成功');
})
.catch(error => {
// 自动播放被阻止
console.log('自动播放被阻止,需要用户交互:', error);
isMusicOn.value = false;
audioElement.value.pause();
});
.catch(error => {
// 自动播放被阻止
console.log('自动播放被阻止,需要用户交互:', error);
isMusicOn.value = false;
audioElement.value.pause();
});
}
} else {
// 非首次访问且用户没有手动静音,但音乐当前暂停,则保持暂停状态
@@ -97,7 +97,7 @@ const initVideo = () => {
setTimeout(() => {
if (videoElement.value) {
const video = videoElement.value;
// 移动设备视频优化设置
video.muted = true;
video.loop = true;
@@ -107,12 +107,12 @@ const initVideo = () => {
video.setAttribute('playsinline', 'true');
video.setAttribute('x5-video-player-type', 'h5');
video.setAttribute('x5-video-player-fullscreen', 'false');
// 移动设备特殊处理
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
if (isMobile) {
video.preload = 'metadata'; // 移动设备使用较小的预加载
// 尝试在用户交互后播放
const playVideo = () => {
video.play().then(() => {
@@ -123,12 +123,12 @@ const initVideo = () => {
videoError.value = true;
});
};
// 在用户点击时尝试播放视频
document.addEventListener('touchstart', playVideo, { once: true });
document.addEventListener('click', playVideo, { once: true });
}
// 按钮交互触发视频播放(用于 iOS 等严格的自动播放限制)
const buttons = document.querySelectorAll('.scene-item');
buttons.forEach(button => {
@@ -140,7 +140,7 @@ const initVideo = () => {
}
}, { once: true });
});
// 监听视频事件
video.addEventListener('loadedmetadata', () => {
console.log('视频元数据加载完成');
@@ -151,7 +151,7 @@ const initVideo = () => {
});
}
});
video.addEventListener('canplay', () => {
videoLoaded.value = true;
videoError.value = false;
@@ -165,7 +165,7 @@ const toggleMusicState = () => {
if (!audioElement.value) {
initGlobalAudio();
}
if (isMusicOn.value) {
// 当前在播放,用户点击静音
audioElement.value.pause();
@@ -181,10 +181,10 @@ const toggleMusicState = () => {
isMusicOn.value = true;
console.log('用户手动开启音乐');
})
.catch(error => {
console.log('播放失败:', error);
isMusicOn.value = false;
});
.catch(error => {
console.log('播放失败:', error);
isMusicOn.value = false;
});
}
}
};
@@ -221,9 +221,12 @@ const handleRule = () => {
globalToastEvent.emit(ToastType.SHOW_RULE)
}
const handleLottery = () => {
globalToastEvent.emit(ToastType.SHOW_LOTTERY)
if (globalStore.draw_chances <= 0) return;
if (globalStore.draw_chances <= 0) {
return weui.alert("还没有抽奖机会,快去参加活动吧")
};
globalStore.reducerDrawChances();
globalToastEvent.emit(ToastType.SHOW_LOTTERY)
}
const router = useRouter();
@@ -240,11 +243,11 @@ const myPhotoValue = route.query.myPhotoValue;
const isMyPhotoVisible = ref(false);
const isPhotoSquareVisible = ref(false);
const showMyPhoto = () => {
const showMyPhoto = () => {
isMyPhotoVisible.value = true;
isPhotoSquareVisible.value = false;
}
const showPhotoSquare=()=>{
const showPhotoSquare = () => {
isMyPhotoVisible.value = false;
isPhotoSquareVisible.value = true;
}
@@ -253,7 +256,7 @@ watch(() => myPhotoValue, async (newVal) => {
if (!newVal) {
return
}
isMyPhotoVisible.value = true;
}, { immediate: true })
@@ -326,7 +329,7 @@ watch(() => mergeId, async (newVal) => {
if (newVal) {
isPhotoSquareVisible.value = true;
}
}, {immediate: true})
}, { immediate: true })
</script>
@@ -335,24 +338,10 @@ watch(() => mergeId, async (newVal) => {
<div :show="show" class="main">
<div class="home-wrapper">
<!-- 视频背景 -->
<video
ref="videoElement"
class="background-video"
:src="backgroundVideo"
autoplay
loop
muted
playsinline
webkit-playsinline
preload="metadata"
x5-video-player-type="h5"
x5-video-player-fullscreen="false"
x5-video-orientation="portraint"
@loadstart="onVideoLoadStart"
@canplay="onVideoCanPlay"
@error="onVideoError"
@loadeddata="onVideoLoaded"
>
<video ref="videoElement" class="background-video" :src="backgroundVideo" autoplay loop muted playsinline
webkit-playsinline preload="metadata" x5-video-player-type="h5" x5-video-player-fullscreen="false"
x5-video-orientation="portraint" @loadstart="onVideoLoadStart" @canplay="onVideoCanPlay" @error="onVideoError"
@loadeddata="onVideoLoaded">
<!-- 为不支持视频的设备提供 fallback -->
<p style="display: none;">您的浏览器不支持视频播放</p>
</video>
@@ -362,17 +351,18 @@ watch(() => mergeId, async (newVal) => {
<div class="scene-item slogan">
<img src="../assets/images/slogan.webp" alt="slogan">
</div>
<!-- fallback 背景图当视频无法加载时显示 -->
<div v-if="videoError || !videoLoaded" class="fallback-background"></div>
<div class="scene-item item-1" @click="handleLottery" :class="{ 'disabled': globalStore.draw_chances <= 0 }">
<img src="../assets/images/lottery.webp" alt="抽奖">
<div class="lottery-main">
<p class="lottery-value">{{ globalStore.draw_chances }}</p>
</div>
</div>
<div class="scene-item item-2" @click="navigateSelectTemplatePage" :class="{ 'disabled': globalStore.game_chances <= 0 }">
<div class="scene-item item-2" @click="navigateSelectTemplatePage"
:class="{ 'disabled': globalStore.game_chances <= 0 }">
<img src="../assets/images/join.webp" alt="立即参与">
<div class="join-main">
<p class="join-value"><span>X</span>{{ globalStore.game_chances }}</p>
@@ -416,14 +406,17 @@ watch(() => mergeId, async (newVal) => {
width: 24vw;
left: 4vw;
}
.slogan {
top: 20vw;
width: 76vw;
}
.main {
height: 100%;
overflow-y: auto;
}
.home-wrapper {
width: 100vw;
height: 200vw;
@@ -433,7 +426,8 @@ watch(() => mergeId, async (newVal) => {
align-items: center;
position: relative;
min-height: -webkit-fill-available;
overflow: hidden; /* 防止视频溢出 */
overflow: hidden;
/* 防止视频溢出 */
}
/* 视频背景样式 */
@@ -443,9 +437,12 @@ watch(() => mergeId, async (newVal) => {
left: 0;
width: 100%;
height: 100%;
object-fit: cover; /* 保持视频比例并填满容器 */
z-index: 0; /* 置于最底层 */
pointer-events: none; /* 禁止视频交互,避免影响按钮点击 */
object-fit: cover;
/* 保持视频比例并填满容器 */
z-index: 0;
/* 置于最底层 */
pointer-events: none;
/* 禁止视频交互,避免影响按钮点击 */
}
/* fallback 背景图 */
@@ -459,8 +456,10 @@ watch(() => mergeId, async (newVal) => {
background-size: cover;
background-repeat: no-repeat;
background-position: center;
z-index: -1; /* 置于视频下方 */
z-index: -1;
/* 置于视频下方 */
}
.scene-item {
position: fixed;
cursor: pointer;
@@ -535,36 +534,42 @@ watch(() => mergeId, async (newVal) => {
right: 0;
animation-delay: 0s;
}
.item-4 {
width: 11vw;
top: 1.5%;
right: 1.5%;
animation-delay: 0s;
}
.item-5 {
width: 11vw;
top: 1.5%;
right: 1.5%;
animation-delay: 0s;
}
.item-6 {
width: 14.5vw;
top: 8%;
right: 0;
animation-delay: 0s;
}
.item-7 {
width: 14.5vw;
top: 13.5%;
right: 0;
animation-delay: 0s;
}
.item-8 {
width: 11vw;
bottom: 32%;
right: 1%;
animation-delay: 0s;
}
.item-9 {
width: 11vw;
bottom: 23%;