feat(sponsor-list): implement new design with animated canvas background

This commit introduces a completely redesigned sponsor list page. The previous two-column layout is replaced with a
modern, single-column auto-scrolling list that unifies all sponsors. A dynamic canvas animation has been added to the
background for a more engaging visual experience. Previous versions of the page have been archived. This update also
includes data corrections for sponsor names and minor fixes to the related PPT assets.
This commit is contained in:
xiaomai
2025-09-16 23:48:44 +08:00
parent 71b2dcf0a5
commit bcbae992a3
16 changed files with 612 additions and 350 deletions

View File

@@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>赞助人名单</title>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
/>
<link rel="stylesheet" href="style.css" />
</head>
<body class="theme-default">
<div class="container">
<div class="header">
<h1>赞助人名单</h1>
<!-- <p class="subtitle">衷心感谢以下企业及个人的慷慨赞助</p> -->
<!--
<div class="stats">
<div id="totalSponsors"><i class="fas fa-users"></i> 赞助单位: 0</div>
<div id="totalAmount"><i class="fas fa-coins"></i> 总金额: RM 0</div>
<div id="totalSeats"><i class="fas fa-chair"></i> 席位总数: 0</div>
</div>
-->
</div>
<div class="main-content">
<div class="section">
<h2>赞助金额</h2>
<div class="scroll-container">
<div class="scroll-content" id="moneyList"></div>
</div>
</div>
<div class="section">
<h2>席位赞助 (RM2000)</h2>
<div class="scroll-container">
<div class="scroll-content" id="seatList"></div>
</div>
</div>
</div>
<div class="footer">
<p id="footerText">感谢所有赞助商对本次活动的大力支持 | 2023年</p>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

View File

@@ -0,0 +1,92 @@
// 自动更新年份
document.getElementById(
"footerText"
).innerHTML = `© ${new Date().getFullYear()} Tootaio.com 保留所有权利。| 由 <a href="https://tootaio.com" target="_blank" rel="noopener">Tootaio</a> 制作。`;
// 页面初始化
function initSponsorsAndSeats(sponsors, seats) {
const moneyList = document.getElementById("moneyList");
const seatList = document.getElementById("seatList");
// Sort by amount descending
sponsors.sort((a, b) => parseFloat(b.amount) - parseFloat(a.amount));
seats.sort((a, b) => parseInt(b.seat) - parseInt(a.seat));
let totalAmount = 0;
sponsors.forEach((s) => {
totalAmount += parseFloat(s.amount);
const div = document.createElement("div");
div.className = "sponsor-item";
div.innerHTML = `<span>${s.name}</span><span class="amount">RM ${Number(
s.amount
).toLocaleString()}</span>`;
moneyList.appendChild(div);
});
// 复制一份实现无缝滚动
moneyList.innerHTML += moneyList.innerHTML;
let totalSeats = 0;
seats.forEach((s) => {
totalSeats += parseInt(s.seat);
const div = document.createElement("div");
div.className = "seat-item";
div.innerHTML = `<span>${s.name}</span><span class="amount">${s.seat} 席</span>`;
seatList.appendChild(div);
});
seatList.innerHTML += seatList.innerHTML;
// 更新统计数据
const totalSponsors = document.getElementById("totalSponsors");
if (totalSponsors) {
totalSponsors.innerHTML = ""; // 清空现有内容
var totalSponsorsIcon = document.createElement("i");
totalSponsorsIcon.className = "fas fa-users";
totalSponsors.prepend(totalSponsorsIcon);
totalSponsors.appendChild(
document.createTextNode(` 赞助单位: ${sponsors.length}`)
);
}
const totalAmountEl = document.getElementById("totalAmount");
totalAmountEl.innerHTML = ""; // 清空现有内容
var totalAmountIcon = document.createElement("i");
totalAmountIcon.className = "fas fa-coins";
totalAmountEl.prepend(totalAmountIcon);
totalAmountEl.appendChild(
document.createTextNode(` 总金额: RM ${totalAmount.toLocaleString()}`)
);
const totalSeatsEl = document.getElementById("totalSeats");
if (totalSeatsEl) {
totalSeatsEl.innerHTML = ""; // 清空现有内容
var totalSeatsIcon = document.createElement("i");
totalSeatsIcon.className = "fas fa-chair";
totalSeatsEl.prepend(totalSeatsIcon);
totalSeatsEl.appendChild(
document.createTextNode(` 席位总数: ${totalSeats}`)
);
}
}
// 🚀 动态加载 JSON 数据
Promise.all([
fetch("../data/sponsors.json").then((res) => res.json()),
fetch("../data/seats.json").then((res) => res.json()),
])
.then(([sponsors, seats]) => {
initSponsorsAndSeats(sponsors, seats);
})
.catch((err) => {
console.error("加载 JSON 数据失败,回退到本地 mock 数据", err);
// 备用 mock 数据(防止页面空白)
const mockSponsors = [
{ name: "亮湘厨中国烧烤", amount: 8000 },
{ name: "星空科技集团", amount: 15000 },
{ name: "未来教育基金会", amount: 20000 },
];
const mockSeats = [
{ name: "郑来兴", seat: 1 },
{ name: "未来教育基金会", seat: 5 },
];
initSponsorsAndSeats(mockSponsors, mockSeats);
});

View File

@@ -0,0 +1,237 @@
:root {
/* 橙色主题 */
--primary-bg: linear-gradient(135deg, #332211, #cc5500);
--card-bg: rgba(0, 0, 0, 0.35);
--primary-text: #fff5e6;
--accent-color: #ff8c42;
--secondary-accent: #ffd700;
--header-color: #ffd700;
--stats-color: #ff8c42;
--item-bg: rgba(255, 255, 255, 0.07);
--sponsor-border: #ff8c42;
--seat-border: #ffd700;
--shadow-color: rgba(0, 0, 0, 0.55);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
transition: background-color 0.5s ease, color 0.5s ease, transform 0.3s ease;
}
body {
background: var(--primary-bg);
color: var(--primary-text);
font-family: "Microsoft YaHei", sans-serif;
padding: 20px;
overflow-x: hidden;
min-height: 100vh;
}
.container {
max-width: 1800px;
margin: auto;
position: relative;
}
.header,
.footer {
text-align: center;
padding: 30px;
background: var(--card-bg);
border-radius: 20px;
box-shadow: 0 10px 30px var(--shadow-color);
backdrop-filter: blur(10px);
margin-bottom: 30px;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.footer {
margin-top: 30px;
padding: 20px;
}
h1 {
font-size: 2rem;
color: var(--header-color);
margin-bottom: 15px;
text-shadow: 0 2px 10px var(--shadow-color);
letter-spacing: 1.5px;
}
a {
color: var(--accent-color);
text-decoration: none;
transition: color 0.3s ease;
}
.subtitle {
font-size: 1.5rem;
color: var(--primary-text);
opacity: 0.9;
margin-bottom: 25px;
}
.stats {
display: flex;
justify-content: center;
gap: 50px;
margin: 25px 0;
}
.stats div {
font-size: 3rem;
color: var(--stats-color);
font-weight: bold;
display: flex;
align-items: center;
gap: 12px;
padding: 12px 20px;
background: var(--item-bg);
border-radius: 12px;
}
.stats i {
font-size: 2.2rem;
}
.main-content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 30px;
margin-top: 20px;
}
.section {
background: var(--card-bg);
border-radius: 20px;
padding: 30px;
height: 650px;
position: relative;
overflow: hidden;
box-shadow: 0 10px 30px var(--shadow-color);
backdrop-filter: blur(5px);
border: 1px solid rgba(255, 255, 255, 0.1);
}
.section h2 {
text-align: center;
color: var(--accent-color);
margin-bottom: 25px;
font-size: 2.4rem;
text-shadow: 0 1px 5px var(--shadow-color);
position: relative;
padding-bottom: 12px;
}
.section h2:after {
content: "";
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 100px;
height: 4px;
background: var(--secondary-accent);
border-radius: 4px;
}
.scroll-container {
height: 540px;
overflow: hidden;
position: relative;
border-radius: 15px;
margin-top: 15px;
}
.scroll-content {
position: absolute;
width: 100%;
}
.sponsor-item,
.seat-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 18px 25px;
margin: 15px 0;
background: var(--item-bg);
border-radius: 12px;
font-size: 1.7rem;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.sponsor-item:hover,
.seat-item:hover {
transform: translateY(-3px);
box-shadow: 0 8px 20px var(--shadow-color);
}
.sponsor-item {
border-left: 6px solid var(--sponsor-border);
}
.seat-item {
border-left: 6px solid var(--seat-border);
}
.amount {
color: var(--secondary-accent);
font-weight: bold;
font-size: 1.8rem;
}
.scroll-content {
animation: scroll 200s linear infinite;
}
.scroll-content:hover {
animation-play-state: paused;
}
@keyframes scroll {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-50%);
}
}
/* 响应式设计 */
@media (max-width: 1200px) {
.main-content {
grid-template-columns: 1fr;
}
h1 {
font-size: 3rem;
}
.stats {
gap: 20px;
}
}
@media (max-width: 768px) {
.stats {
flex-direction: column;
gap: 15px;
}
.header,
.footer {
padding: 20px;
}
.section {
padding: 20px;
height: 500px;
}
.scroll-container {
height: 400px;
}
}