feat: 为 App.vue 组件新增背景动画元素,优化背景样式,并实现随机生成元素位置的功能,同时添加暗色模式适配和动画性能优化。
This commit is contained in:
parent
334b538092
commit
7db6d59780
96
src/App.vue
96
src/App.vue
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user