M23环节1公告轮播+卡片交互+状态动态化完成
This commit is contained in:
parent
ebeee8c424
commit
e00171e073
123
homepage/app.js
123
homepage/app.js
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue