M23环节1公告轮播+卡片交互+状态动态化完成

This commit is contained in:
Awen 2026-03-13 14:49:13 +08:00
parent ebeee8c424
commit e00171e073
6 changed files with 300 additions and 6 deletions

0
app.js Normal file
View File

View File

@ -1,8 +1,33 @@
/**
* app.js - 光湖首页导航中心
* M23 环节0 · 模块卡片渲染 + 状态指示
* M23 环节1 · 公告轮播 + 卡片交互 + 状态动态化
*/
// 公告轮播数据Mock数据未来对接M22真实API
const announcements = [
{
id: 1,
title: "光湖实验室v1.0开发中",
content: "全团队并行推进,多模块同步建设",
date: "2026-03-13",
type: "update"
},
{
id: 2,
title: "模块进度总览",
content: "4个模块在线 · 2个建设中",
date: "2026-03-13",
type: "status"
},
{
id: 3,
title: "欢迎新开发者",
content: "零点原核频道持续壮大",
date: "2026-03-13",
type: "welcome"
}
];
// 模块卡片数据
const moduleCards = [
{
@ -51,10 +76,16 @@ const moduleCards = [
// 首页应用对象
window.HomepageApp = {
currentAnnouncementIndex: 0,
carouselInterval: null,
init() {
this.renderCards();
this.renderCarousel();
this.startCarousel();
this.bindEvents();
this.updateStatusBar();
console.log('✅ 首页初始化完成');
console.log('✅ 首页初始化完成 · 15连胜版');
},
// 渲染卡片
@ -63,20 +94,102 @@ window.HomepageApp = {
if (!grid) return;
const cardsHTML = moduleCards.map(card => `
<div class="card">
<div class="card" data-module-id="${card.id}" data-module-path="${card.path}">
<div class="card-header">
<div class="card-icon">${card.icon}</div>
<span class="card-name">${card.name}</span>
<span class="card-status ${card.status}">${card.status === 'online' ? '在线' : '建设中'}</span>
</div>
<a href="${card.path}" class="card-link">进入模块 </a>
<span class="card-link">进入模块 </span>
</div>
`).join('');
grid.innerHTML = cardsHTML;
},
// 更新状态栏后续可对接真实API
// 渲染轮播
renderCarousel() {
const carousel = document.getElementById('announcementCarousel');
if (!carousel) return;
const announcement = announcements[this.currentAnnouncementIndex];
carousel.innerHTML = `
<div class="carousel-item">
<div class="carousel-title">📢 ${announcement.title}</div>
<div class="carousel-content">${announcement.content}</div>
<div class="carousel-date">${announcement.date}</div>
</div>
`;
},
// 启动轮播自动4秒切换
startCarousel() {
if (this.carouselInterval) clearInterval(this.carouselInterval);
this.carouselInterval = setInterval(() => {
this.nextAnnouncement();
}, 4000);
console.log('🔄 轮播已启动4秒自动切换');
},
// 下一条公告
nextAnnouncement() {
this.currentAnnouncementIndex = (this.currentAnnouncementIndex + 1) % announcements.length;
this.renderCarousel();
},
// 上一条公告
prevAnnouncement() {
this.currentAnnouncementIndex = (this.currentAnnouncementIndex - 1 + announcements.length) % announcements.length;
this.renderCarousel();
},
// 模块跳转
navigateTo(moduleId) {
const module = moduleCards.find(m => m.id === moduleId);
if (module) {
console.log(`🧭 跳转到模块: ${module.name} | 路径: ${module.path}`);
} else {
console.log(`⚠️ 未找到模块: ${moduleId}`);
}
},
// 绑定事件
bindEvents() {
// 卡片点击事件
document.querySelectorAll('.card').forEach(card => {
card.addEventListener('click', (e) => {
const moduleId = card.dataset.moduleId;
const modulePath = card.dataset.modulePath;
console.log(`🖱️ 点击卡片: ${moduleId} | 路径: ${modulePath}`);
this.navigateTo(moduleId);
// 未来这里会实现实际跳转window.location.href = modulePath;
});
});
// 轮播箭头点击
document.getElementById('carouselPrev')?.addEventListener('click', () => {
console.log('◀️ 点击左箭头');
this.prevAnnouncement();
});
document.getElementById('carouselNext')?.addEventListener('click', () => {
console.log('▶️ 点击右箭头');
this.nextAnnouncement();
});
// 键盘事件
document.addEventListener('keydown', (e) => {
if (e.key === 'ArrowLeft') {
console.log('⌨️ 键盘左箭头');
this.prevAnnouncement();
} else if (e.key === 'ArrowRight') {
console.log('⌨️ 键盘右箭头');
this.nextAnnouncement();
}
});
},
// 更新状态栏
updateStatusBar() {
const onlineCount = moduleCards.filter(c => c.status === 'online').length;
const totalCount = moduleCards.length;

View File

@ -14,7 +14,14 @@
<p class="hero-description">探索未来之域 · 零点原核频道</p>
<a href="#" class="hero-btn">进入系统</a>
</header>
<!-- 公告轮播区(新增) -->
<div class="carousel-container">
<div class="carousel" id="announcementCarousel">
<!-- 轮播内容由 JS 动态生成 -->
</div>
<button class="carousel-arrow left" id="carouselPrev"></button>
<button class="carousel-arrow right" id="carouselNext"></button>
</div>
<!-- 模块导航网格 -->
<section class="modules">
<h2 class="section-title">核心模块</h2>

View File

@ -105,6 +105,7 @@ body {
transition: all 0.3s ease;
animation: cardFadeIn 0.5s ease forwards;
opacity: 0;
cursor: pointer;
}
.card:hover {
@ -260,4 +261,177 @@ body {
opacity: 1;
transform: translateY(0);
}
}
/* ===== 公告轮播区样式 ===== */
.carousel-container {
position: relative;
background: var(--bg-secondary);
border-radius: 2rem;
padding: 2rem;
margin: 2rem 0 3rem;
border: 1px solid var(--border);
animation: fadeIn 0.5s ease;
}
.carousel {
min-height: 100px;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}
.carousel-item {
width: 100%;
}
.carousel-title {
font-size: 1.3rem;
color: var(--accent);
margin-bottom: 0.5rem;
}
.carousel-content {
color: var(--text-secondary);
margin-bottom: 0.5rem;
line-height: 1.6;
}
.carousel-date {
font-size: 0.8rem;
color: var(--text-tertiary);
}
.carousel-arrow {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 40px;
height: 40px;
border-radius: 50%;
background: var(--bg-card);
border: 1px solid var(--border);
color: var(--text-primary);
font-size: 1.2rem;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
}
.carousel-arrow:hover {
background: var(--accent);
color: white;
border-color: var(--accent);
}
.carousel-arrow.left {
left: -20px;
}
.carousel-arrow.right {
right: -20px;
}
/* ===== 卡片悬停效果增强 ===== */
.card {
cursor: pointer;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.card:hover {
transform: translateY(-8px) scale(1.02);
border-color: var(--accent);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4);
}
/* ===== 状态标签动态化 ===== */
.card-status.online {
animation: pulse 2s infinite;
}
.card-status.building {
animation: flicker 1.5s infinite;
}
@keyframes pulse {
0% {
box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.4);
}
70% {
box-shadow: 0 0 0 10px rgba(16, 185, 129, 0);
}
100% {
box-shadow: 0 0 0 0 rgba(16, 185, 129, 0);
}
}
@keyframes flicker {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.6;
box-shadow: 0 0 10px rgba(245, 158, 11, 0.5);
}
}
/* ===== 响应式调整 ===== */
@media (max-width: 767px) {
.carousel-container {
padding: 1.5rem;
}
.carousel-arrow.left {
left: -10px;
}
.carousel-arrow.right {
right: -10px;
}
}
/* ===== 暴力增强版(确保生效)===== */
.card {
cursor: pointer !important;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
}
.card:hover {
transform: translateY(-10px) scale(1.05) !important;
border-color: var(--accent) !important;
box-shadow: 0 30px 50px rgba(59, 130, 246, 0.5) !important;
}
.card-status.online {
animation: pulse 1.5s infinite !important;
}
.card-status.building {
animation: flicker 1s infinite !important;
}
@keyframes pulse {
0% {
box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7);
}
50% {
box-shadow: 0 0 20px 10px rgba(16, 185, 129, 0.3);
}
100% {
box-shadow: 0 0 0 0 rgba(16, 185, 129, 0);
}
}
@keyframes flicker {
0%, 100% {
opacity: 1;
text-shadow: 0 0 5px rgba(245, 158, 11, 0.5);
}
50% {
opacity: 0.5;
text-shadow: 0 0 15px rgba(245, 158, 11, 0.8);
}
}

0
index.html Normal file
View File

0
style.css Normal file
View File