Splash.vue 5.83 KB
<template>
  <div class="splash-container" :class="{ 'fade-out': isExiting }">
    <!-- 背景图片 -->
    <div class="background-image"></div>
    
    <!-- 黑色半透明蒙板 -->
    <div class="overlay"></div>
    
    <!-- 初始加载指示器 - 水滴波纹效果 -->
    <div class="initial-loader">
      <div class="water-drop"></div>
      <div class="ripple ripple-1"></div>
      <div class="ripple ripple-2"></div>
      <div class="ripple ripple-3"></div>
      <div class="ripple ripple-4"></div>
    </div>
    
    <!-- 内容层 -->
    <div class="splash-content">
      <!-- 左上角Logo -->
      <div class="logo-section animate-fade-in-up">
        <img src="/src/assets/images/01启动页/logo@2x.png" alt="三坛大戒" class="logo-image" />
      </div>
      
      <!-- 底部按钮 -->
      <div class="bottom-section animate-fade-in-up-delay">
        <div class="enter-button" @click="enterApp">
          <img src="/src/assets/images/01启动页/进入传戒现场@2x.png" alt="进入传戒现场" class="enter-image" />
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'

const router = useRouter()
const isExiting = ref(false)

// 进入应用函数
const enterApp = () => {
  isExiting.value = true
  // 等待淡出动画完成后跳转
  setTimeout(() => {
    router.push('/home')
  }, 500)
}

onMounted(() => {
  // 可以在这里添加一些初始化逻辑
})
</script>

<style scoped>
.splash-container {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 50%, #1a1a1a 100%);
  transition: opacity 0.5s ease-out;
}

.splash-container.fade-out {
  opacity: 0;
}

/* 背景图片 */
.background-image {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-image: url('/src/assets/images/01启动页/海报@2x.png');
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  z-index: 1;
  opacity: 0;
  animation: backgroundFadeIn 0.8s ease-out forwards;
}

/* 黑色半透明蒙板 */
.overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.4);
  z-index: 2;
  opacity: 0;
  animation: backgroundFadeIn 0.8s ease-out 0.2s forwards;
}

/* 初始加载指示器 - 水滴波纹效果 */
.initial-loader {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 4;
  width: 12.5rem;
  height: 12.5rem;
  opacity: 1;
  animation: loaderFadeOut 1s ease-out 2.5s forwards;
}

/* 水滴 */
.water-drop {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0.5rem;
  height: 0.5rem;
  background: radial-gradient(circle, #fbbf24 0%, #f59e0b 70%, #d97706 100%);
  border-radius: 50%;
  transform: translate(-50%, -50%);
  box-shadow: 
    0 0 0.625rem rgba(251, 191, 36, 0.8),
    0 0 1.25rem rgba(251, 191, 36, 0.4),
    0 0 1.875rem rgba(251, 191, 36, 0.2);
  animation: waterDrop 0.6s ease-out;
}

/* 波纹圈 */
.ripple {
  position: absolute;
  top: 50%;
  left: 50%;
  border: 0.125rem solid rgba(251, 191, 36, 0.6);
  border-radius: 50%;
  transform: translate(-50%, -50%);
  opacity: 0;
}

.ripple-1 {
  width: 1.25rem;
  height: 1.25rem;
  animation: rippleExpand 2s ease-out 0.2s infinite;
}

.ripple-2 {
  width: 2.5rem;
  height: 2.5rem;
  animation: rippleExpand 2s ease-out 0.4s infinite;
}

.ripple-3 {
  width: 3.75rem;
  height: 3.75rem;
  animation: rippleExpand 2s ease-out 0.6s infinite;
}

.ripple-4 {
  width: 5rem;
  height: 5rem;
  animation: rippleExpand 2s ease-out 0.8s infinite;
}

/* 内容层 */
.splash-content {
  position: relative;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  z-index: 3;
  padding: 2rem;
}

/* 左上角Logo */
.logo-section {
  align-self: flex-start;
  margin-top: 2.5rem;
  margin-left: 2.5rem;
}

.logo-image {
  width: auto;
  height: 10rem;
  max-width: 15.625rem;
  object-fit: contain;
  display: block;
}

/* 底部按钮区域 */
.bottom-section {
  align-self: center;
  margin-bottom: 3rem;
}

.enter-button {
  cursor: pointer;
  transition: transform 0.3s ease, opacity 0.3s ease;
}

.enter-button:hover {
  transform: scale(1.05);
}

.enter-button:active {
  transform: scale(0.95);
}

.enter-image {
  width: auto;
  height: 5rem;
  max-width: 25rem;
  object-fit: contain;
  display: block;
}

/* 动画 */
@keyframes waterDrop {
  0% {
    transform: translate(-50%, -5rem) scale(0.5);
    opacity: 0.8;
  }
  50% {
    transform: translate(-50%, -50%) scale(1.2);
    opacity: 1;
  }
  100% {
    transform: translate(-50%, -50%) scale(1);
    opacity: 1;
  }
}

@keyframes rippleExpand {
  0% {
    width: 0;
    height: 0;
    opacity: 0.8;
    border-width: 0.1875rem;
  }
  50% {
    opacity: 0.4;
    border-width: 0.125rem;
  }
  100% {
    width: 10rem;
    height: 10rem;
    opacity: 0;
    border-width: 0.0625rem;
  }
}

@keyframes loaderFadeOut {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
    visibility: hidden;
  }
}

@keyframes backgroundFadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(1.875rem);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.animate-fade-in-up {
  animation: fadeInUp 0.6s ease-out 1.5s both;
}

.animate-fade-in-up-delay {
  animation: fadeInUp 0.6s ease-out 1.8s both;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .splash-content {
    padding: 1.5rem;
  }

  .logo-image {
    height: 14rem;
  }

  .enter-image {
    height: 4rem;
  }

  .bottom-section {
    margin-bottom: 2rem;
  }
}

@media (max-width: 480px) {
  .splash-content {
    padding: 1rem;
  }

  .logo-image {
    height: 13rem;
  }

  .enter-image {
    height: 3.5rem;
  }
}
</style>