205 lines
4.3 KiB
Vue
205 lines
4.3 KiB
Vue
<template>
|
||
<view v-if="visible" class="splash-screen" :class="{ 'fade-out': fadingOut }">
|
||
<view class="splash-content">
|
||
<view class="logo-wrapper">
|
||
<image class="logo-img" :src="logoUrl" mode="aspectFit" />
|
||
</view>
|
||
<view class="slogan-wrapper">
|
||
<text class="slogan-text">{{ sloganText }}</text>
|
||
</view>
|
||
<view class="loading-dots">
|
||
<view class="dot"></view>
|
||
<view class="dot"></view>
|
||
<view class="dot"></view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, onMounted } from 'vue'
|
||
|
||
const visible = ref(false)
|
||
const fadingOut = ref(false)
|
||
const sloganText = ref('没有套路的真盲盒,就在柯大鸭')
|
||
const logoUrl = ref('/static/logo.png')
|
||
|
||
onMounted(() => {
|
||
// 获取今天的日期字符串(YYYY-MM-DD格式)
|
||
const today = new Date()
|
||
const dateStr = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`
|
||
|
||
// 获取所有日期的显示记录(JSON对象)
|
||
const splashKey = 'splash_count'
|
||
let splashData = uni.getStorageSync(splashKey)
|
||
|
||
// 如果缓存不存在或格式错误,初始化为空对象
|
||
if (!splashData || typeof splashData !== 'object') {
|
||
splashData = {}
|
||
}
|
||
|
||
// 清理不是今天的缓存,只保留今天的记录
|
||
const cleanedSplashData = {}
|
||
if (splashData[dateStr]) {
|
||
cleanedSplashData[dateStr] = splashData[dateStr]
|
||
}
|
||
splashData = cleanedSplashData
|
||
|
||
// 获取今天的显示次数
|
||
const todayCount = splashData[dateStr] || 0
|
||
|
||
// 每天前10次启动显示开屏动画
|
||
if (todayCount < 10) {
|
||
// 显示开屏动画
|
||
visible.value = true
|
||
|
||
// 更新今天的显示次数
|
||
splashData[dateStr] = todayCount + 1
|
||
uni.setStorageSync(splashKey, splashData)
|
||
|
||
// 停留5秒后开始淡出动画
|
||
setTimeout(() => {
|
||
fadingOut.value = true
|
||
// 淡出动画持续0.6秒,然后隐藏组件
|
||
setTimeout(() => {
|
||
visible.value = false
|
||
}, 600)
|
||
}, 5000)
|
||
}
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.splash-screen {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
z-index: 9999;
|
||
background: linear-gradient(135deg, #FF6B00 0%, #FF9500 100%);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
transition: opacity 0.6s ease-out, visibility 0.6s ease-out;
|
||
|
||
&.fade-out {
|
||
opacity: 0;
|
||
visibility: hidden;
|
||
}
|
||
}
|
||
|
||
.splash-content {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 0 60rpx;
|
||
animation: splashContentIn 0.8s cubic-bezier(0.2, 0.8, 0.2, 1);
|
||
}
|
||
|
||
@keyframes splashContentIn {
|
||
from {
|
||
opacity: 0;
|
||
transform: scale(0.8) translateY(40rpx);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: scale(1) translateY(0);
|
||
}
|
||
}
|
||
|
||
.logo-wrapper {
|
||
margin-bottom: 60rpx;
|
||
animation: logoFloat 2s ease-in-out infinite;
|
||
|
||
.logo-img {
|
||
width: 200rpx;
|
||
height: 200rpx;
|
||
border-radius: 40rpx;
|
||
background: rgba(255, 255, 255, 0.95);
|
||
box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.2);
|
||
}
|
||
}
|
||
|
||
@keyframes logoFloat {
|
||
0%, 100% {
|
||
transform: translateY(0);
|
||
}
|
||
50% {
|
||
transform: translateY(-15rpx);
|
||
}
|
||
}
|
||
|
||
.slogan-wrapper {
|
||
margin-bottom: 80rpx;
|
||
text-align: center;
|
||
|
||
.slogan-text {
|
||
font-size: 44rpx;
|
||
font-weight: 900;
|
||
color: #ffffff;
|
||
letter-spacing: 2rpx;
|
||
line-height: 1.5;
|
||
text-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);
|
||
animation: sloganFadeIn 1s ease-out 0.3s both;
|
||
}
|
||
}
|
||
|
||
@keyframes sloganFadeIn {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(20rpx);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
.loading-dots {
|
||
display: flex;
|
||
gap: 16rpx;
|
||
animation: dotsFadeIn 0.6s ease-out 0.6s both;
|
||
|
||
.dot {
|
||
width: 16rpx;
|
||
height: 16rpx;
|
||
border-radius: 50%;
|
||
background: rgba(255, 255, 255, 0.9);
|
||
box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.1);
|
||
animation: dotBounce 1.4s ease-in-out infinite;
|
||
|
||
&:nth-child(1) {
|
||
animation-delay: 0s;
|
||
}
|
||
&:nth-child(2) {
|
||
animation-delay: 0.2s;
|
||
}
|
||
&:nth-child(3) {
|
||
animation-delay: 0.4s;
|
||
}
|
||
}
|
||
}
|
||
|
||
@keyframes dotsFadeIn {
|
||
from {
|
||
opacity: 0;
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
}
|
||
}
|
||
|
||
@keyframes dotBounce {
|
||
0%, 80%, 100% {
|
||
transform: scale(0.6);
|
||
opacity: 0.5;
|
||
}
|
||
40% {
|
||
transform: scale(1);
|
||
opacity: 1;
|
||
}
|
||
}
|
||
</style>
|