feat: 为 App.vue 组件新增背景动画元素,优化背景样式,并实现随机生成元素位置的功能,同时添加暗色模式适配和动画性能优化。

This commit is contained in:
Cat Tom 2025-03-26 12:10:34 +08:00
parent 334b538092
commit 7db6d59780

View File

@ -1,5 +1,11 @@
<template>
<div class="app-container">
<!-- 背景动画元素 -->
<div class="background-animation">
<div v-for="n in 12" :key="n" class="floating-element" :style="{ '--delay': `${n * 2}s` }"></div>
<div v-for="n in 8" :key="`bubble-${n}`" class="floating-bubble" :style="{ '--delay': `${n * 3}s` }"></div>
</div>
<!-- 3D粒子背景 -->
<ParticleBackground />
@ -43,22 +49,110 @@
</template>
<script setup>
import { ref } from 'vue'
import { ref, onMounted, onUnmounted } from 'vue'
import ParticleBackground from './components/ParticleBackground.vue'
import SocialLinks from './components/SocialLinks.vue'
import Typewriter from './components/Typewriter.vue'
import WechatModal from './components/WechatModal.vue'
const showWechatModal = ref(false)
//
onMounted(() => {
const elements = document.querySelectorAll('.floating-element, .floating-bubble')
elements.forEach(el => {
el.style.left = `${Math.random() * 100}vw`
el.style.top = `${Math.random() * 100}vh`
})
})
</script>
<style scoped>
.app-container {
min-height: 100vh;
background: linear-gradient(135deg, #e0f7fa 0%, #f3e5f5 100%);
position: relative;
overflow: hidden;
}
.background-animation {
position: fixed;
inset: 0;
pointer-events: none;
z-index: 0;
}
.floating-element {
position: absolute;
width: 60px;
height: 60px;
background: linear-gradient(45deg, rgba(255,255,255,0.4), rgba(255,255,255,0.1));
border-radius: 20% 60% 40% 80%;
animation: float 20s linear infinite;
animation-delay: var(--delay);
opacity: 0.6;
backdrop-filter: blur(2px);
}
.floating-bubble {
position: absolute;
width: 40px;
height: 40px;
background: radial-gradient(circle at 30% 30%, rgba(255,255,255,0.8), rgba(255,255,255,0.1));
border-radius: 50%;
animation: bubble 15s ease-in-out infinite;
animation-delay: var(--delay);
opacity: 0.4;
}
@keyframes float {
0% {
transform: translate(-100px, 100vh) rotate(0deg);
}
100% {
transform: translate(calc(100vw + 100px), -100px) rotate(360deg);
}
}
@keyframes bubble {
0%, 100% {
transform: translate(
calc(random(100) * 1vw),
calc(100vh + 50px)
);
}
50% {
transform: translate(
calc(random(100) * 1vw),
-50px
);
}
}
/* 暗色模式适配 */
@media (prefers-color-scheme: dark) {
.app-container {
background: linear-gradient(135deg, #263238 0%, #1a237e 100%);
}
.floating-element {
background: linear-gradient(45deg, rgba(255,255,255,0.1), rgba(255,255,255,0.05));
}
.floating-bubble {
background: radial-gradient(circle at 30% 30%, rgba(255,255,255,0.2), rgba(255,255,255,0.05));
}
}
/* 优化动画性能 */
@media (prefers-reduced-motion: reduce) {
.floating-element,
.floating-bubble {
animation: none;
display: none;
}
}
.content {
position: relative;
z-index: var(--z-index-content);