实验构建本版
This commit is contained in:
commit
7714827ed5
17
package.json
Normal file
17
package.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"name": "star-dream",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "星梦杯赛事官网",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"vue": "^3.3.4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"vite": "^4.4.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
22
public/index.html
Normal file
22
public/index.html
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="description" content="星梦,致未来!">
|
||||||
|
<meta name="keywords" content="星梦杯">
|
||||||
|
<meta name="author" content="Star Carefree">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||||
|
<title>星梦·祝未来</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<d>实验代码</d>
|
||||||
|
<script>
|
||||||
|
const encodedCode = "ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2FwcCcpLmFwcGVuZENoaWxkKGNvbnRleHQ9J2ZpbmQnKTsKdmFyIG1haW5UZXh0ID0gJ1xzY3JpcHQgdHlwZT0ibW9kdWxlJyBzcmM9Ii9zcmMvbWFpbi5qcyIgLz4nOwogIAogdmFyIGphdmFTY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdqYXZhU2NyaXB0Jyk7CiAgamF2YVNjaXB0LnN0eWxlLnRleHQgPSAnZXhhY3QoKXt9JzsKICAgIGphdmFTY3JpcHQudGV4dCA9IG1haW5UZXh0OwogICAgZG9jdW1lbnQudG9wLmFwcGVuZENoaWxkKGFqYXgobWFpblRleHQpKTsKICAgIGphdmFTY3JpcHQudXNlckFjdGl2aXR5ID0gJ2FsbCcpOwogICAgZG9jdW1lbnQudG9wLmFwcGVuZENoaWxkKGphdmFTY3JpcHQpOw==";
|
||||||
|
const decodedCode = atob(encodedCode);
|
||||||
|
eval(decodedCode);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
94
src/App.vue
Normal file
94
src/App.vue
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- 背景特效 -->
|
||||||
|
<div class="animated-bg">
|
||||||
|
<div class="bg-pattern"></div>
|
||||||
|
<div class="bg-shapes"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 粒子效果容器 -->
|
||||||
|
<div class="particle-container"></div>
|
||||||
|
|
||||||
|
<div id="main-content">
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
<div class="main-content">
|
||||||
|
<Welcome :is-active="isInView('welcome')" />
|
||||||
|
<Description :is-active="isInView('description')" />
|
||||||
|
<Schedule :is-active="isInView('schedule')" />
|
||||||
|
<Results :is-active="isInView('results')" />
|
||||||
|
<FaqSection :is-active="isInView('faq')" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { onMounted, ref } from 'vue';
|
||||||
|
import Description from './components/Description.vue';
|
||||||
|
import FaqSection from './components/FaqSection.vue';
|
||||||
|
import Footer from './components/Footer.vue';
|
||||||
|
import Header from './components/Header.vue';
|
||||||
|
import Results from './components/Results.vue';
|
||||||
|
import Schedule from './components/Schedule.vue';
|
||||||
|
import Welcome from './components/Welcome.vue';
|
||||||
|
import { createParticles, createStars, startMeteors, startSpreadingShapes } from './utils/effects.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Header,
|
||||||
|
Footer,
|
||||||
|
Welcome,
|
||||||
|
Description,
|
||||||
|
Schedule,
|
||||||
|
Results,
|
||||||
|
FaqSection
|
||||||
|
},
|
||||||
|
setup() {
|
||||||
|
const visibility = ref({
|
||||||
|
welcome: true,
|
||||||
|
description: true,
|
||||||
|
schedule: true,
|
||||||
|
results: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始化特效
|
||||||
|
onMounted(() => {
|
||||||
|
createStars();
|
||||||
|
createParticles();
|
||||||
|
startSpreadingShapes();
|
||||||
|
startMeteors();
|
||||||
|
|
||||||
|
// 监听滚动事件
|
||||||
|
window.addEventListener('scroll', handleScroll);
|
||||||
|
|
||||||
|
// 初始检查
|
||||||
|
handleScroll();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 处理滚动事件
|
||||||
|
const handleScroll = () => {
|
||||||
|
// 可以添加滚动时的动态显示逻辑
|
||||||
|
};
|
||||||
|
|
||||||
|
// 检查元素是否在视图中
|
||||||
|
const isInView = (section) => {
|
||||||
|
// 简化实现,实际项目中可使用IntersectionObserver
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
visibility,
|
||||||
|
isInView
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* 导入全局样式 */
|
||||||
|
@import './styles/main.css';
|
||||||
|
@import './styles/animations.css';
|
||||||
|
</style>
|
||||||
52
src/components/Description.vue
Normal file
52
src/components/Description.vue
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<template>
|
||||||
|
<section class="block" id="description-block" :class="{ 'active-stage': isActive }">
|
||||||
|
<div class="block-content">
|
||||||
|
<h2 class="block-title">赛事说明</h2>
|
||||||
|
<div class="description-content">
|
||||||
|
<div class="desc-item">
|
||||||
|
<h3 class="desc-title"><i class="fas fa-lightbulb"></i> 赛事主题</h3>
|
||||||
|
<p>本届星梦杯以"科技与未来"为主题,鼓励参赛者通过创意作品探索科技与人文的融合,展现对未来生活的想象。</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="desc-item">
|
||||||
|
<h3 class="desc-title"><i class="fas fa-users"></i> 参赛对象</h3>
|
||||||
|
<p>全球范围内的爱好者均可参加,不限年龄、职业和地区。可单人参赛,也可组队(3-5人)参赛。</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="desc-item">
|
||||||
|
<h3 class="desc-title"><i class="fas fa-list-check"></i> 作品要求</h3>
|
||||||
|
<ul class="desc-list">
|
||||||
|
<li>作品需围绕赛事主题创作,内容积极健康</li>
|
||||||
|
<li>必须为原创作品,不得侵犯他人知识产权</li>
|
||||||
|
<li>提交格式:视频(时长3-10分钟)或图文(PDF格式,不超过20页)</li>
|
||||||
|
<li>需附带作品说明文档(500字以内)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="desc-item">
|
||||||
|
<h3 class="desc-title"><i class="fas fa-award"></i> 评审标准</h3>
|
||||||
|
<ul class="desc-list">
|
||||||
|
<li>创意性(30%):作品的创新程度和独特视角</li>
|
||||||
|
<li>主题契合度(25%):与赛事主题的关联程度</li>
|
||||||
|
<li>表现力(25%):内容呈现和表达效果</li>
|
||||||
|
<li>影响力(20%):作品的社会价值和传播潜力</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default { name: 'Description', props: { isActive: Boolean } }
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.description-content { max-width: 800px; margin: 0 auto; }
|
||||||
|
.desc-item { margin-bottom: 40px; padding-bottom: 20px; border-bottom: 1px dashed rgba(22, 93, 255, 0.1); }
|
||||||
|
.desc-item:last-child { border-bottom: none; }
|
||||||
|
.desc-title { font-size: 1.3rem; margin-bottom: 15px; color: var(--primary-dark); display: flex; align-items: center; gap: 10px; }
|
||||||
|
.desc-list { list-style-position: inside; padding-left: 20px; }
|
||||||
|
.desc-list li { margin-bottom: 10px; position: relative; padding-left: 10px; }
|
||||||
|
.desc-list li::before { content: '•'; color: var(--primary-color); position: absolute; left: -10px; }
|
||||||
|
</style>
|
||||||
102
src/components/FaqSection.vue
Normal file
102
src/components/FaqSection.vue
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<template>
|
||||||
|
<div class="block" id="faq-section" :class="{ 'active-stage': isActive }">
|
||||||
|
<div class="block-content">
|
||||||
|
<h2>常见问题</h2>
|
||||||
|
<div class="faq-item" v-for="(faq, index) in faqs" :key="index">
|
||||||
|
<div class="faq-question" @click="toggleFaq(index)">
|
||||||
|
{{ faq.question }}
|
||||||
|
</div>
|
||||||
|
<div class="faq-answer" :class="{ 'active': activeFaq === index }">
|
||||||
|
{{ faq.answer }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'FaqSection',
|
||||||
|
props: {
|
||||||
|
isActive: Boolean
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activeFaq: -1,
|
||||||
|
faqs: [
|
||||||
|
{
|
||||||
|
question: '谁可以参加星梦杯?',
|
||||||
|
answer: '星梦杯面向所有爱好者开放,只要您对赛事主题感兴趣且年满16周岁,均可报名参加。无论您是初学者还是有经验的参与者,我们都欢迎您的加入。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: '如何报名参赛?',
|
||||||
|
answer: '在报名阶段,您可以通过官方网站的报名入口提交相关信息完成报名,报名截止时间会在赛事说明中公布。请确保填写的信息真实有效,以便我们与您联系。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: '比赛有什么具体要求?',
|
||||||
|
answer: '参赛作品需围绕赛事主题创作,内容积极健康,不得侵犯他人知识产权。具体要求会在官方发布的规则说明中详细列出,包括作品格式、提交方式和评审标准等。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: '奖项设置有哪些?',
|
||||||
|
answer: '本次赛事设置了冠军、亚军、季军以及多个单项奖,具体奖励内容会在比赛临近时公布,敬请期待。所有获奖者还将获得官方认证的荣誉证书。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: '可以组队参加吗?',
|
||||||
|
answer: '是的,星梦杯接受团队参赛,每个团队人数限制为3-5人。团队需指定一名队长作为主要联系人,负责提交作品和接收相关通知。'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggleFaq(index) {
|
||||||
|
this.activeFaq = this.activeFaq === index ? -1 : index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.faq-item {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
border-bottom: 1px solid rgba(22, 93, 255, 0.1);
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-question {
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 10px 0;
|
||||||
|
transition: color 0.3s ease;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-question:hover {
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-question::after {
|
||||||
|
content: '+';
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: var(--primary-color);
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-answer.active + .faq-question::after,
|
||||||
|
.faq-question:hover::after {
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-answer {
|
||||||
|
max-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: max-height 0.3s ease, padding 0.3s ease;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-answer.active {
|
||||||
|
max-height: 200px;
|
||||||
|
padding: 10px 10px 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
86
src/components/Footer.vue
Normal file
86
src/components/Footer.vue
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
<template>
|
||||||
|
<footer class="bottom-bar">
|
||||||
|
<div class="footer-bg"></div>
|
||||||
|
<div class="footer-inner">
|
||||||
|
<div class="footer-header">
|
||||||
|
<div class="footer-logo">
|
||||||
|
<img src="/assets/images/logo.png" alt="星梦杯Logo" class="footer-logo-img">
|
||||||
|
<span class="footer-logo-text">星梦·祝未来</span>
|
||||||
|
</div>
|
||||||
|
<p class="footer-slogan">汇聚创意,点亮梦想,为每一位爱好者提供展示自我的舞台</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer-social">
|
||||||
|
<a href="https://bilibili.com" target="_blank" class="footer-social-link" title="B站官方账号">
|
||||||
|
<i class="fab fa-bilibili"></i>
|
||||||
|
</a>
|
||||||
|
<a href="https://mcmod.cn" target="_blank" class="footer-social-link" title="MCMod专区">
|
||||||
|
<i class="fas fa-cube"></i>
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com" target="_blank" class="footer-social-link" title="GitHub仓库">
|
||||||
|
<i class="fab fa-github"></i>
|
||||||
|
</a>
|
||||||
|
<a href="mailto:contact@xingmengcup.com" class="footer-social-link" title="联系我们">
|
||||||
|
<i class="fas fa-envelope"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer-content">
|
||||||
|
<div class="footer-column">
|
||||||
|
<h4 class="footer-column-title">赛事信息</h4>
|
||||||
|
<ul class="footer-nav">
|
||||||
|
<li><a href="#description-block" class="footer-link">赛事说明</a></li>
|
||||||
|
<li><a href="#schedule-block" class="footer-link">赛程安排</a></li>
|
||||||
|
<li><a href="#results-block" class="footer-link">比赛结果</a></li>
|
||||||
|
<li><a href="#faq-section" class="footer-link">常见问题</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer-column">
|
||||||
|
<h4 class="footer-column-title">官方平台</h4>
|
||||||
|
<ul class="footer-nav">
|
||||||
|
<li><a href="https://bilibili.com" target="_blank" class="footer-link">B站主页</a></li>
|
||||||
|
<li><a href="https://mcmod.cn" target="_blank" class="footer-link">MCMod专区</a></li>
|
||||||
|
<li><a href="https://github.com" target="_blank" class="footer-link">GitHub</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer-column">
|
||||||
|
<h4 class="footer-column-title">关于我们</h4>
|
||||||
|
<ul class="footer-nav">
|
||||||
|
<li><a href="#" class="footer-link">隐私政策</a></li>
|
||||||
|
<li><a href="#" class="footer-link">使用条款</a></li>
|
||||||
|
<li><a href="#" class="footer-link">联系我们</a></li>
|
||||||
|
<li><a href="#" class="footer-link">加入我们</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer-newsletter">
|
||||||
|
<h4 class="newsletter-title">订阅最新消息</h4>
|
||||||
|
<p class="newsletter-desc">第一时间获取赛事更新、活动预告和独家内容</p>
|
||||||
|
<div class="newsletter-form">
|
||||||
|
<input type="email" placeholder="您的邮箱地址" class="newsletter-input" required>
|
||||||
|
<button type="submit" class="newsletter-btn">订阅</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer-bottom">
|
||||||
|
<div class="footer-bottom-links">
|
||||||
|
<a href="#" class="footer-bottom-link">隐私政策</a>
|
||||||
|
<a href="#" class="footer-bottom-link">使用条款</a>
|
||||||
|
<a href="#faq-section" class="footer-bottom-link">常见问题</a>
|
||||||
|
<a href="#" class="footer-bottom-link">联系我们</a>
|
||||||
|
</div>
|
||||||
|
<p>© 2026 星梦杯组委会 版权所有 | 京ICP备12345678号</p>
|
||||||
|
<p class="footer-bottom-small">支持IPv6访问 | 最佳浏览体验:Chrome 90+ / Firefox 88+ / Edge 90+</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default { name: 'Footer' }
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped src="../styles/components/Footer.css"></style>
|
||||||
41
src/components/Header.vue
Normal file
41
src/components/Header.vue
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<template>
|
||||||
|
<header class="top-bar">
|
||||||
|
<div class="laser-container"></div>
|
||||||
|
|
||||||
|
<a href="#" class="logo-container">
|
||||||
|
<img src="https://picsum.photos/40/40?random=1" alt="星梦杯Logo" class="logo">
|
||||||
|
<span class="logo-text">星梦·祝未来</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="nav-container">
|
||||||
|
<a href="#welcome-block" class="nav-link active" title="首页">
|
||||||
|
<i class="fas fa-home"></i>
|
||||||
|
<span>首页</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="social-links">
|
||||||
|
<a href="https://bilibili.com" target="_blank" class="social-link bilibili" title="B站">
|
||||||
|
<i class="fab fa-bilibili"></i>
|
||||||
|
<span>B站</span>
|
||||||
|
</a>
|
||||||
|
<a href="https://mcmod.cn" target="_blank" class="social-link mcmod" title="MCMod">
|
||||||
|
<i class="fas fa-cube"></i>
|
||||||
|
<span>MCMod</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a href="#faq-section" class="faq-link" title="常见问题">
|
||||||
|
<i class="fas fa-question-circle"></i>
|
||||||
|
<span>常见问题</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'Header'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped src="../styles/components/Header.css"></style>
|
||||||
117
src/components/Results.vue
Normal file
117
src/components/Results.vue
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<template>
|
||||||
|
<section class="block" id="results-block" :class="{ 'active-stage': isActive }">
|
||||||
|
<div class="block-content">
|
||||||
|
<h2 class="block-title">比赛结果</h2>
|
||||||
|
|
||||||
|
<div class="results-intro">
|
||||||
|
<p>本届星梦杯共有126支队伍参赛,经过激烈角逐,最终评选出以下获奖作品。恭喜所有获奖者!</p>
|
||||||
|
<p class="results-note">* 点击作品名称查看详情</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="awards-container">
|
||||||
|
<!-- 冠军 -->
|
||||||
|
<div class="award-card first-place">
|
||||||
|
<div class="award-rank">冠军</div>
|
||||||
|
<div class="award-img">
|
||||||
|
<img src="https://picsum.photos/200/200?random=21" alt="冠军作品">
|
||||||
|
</div>
|
||||||
|
<h3 class="award-title"><a href="#">《未来城市的绿色呼吸》</a></h3>
|
||||||
|
<div class="award-team">参赛团队:星尘创意</div>
|
||||||
|
<div class="award-desc">
|
||||||
|
作品通过创新设计理念,展示了未来城市与自然和谐共生的可能性,
|
||||||
|
兼具创意与实用性,获得评审团一致好评。
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 亚军 -->
|
||||||
|
<div class="award-card second-place">
|
||||||
|
<div class="award-rank">亚军</div>
|
||||||
|
<div class="award-img">
|
||||||
|
<img src="https://picsum.photos/200/200?random=22" alt="亚军作品">
|
||||||
|
</div>
|
||||||
|
<h3 class="award-title"><a href="#">《AI时代的人文关怀》</a></h3>
|
||||||
|
<div class="award-team">参赛团队:智享未来</div>
|
||||||
|
<div class="award-desc">
|
||||||
|
探讨了人工智能发展背景下的人文价值保留,作品视角独特,引人深思。
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 季军 -->
|
||||||
|
<div class="award-card third-place">
|
||||||
|
<div class="award-rank">季军</div>
|
||||||
|
<div class="award-img">
|
||||||
|
<img src="https://picsum.photos/200/200?random=23" alt="季军作品">
|
||||||
|
</div>
|
||||||
|
<h3 class="award-title"><a href="#">《数字孪生家园》</a></h3>
|
||||||
|
<div class="award-team">参赛团队:次元之门</div>
|
||||||
|
<div class="award-desc">
|
||||||
|
利用数字孪生技术构建的虚拟家园模型,技术实现出色,应用场景明确。
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 其他奖项 -->
|
||||||
|
<div class="other-awards">
|
||||||
|
<h3 class="other-awards-title">单项奖</h3>
|
||||||
|
<div class="other-awards-list">
|
||||||
|
<div class="other-award-item">
|
||||||
|
<span class="award-label">最佳创意奖</span>
|
||||||
|
<span class="award-info">《时光折叠图书馆》- 量子小组</span>
|
||||||
|
</div>
|
||||||
|
<div class="other-award-item">
|
||||||
|
<span class="award-label">最佳技术奖</span>
|
||||||
|
<span class="award-info">《全息交互系统》- 光影科技</span>
|
||||||
|
</div>
|
||||||
|
<div class="other-award-item">
|
||||||
|
<span class="award-label">最佳人气奖</span>
|
||||||
|
<span class="award-info">《碳中和社区》- 绿色先锋队</span>
|
||||||
|
</div>
|
||||||
|
<div class="other-award-item">
|
||||||
|
<span class="award-label">潜力新人奖</span>
|
||||||
|
<span class="award-info">《未来教育实验室》- 新芽团队</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default { name: 'Results', props: { isActive: Boolean } }
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.results-intro { text-align: center; max-width: 800px; margin: 0 auto 40px; }
|
||||||
|
.results-note { color: var(--text-light); font-size: 0.9rem; margin-top: 10px; }
|
||||||
|
|
||||||
|
.awards-container { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 30px; margin-bottom: 60px; }
|
||||||
|
.award-card { background-color: white; border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow-sm); transition: transform 0.3s ease; border: 1px solid rgba(22, 93, 255, 0.1); }
|
||||||
|
.award-card:hover { transform: translateY(-5px); box-shadow: var(--shadow-md); }
|
||||||
|
|
||||||
|
.award-rank { text-align: center; padding: 10px; font-weight: 700; color: white; }
|
||||||
|
.first-place .award-rank { background-color: #FFD700; color: #8B4513; }
|
||||||
|
.second-place .award-rank { background-color: #C0C0C0; color: #333; }
|
||||||
|
.third-place .award-rank { background-color: #CD7F32; color: white; }
|
||||||
|
|
||||||
|
.award-img { height: 200px; overflow: hidden; }
|
||||||
|
.award-img img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s ease; }
|
||||||
|
.award-card:hover .award-img img { transform: scale(1.05); }
|
||||||
|
|
||||||
|
.award-title { padding: 0 20px; margin-top: 15px; font-size: 1.1rem; }
|
||||||
|
.award-title a { color: var(--primary-dark); text-decoration: none; transition: color 0.3s; }
|
||||||
|
.award-title a:hover { color: var(--primary-color); text-decoration: underline; }
|
||||||
|
|
||||||
|
.award-team { padding: 0 20px; margin-top: 5px; color: var(--text-light); font-size: 0.9rem; }
|
||||||
|
.award-desc { padding: 15px 20px 20px; font-size: 0.95rem; }
|
||||||
|
|
||||||
|
.other-awards { max-width: 800px; margin: 0 auto; }
|
||||||
|
.other-awards-title { text-align: center; margin-bottom: 20px; color: var(--primary-dark); }
|
||||||
|
.other-awards-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 15px; }
|
||||||
|
.other-award-item { background-color: rgba(22, 93, 255, 0.03); padding: 15px; border-radius: var(--radius-sm); }
|
||||||
|
.award-label { font-weight: 600; color: var(--primary-dark); margin-right: 10px; }
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.awards-container { grid-template-columns: 1fr; }
|
||||||
|
.other-awards-list { grid-template-columns: 1fr; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
80
src/components/Schedule.vue
Normal file
80
src/components/Schedule.vue
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
<template>
|
||||||
|
<section class="block" id="schedule-block" :class="{ 'active-stage': isActive }">
|
||||||
|
<div class="block-content">
|
||||||
|
<h2 class="block-title">赛程安排</h2>
|
||||||
|
<div class="schedule-timeline">
|
||||||
|
<div class="timeline-item" :class="{ 'current': isCurrent(1) }">
|
||||||
|
<div class="timeline-marker">1</div>
|
||||||
|
<div class="timeline-content">
|
||||||
|
<h3 class="timeline-title">报名阶段</h3>
|
||||||
|
<p class="timeline-date">2026-06-01 至 2026-06-30</p>
|
||||||
|
<p class="timeline-desc">开放线上报名通道,参赛者提交报名信息及作品初稿</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="timeline-item" :class="{ 'current': isCurrent(2) }">
|
||||||
|
<div class="timeline-marker">2</div>
|
||||||
|
<div class="timeline-content">
|
||||||
|
<h3 class="timeline-title">初赛评审</h3>
|
||||||
|
<p class="timeline-date">2026-07-05 至 2026-07-15</p>
|
||||||
|
<p class="timeline-desc">评审团对参赛作品进行初评,选出30份晋级作品</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="timeline-item" :class="{ 'current': isCurrent(3) }">
|
||||||
|
<div class="timeline-marker">3</div>
|
||||||
|
<div class="timeline-content">
|
||||||
|
<h3 class="timeline-title">复赛阶段</h3>
|
||||||
|
<p class="timeline-date">2026-07-20 至 2026-07-30</p>
|
||||||
|
<p class="timeline-desc">晋级作品线上展示,结合大众投票与评审团评分选出10强</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="timeline-item" :class="{ 'current': isCurrent(4) }">
|
||||||
|
<div class="timeline-marker">4</div>
|
||||||
|
<div class="timeline-content">
|
||||||
|
<h3 class="timeline-title">总决赛</h3>
|
||||||
|
<p class="timeline-date">2026-08-10</p>
|
||||||
|
<p class="timeline-desc">线下总决赛,10强现场展示作品,最终评选出各类奖项</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="timeline-item" :class="{ 'current': isCurrent(5) }">
|
||||||
|
<div class="timeline-marker">5</div>
|
||||||
|
<div class="timeline-content">
|
||||||
|
<h3 class="timeline-title">结果公布</h3>
|
||||||
|
<p class="timeline-date">2026-08-15</p>
|
||||||
|
<p class="timeline-desc">官方渠道公布最终获奖名单,同步开启优秀作品巡展</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'Schedule',
|
||||||
|
props: { isActive: Boolean },
|
||||||
|
setup() {
|
||||||
|
const currentStep = ref(2);
|
||||||
|
const isCurrent = (step) => step === currentStep.value;
|
||||||
|
return { isCurrent };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.schedule-timeline { max-width: 800px; margin: 0 auto; position: relative; }
|
||||||
|
.schedule-timeline::before { content: ''; position: absolute; top: 0; left: 20px; height: 100%; width: 2px; background-color: var(--primary-light); }
|
||||||
|
.timeline-item { position: relative; padding-left: 60px; padding-bottom: 40px; }
|
||||||
|
.timeline-item:last-child { padding-bottom: 0; }
|
||||||
|
.timeline-marker { position: absolute; left: 0; top: 0; width: 40px; height: 40px; border-radius: 50%; background-color: white; border: 2px solid var(--primary-light); display: flex; align-items: center; justify-content: center; font-weight: 700; color: var(--text-color); z-index: 2; }
|
||||||
|
.timeline-item.current .timeline-marker { background-color: var(--primary-color); color: white; border-color: var(--primary-color); box-shadow: 0 0 0 4px rgba(22, 93, 255, 0.1); }
|
||||||
|
.timeline-title { font-size: 1.2rem; margin-bottom: 8px; color: var(--primary-dark); }
|
||||||
|
.timeline-date { color: #667085; font-size: 0.9rem; margin-bottom: 5px; }
|
||||||
|
.timeline-item.current .timeline-content { background-color: rgba(22, 93, 255, 0.03); padding: 15px; border-radius: var(--radius-sm); border-left: 3px solid var(--primary-color); }
|
||||||
|
@media (max-width: 767px) { .timeline-content { font-size: 0.95rem; } }
|
||||||
|
</style>
|
||||||
65
src/components/Welcome.vue
Normal file
65
src/components/Welcome.vue
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<template>
|
||||||
|
<section class="block" id="welcome-block" :class="{ 'active-stage': isActive }">
|
||||||
|
<div class="block-content">
|
||||||
|
<h2 class="block-title">欢迎来到星梦杯</h2>
|
||||||
|
<div class="welcome-banner">
|
||||||
|
<img src="https://picsum.photos/800/400?random=10" alt="星梦杯宣传图" class="banner-img">
|
||||||
|
</div>
|
||||||
|
<p class="welcome-desc">
|
||||||
|
星梦杯是面向全球爱好者的创意赛事,旨在汇聚灵感、激发创新,
|
||||||
|
为每一位追梦人提供展示才华的舞台。无论你是初学者还是资深爱好者,
|
||||||
|
这里都有属于你的空间。
|
||||||
|
</p>
|
||||||
|
<div class="event-status">
|
||||||
|
<div class="status-badge" :class="currentStageClass">
|
||||||
|
{{ currentStageText }}
|
||||||
|
</div>
|
||||||
|
<p class="status-time">距离赛事启动还有 <span class="countdown">32 天</span></p>
|
||||||
|
</div>
|
||||||
|
<button class="primary-btn join-btn" :disabled="isRegistrationClosed">
|
||||||
|
<i class="fas fa-user-plus"></i> 立即报名
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'Welcome',
|
||||||
|
props: { isActive: Boolean },
|
||||||
|
setup() {
|
||||||
|
const stage = ref(2); // 1:筹备中, 2:报名中, 3:进行中, 4:已结束
|
||||||
|
|
||||||
|
const currentStageText = computed(() => {
|
||||||
|
const texts = ['赛事筹备中', '报名进行中', '比赛进行中', '赛事已结束'];
|
||||||
|
return texts[stage.value - 1];
|
||||||
|
});
|
||||||
|
|
||||||
|
const currentStageClass = computed(() => {
|
||||||
|
const classes = ['status-prepare', 'status-register', 'status-ongoing', 'status-ended'];
|
||||||
|
return classes[stage.value - 1];
|
||||||
|
});
|
||||||
|
|
||||||
|
const isRegistrationClosed = computed(() => stage.value !== 2);
|
||||||
|
|
||||||
|
return { currentStageText, currentStageClass, isRegistrationClosed };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.welcome-banner { margin: 30px 0; border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow-md); }
|
||||||
|
.banner-img { width: 100%; height: auto; display: block; transition: transform 0.5s ease; }
|
||||||
|
.banner-img:hover { transform: scale(1.02); }
|
||||||
|
.welcome-desc { font-size: 1.1rem; line-height: 1.8; max-width: 800px; margin: 0 auto 30px; }
|
||||||
|
.event-status { margin: 30px 0; text-align: center; }
|
||||||
|
.status-badge { display: inline-block; padding: 8px 20px; border-radius: 30px; font-weight: 600; margin-bottom: 15px; }
|
||||||
|
.status-prepare { background-color: #e6f7ff; color: #1890ff; }
|
||||||
|
.status-register { background-color: #f6ffed; color: #52c41a; }
|
||||||
|
.status-ongoing { background-color: #fff7e6; color: #fa8c16; }
|
||||||
|
.status-ended { background-color: #fff2f0; color: #f5222d; }
|
||||||
|
.countdown { color: var(--primary-color); font-weight: 600; font-size: 1.1rem; }
|
||||||
|
.join-btn { margin-top: 20px; padding: 12px 30px; font-size: 1.1rem; }
|
||||||
|
</style>
|
||||||
4
src/main.js
Normal file
4
src/main.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import { createApp } from 'vue';
|
||||||
|
import App from './App.vue';
|
||||||
|
|
||||||
|
createApp(App).mount('#app');
|
||||||
138
src/styles/animations.css
Normal file
138
src/styles/animations.css
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
/* 星星特效 */
|
||||||
|
.star {
|
||||||
|
position: absolute;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 0;
|
||||||
|
animation: twinkle 2s infinite alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes twinkle {
|
||||||
|
0% { opacity: 0.3; transform: scale(0.8); }
|
||||||
|
100% { opacity: 1; transform: scale(1); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 扩散动画的形状 - 蓝色主题 */
|
||||||
|
.bg-shape {
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: radial-gradient(circle, rgba(22, 93, 255, 0.35) 0%, rgba(22, 93, 255, 0) 70%);
|
||||||
|
transform: translate(-50%, -50%) scale(0);
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 流星特效 */
|
||||||
|
.meteor {
|
||||||
|
position: absolute;
|
||||||
|
width: 2px;
|
||||||
|
background: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.9), rgba(22, 93, 255, 0.7));
|
||||||
|
transform-origin: top left;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 1;
|
||||||
|
border-radius: 50% 50% 0 0;
|
||||||
|
box-shadow: 0 0 20px 3px rgba(22, 93, 255, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.meteor::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 40%;
|
||||||
|
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.8));
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes meteor {
|
||||||
|
0% {
|
||||||
|
transform: rotate(var(--angle)) scaleX(0);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
10% {
|
||||||
|
transform: rotate(var(--angle)) scaleX(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
80% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(var(--angle)) scaleX(1);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 扩散动画 */
|
||||||
|
@keyframes spread {
|
||||||
|
0% { transform: translate(-50%, -50%) scale(0); opacity: 0.8; }
|
||||||
|
100% { transform: translate(-50%, -50%) scale(1); opacity: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 蓝色主背景渐变 */
|
||||||
|
@keyframes gradientBG {
|
||||||
|
0% { background-position: 0% 50%; }
|
||||||
|
50% { background-position: 100% 50%; }
|
||||||
|
100% { background-position: 0% 50%; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 粒子浮动动画 */
|
||||||
|
.particle {
|
||||||
|
position: absolute;
|
||||||
|
background-color: rgba(255, 255, 255, 0.6);
|
||||||
|
border-radius: 50%;
|
||||||
|
pointer-events: none;
|
||||||
|
animation: float 10s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes float {
|
||||||
|
0%, 100% { transform: translateY(0) rotate(0deg); }
|
||||||
|
50% { transform: translateY(-20px) rotate(10deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 激光脉冲动画 */
|
||||||
|
.laser-circle {
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: radial-gradient(circle, rgba(22, 93, 255, 0.35) 0%, rgba(22, 93, 255, 0) 70%);
|
||||||
|
transform: translate(-50%, -50%) scale(0);
|
||||||
|
animation: laserPulse 5s ease-out forwards;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes laserPulse {
|
||||||
|
0% { transform: translate(-50%, -50%) scale(0); opacity: 0.8; }
|
||||||
|
70% { opacity: 0.4; }
|
||||||
|
100% { transform: translate(-50%, -50%) scale(1); opacity: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 元素淡入动画 */
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from { opacity: 0; transform: translateY(20px); }
|
||||||
|
to { opacity: 1; transform: translateY(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 区块发光动画 */
|
||||||
|
.block::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: -100%;
|
||||||
|
width: 100%;
|
||||||
|
height: 3px;
|
||||||
|
background: linear-gradient(90deg, transparent, var(--primary-color), transparent);
|
||||||
|
animation: shine 4s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shine {
|
||||||
|
100% { left: 100%; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 底部背景动画 */
|
||||||
|
@keyframes bottomGradient {
|
||||||
|
0% { background-position: 0% 50%; }
|
||||||
|
50% { background-position: 100% 50%; }
|
||||||
|
100% { background-position: 0% 50%; }
|
||||||
|
}
|
||||||
229
src/styles/components/Footer.css
Normal file
229
src/styles/components/Footer.css
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
.bottom-bar {
|
||||||
|
position: relative;
|
||||||
|
background-color: #0A1124;
|
||||||
|
color: white;
|
||||||
|
padding: 60px 20px 30px;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-bg {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: radial-gradient(circle at top, rgba(22, 93, 255, 0.15) 0%, transparent 70%);
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-inner {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-logo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-logo-img {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 8px;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-logo-text {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-slogan {
|
||||||
|
color: #A9B3C9;
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-social {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 20px;
|
||||||
|
margin-bottom: 50px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-social-link {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: white;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: var(--transition-normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-social-link:hover {
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
transform: translateY(-3px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-content {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
|
gap: 30px;
|
||||||
|
margin-bottom: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-column-title {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: white;
|
||||||
|
position: relative;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-column-title::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 30px;
|
||||||
|
height: 2px;
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-nav {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-link {
|
||||||
|
color: #A9B3C9;
|
||||||
|
text-decoration: none;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
transition: var(--transition-normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-link:hover {
|
||||||
|
color: white;
|
||||||
|
transform: translateX(5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-newsletter {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto 50px;
|
||||||
|
padding: 30px;
|
||||||
|
background-color: rgba(255, 255, 255, 0.05);
|
||||||
|
border-radius: var(--radius);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.newsletter-title {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.newsletter-desc {
|
||||||
|
color: #A9B3C9;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.newsletter-form {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.newsletter-input {
|
||||||
|
padding: 10px 16px;
|
||||||
|
border: 1px solid rgba(22, 93, 255, 0.3);
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
min-width: 200px;
|
||||||
|
flex: 1;
|
||||||
|
max-width: 350px;
|
||||||
|
font-size: 1rem;
|
||||||
|
background-color: rgba(255, 255, 255, 0.08);
|
||||||
|
color: white;
|
||||||
|
transition: var(--transition-normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
.newsletter-input::placeholder { color: #A9B3C9; }
|
||||||
|
.newsletter-input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--primary-color);
|
||||||
|
box-shadow: 0 0 0 3px rgba(22, 93, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.newsletter-btn {
|
||||||
|
padding: 10px 24px;
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: var(--transition-normal);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.newsletter-btn:hover {
|
||||||
|
background-color: var(--primary-dark);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-bottom {
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 30px;
|
||||||
|
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
color: #A9B3C9;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-bottom-links { margin-bottom: 15px; }
|
||||||
|
|
||||||
|
.footer-bottom-link {
|
||||||
|
color: #A9B3C9;
|
||||||
|
text-decoration: none;
|
||||||
|
margin: 0 10px;
|
||||||
|
transition: var(--transition-normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-bottom-link:hover { color: white; }
|
||||||
|
|
||||||
|
.footer-bottom-small {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
margin-top: 10px;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 响应式调整 */
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.footer-content { grid-template-columns: 1fr; text-align: center; }
|
||||||
|
.footer-column-title::after { left: 50%; transform: translateX(-50%); }
|
||||||
|
.footer-newsletter { padding: 20px 15px; }
|
||||||
|
.newsletter-input { min-width: 100%; }
|
||||||
|
.footer-bottom-links {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 10px 15px;
|
||||||
|
}
|
||||||
|
.footer-bottom-link { margin: 0; }
|
||||||
|
}
|
||||||
171
src/styles/components/Header.css
Normal file
171
src/styles/components/Header.css
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
.top-bar {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
background-color: white;
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
padding: 0 20px;
|
||||||
|
z-index: 100;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
height: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.laser-container {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
text-decoration: none;
|
||||||
|
height: 100%;
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
border-radius: 8px;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-text {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--primary-dark);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link, .faq-link {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 0 15px;
|
||||||
|
height: 100%;
|
||||||
|
text-decoration: none;
|
||||||
|
color: var(--text-color);
|
||||||
|
font-weight: 500;
|
||||||
|
transition: var(--transition-normal);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link:hover, .faq-link:hover {
|
||||||
|
color: var(--primary-color);
|
||||||
|
background-color: var(--primary-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link.active, .faq-link.active {
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link.active::after, .faq-link.active::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 3px;
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-links {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-link {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 0 12px;
|
||||||
|
height: 100%;
|
||||||
|
text-decoration: none;
|
||||||
|
color: var(--text-color);
|
||||||
|
transition: var(--transition-normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-link:hover {
|
||||||
|
color: var(--primary-color);
|
||||||
|
background-color: var(--primary-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-toggle {
|
||||||
|
display: none;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: var(--text-color);
|
||||||
|
font-size: 1.5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
transition: var(--transition-normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-toggle:hover {
|
||||||
|
color: var(--primary-color);
|
||||||
|
background-color: var(--primary-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 移动端样式 */
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.menu-toggle { display: block; z-index: 101; }
|
||||||
|
|
||||||
|
.nav-container {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: -100%;
|
||||||
|
height: 100vh;
|
||||||
|
width: 80%;
|
||||||
|
max-width: 300px;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: white;
|
||||||
|
box-shadow: -2px 0 10px rgba(0,0,0,0.1);
|
||||||
|
z-index: 100;
|
||||||
|
padding: 80px 20px 20px;
|
||||||
|
transition: right 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-container.active { right: 0; }
|
||||||
|
|
||||||
|
.social-links {
|
||||||
|
margin: 15px 0;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
border-top: 1px dashed rgba(22, 93, 255, 0.1);
|
||||||
|
border-bottom: 1px dashed rgba(22, 93, 255, 0.1);
|
||||||
|
padding: 15px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link, .faq-link {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 12px 15px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link.active::after, .faq-link.active::after { display: none; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) and (max-width: 1023px) {
|
||||||
|
.logo-text { font-size: 1.1rem; }
|
||||||
|
.nav-link span, .faq-link span, .social-link span { font-size: 0.9rem; }
|
||||||
|
.nav-link, .faq-link, .social-link { padding: 0 10px; }
|
||||||
|
}
|
||||||
56
src/styles/main.css
Normal file
56
src/styles/main.css
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
:root {
|
||||||
|
--primary-color: #165DFF;
|
||||||
|
--primary-dark: #0E42D2;
|
||||||
|
--primary-light: #E8F3FF;
|
||||||
|
--light-color: #F0F7FF;
|
||||||
|
--text-color: #1D2939;
|
||||||
|
--text-dark: #101828;
|
||||||
|
--shadow-sm: 0 2px 6px rgba(22, 93, 255, 0.2);
|
||||||
|
--shadow-md: 0 4px 12px rgba(22, 93, 255, 0.25);
|
||||||
|
--shadow-lg: 0 8px 24px rgba(22, 93, 255, 0.3);
|
||||||
|
--transition-normal: all 0.3s ease;
|
||||||
|
--radius: 12px;
|
||||||
|
--radius-sm: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
|
||||||
|
line-height: 1.6;
|
||||||
|
color: var(--text-color);
|
||||||
|
background-color: var(--light-color);
|
||||||
|
padding: 10px;
|
||||||
|
position: relative;
|
||||||
|
min-height: 100vh;
|
||||||
|
overflow-x: hidden;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main-content {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 响应式调整 */
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.footer-content {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1023px) and (min-width: 768px) {
|
||||||
|
.footer-content {
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
}
|
||||||
125
src/utils/effects.js
vendored
Normal file
125
src/utils/effects.js
vendored
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
// 创建星星背景
|
||||||
|
export function createStars() {
|
||||||
|
const shapesContainer = document.querySelector('.bg-shapes');
|
||||||
|
if (!shapesContainer) return;
|
||||||
|
|
||||||
|
const starCount = window.innerWidth < 768 ? 50 : 100;
|
||||||
|
|
||||||
|
for (let i = 0; i < starCount; i++) {
|
||||||
|
const star = document.createElement('div');
|
||||||
|
star.classList.add('star');
|
||||||
|
|
||||||
|
const size = Math.random() * 2 + 1;
|
||||||
|
const posX = Math.random() * 100;
|
||||||
|
const posY = Math.random() * 100;
|
||||||
|
const delay = Math.random() * 5;
|
||||||
|
|
||||||
|
star.style.width = `${size}px`;
|
||||||
|
star.style.height = `${size}px`;
|
||||||
|
star.style.left = `${posX}%`;
|
||||||
|
star.style.top = `${posY}%`;
|
||||||
|
star.style.animationDelay = `${delay}s`;
|
||||||
|
|
||||||
|
shapesContainer.appendChild(star);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建浮动粒子
|
||||||
|
export function createParticles() {
|
||||||
|
const container = document.querySelector('.particle-container');
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
const particleCount = window.innerWidth < 768 ? 20 : 40;
|
||||||
|
|
||||||
|
for (let i = 0; i < particleCount; i++) {
|
||||||
|
const particle = document.createElement('div');
|
||||||
|
particle.classList.add('particle');
|
||||||
|
|
||||||
|
const size = Math.random() * 4 + 1;
|
||||||
|
const posX = Math.random() * 100;
|
||||||
|
const posY = Math.random() * 100;
|
||||||
|
const delay = Math.random() * 10;
|
||||||
|
const duration = Math.random() * 10 + 10;
|
||||||
|
|
||||||
|
particle.style.width = `${size}px`;
|
||||||
|
particle.style.height = `${size}px`;
|
||||||
|
particle.style.left = `${posX}%`;
|
||||||
|
particle.style.top = `${posY}%`;
|
||||||
|
particle.style.animationDelay = `${delay}s`;
|
||||||
|
particle.style.animationDuration = `${duration}s`;
|
||||||
|
|
||||||
|
container.appendChild(particle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建扩散形状
|
||||||
|
export function createSpreadingShape() {
|
||||||
|
const shapesContainer = document.querySelector('.bg-shapes');
|
||||||
|
if (!shapesContainer) return;
|
||||||
|
|
||||||
|
const shape = document.createElement('div');
|
||||||
|
shape.classList.add('bg-shape');
|
||||||
|
|
||||||
|
const size = Math.random() * 450 + 200;
|
||||||
|
const posX = Math.random() * 100;
|
||||||
|
const posY = Math.random() * 100;
|
||||||
|
const duration = Math.random() * 6 + 4;
|
||||||
|
const delay = Math.random() * 1.5;
|
||||||
|
|
||||||
|
shape.style.width = `${size}px`;
|
||||||
|
shape.style.height = `${size}px`;
|
||||||
|
shape.style.left = `${posX}%`;
|
||||||
|
shape.style.top = `${posY}%`;
|
||||||
|
shape.style.animation = `spread ${duration}s ease-out forwards`;
|
||||||
|
shape.style.animationDelay = `${delay}s`;
|
||||||
|
|
||||||
|
shapesContainer.appendChild(shape);
|
||||||
|
|
||||||
|
// 动画结束后移除元素
|
||||||
|
setTimeout(() => {
|
||||||
|
shape.remove();
|
||||||
|
}, (duration + delay) * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定时创建扩散形状
|
||||||
|
export function startSpreadingShapes() {
|
||||||
|
createSpreadingShape();
|
||||||
|
setInterval(createSpreadingShape, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建流星效果
|
||||||
|
export function createMeteor() {
|
||||||
|
const container = document.querySelector('.bg-shapes');
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
const meteor = document.createElement('div');
|
||||||
|
meteor.classList.add('meteor');
|
||||||
|
|
||||||
|
const height = Math.random() * 150 + 100;
|
||||||
|
const angle = Math.random() * 30 + 45;
|
||||||
|
const posX = Math.random() * 100;
|
||||||
|
const posY = Math.random() * 30;
|
||||||
|
const duration = Math.random() * 2 + 1;
|
||||||
|
|
||||||
|
meteor.style.height = `${height}px`;
|
||||||
|
meteor.style.left = `${posX}%`;
|
||||||
|
meteor.style.top = `${posY}%`;
|
||||||
|
meteor.style.setProperty('--angle', `${angle}deg`);
|
||||||
|
meteor.style.animation = `meteor ${duration}s linear forwards`;
|
||||||
|
|
||||||
|
container.appendChild(meteor);
|
||||||
|
|
||||||
|
// 动画结束后移除元素
|
||||||
|
setTimeout(() => {
|
||||||
|
meteor.remove();
|
||||||
|
}, duration * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定时创建流星
|
||||||
|
export function startMeteors() {
|
||||||
|
setInterval(() => {
|
||||||
|
if (Math.random() > 0.7) { // 70%概率创建流星
|
||||||
|
createMeteor();
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user