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,104 @@
<!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="theme-panel">
<div
class="theme-btn theme-default active"
data-theme="default"
title="深海蓝主题"
></div>
<div
class="theme-btn theme-light-btn"
data-theme="light"
title="浅色主题"
></div>
<div
class="theme-btn theme-purple-btn"
data-theme="purple"
title="深紫主题"
></div>
<div
class="theme-btn theme-green-btn"
data-theme="green"
title="绿色主题"
></div>
<div
class="theme-btn theme-red-btn"
data-theme="red"
title="红色主题"
></div>
<div
class="theme-btn theme-orange-btn"
data-theme="orange"
title="橙色主题"
></div>
<div
class="theme-btn theme-pink-btn"
data-theme="pink"
title="粉色主题"
></div>
<div
class="theme-btn theme-gold-btn"
data-theme="gold"
title="金色主题"
></div>
<div
class="theme-btn theme-tech-btn"
data-theme="tech"
title="科技蓝主题"
></div>
<div
class="theme-btn theme-dark-minimal-btn"
data-theme="dark-minimal"
title="深色简约"
></div>
<div
class="theme-btn theme-sunset-btn"
data-theme="sunset"
title="日落主题"
></div>
</div>
<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>席位赞助</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,136 @@
// 自动更新年份
document.getElementById(
"footerText"
).innerHTML = `© ${new Date().getFullYear()} Tootaio.com 保留所有权利。| 由 <a href="https://tootaio.com" target="_blank" rel="noopener">Tootaio</a> 制作。`;
// 主题切换功能
const themeButtons = document.querySelectorAll(".theme-btn");
const body = document.body;
themeButtons.forEach((button) => {
button.addEventListener("click", () => {
const theme = button.getAttribute("data-theme");
// 移除所有主题类
body.classList.remove(
"theme-default",
"theme-light",
"theme-purple",
"theme-green",
"theme-red",
"theme-orange",
"theme-pink",
"theme-gold",
"theme-tech",
"theme-dark-minimal",
"theme-sunset"
);
// 添加所选主题类
if (theme !== "default") {
body.classList.add(`theme-${theme}`);
}
// 更新活动按钮状态
themeButtons.forEach((btn) => btn.classList.remove("active"));
button.classList.add("active");
// 保存主题到本地存储
localStorage.setItem("selectedTheme", theme);
});
});
// 检查本地存储中的主题偏好
const savedTheme = localStorage.getItem("selectedTheme");
if (savedTheme) {
const themeButton = document.querySelector(
`.theme-btn[data-theme="${savedTheme}"]`
);
if (themeButton) {
themeButton.click();
}
}
// 页面初始化
function initSponsorsAndSeats(sponsors, seats) {
const moneyList = document.getElementById("moneyList");
const seatList = document.getElementById("seatList");
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,474 @@
:root {
/* 默认主题 - 深海蓝 */
--primary-bg: linear-gradient(135deg, #0f1c30, #1a2a6c);
--card-bg: rgba(0, 0, 0, 0.3);
--primary-text: #ffffff;
--accent-color: #4fc3f7;
--secondary-accent: #ffd700;
--header-color: #ffd700;
--stats-color: #4fc3f7;
--item-bg: rgba(255, 255, 255, 0.05);
--sponsor-border: #4fc3f7;
--seat-border: #ffd700;
--shadow-color: rgba(0, 0, 0, 0.5);
}
/* 浅色主题 */
.theme-light {
--primary-bg: linear-gradient(135deg, #f5f7fa, #e4e8f0);
--card-bg: rgba(255, 255, 255, 0.8);
--primary-text: #2d3748;
--accent-color: #3182ce;
--secondary-accent: #d69e2e;
--header-color: #2b6cb0;
--stats-color: #4a5568;
--item-bg: rgba(0, 0, 0, 0.05);
--sponsor-border: #3182ce;
--seat-border: #d69e2e;
--shadow-color: rgba(0, 0, 0, 0.1);
}
/* 深紫色主题 */
.theme-purple {
--primary-bg: linear-gradient(135deg, #1a1a2e, #4a154b);
--card-bg: rgba(0, 0, 0, 0.4);
--primary-text: #f0e6ef;
--accent-color: #9f7aea;
--secondary-accent: #faf089;
--header-color: #faf089;
--stats-color: #9f7aea;
--item-bg: rgba(255, 255, 255, 0.08);
--sponsor-border: #9f7aea;
--seat-border: #faf089;
--shadow-color: rgba(0, 0, 0, 0.6);
}
/* 绿色主题 */
.theme-green {
--primary-bg: linear-gradient(135deg, #0a2f1d, #1a3c2b);
--card-bg: rgba(0, 0, 0, 0.35);
--primary-text: #e6fffa;
--accent-color: #38b2ac;
--secondary-accent: #fefcbf;
--header-color: #fefcbf;
--stats-color: #38b2ac;
--item-bg: rgba(255, 255, 255, 0.06);
--sponsor-border: #38b2ac;
--seat-border: #fefcbf;
--shadow-color: rgba(0, 0, 0, 0.55);
}
/* 红色主题 */
.theme-red {
--primary-bg: linear-gradient(135deg, #2a0e0e, #8b0000);
--card-bg: rgba(0, 0, 0, 0.4);
--primary-text: #ffe6e6;
--accent-color: #ff6b6b;
--secondary-accent: #ffd93d;
--header-color: #ffd93d;
--stats-color: #ff6b6b;
--item-bg: rgba(255, 255, 255, 0.08);
--sponsor-border: #ff6b6b;
--seat-border: #ffd93d;
--shadow-color: rgba(0, 0, 0, 0.6);
}
/* 橙色主题 */
.theme-orange {
--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);
}
/* 粉色主题 */
.theme-pink {
--primary-bg: linear-gradient(135deg, #2e1a2e, #8a2be2);
--card-bg: rgba(0, 0, 0, 0.4);
--primary-text: #fce4ec;
--accent-color: #ff6ec7;
--secondary-accent: #a5d6ff;
--header-color: #a5d6ff;
--stats-color: #ff6ec7;
--item-bg: rgba(255, 255, 255, 0.08);
--sponsor-border: #ff6ec7;
--seat-border: #a5d6ff;
--shadow-color: rgba(0, 0, 0, 0.6);
}
/* 金色奢华主题 */
.theme-gold {
--primary-bg: linear-gradient(135deg, #1a1818, #4a3c2a);
--card-bg: rgba(0, 0, 0, 0.5);
--primary-text: #f8ecc9;
--accent-color: #c5a572;
--secondary-accent: #ffd700;
--header-color: #ffd700;
--stats-color: #c5a572;
--item-bg: rgba(200, 170, 100, 0.1);
--sponsor-border: #c5a572;
--seat-border: #ffd700;
--shadow-color: rgba(0, 0, 0, 0.7);
}
/* 科技蓝主题 */
.theme-tech {
--primary-bg: linear-gradient(135deg, #001425, #003a5d);
--card-bg: rgba(0, 30, 60, 0.6);
--primary-text: #e0f7ff;
--accent-color: #00c8ff;
--secondary-accent: #00ffcc;
--header-color: #00ffcc;
--stats-color: #00c8ff;
--item-bg: rgba(0, 200, 255, 0.1);
--sponsor-border: #00c8ff;
--seat-border: #00ffcc;
--shadow-color: rgba(0, 40, 80, 0.7);
}
/* 深色简约主题 */
.theme-dark-minimal {
--primary-bg: linear-gradient(135deg, #0a0a0a, #2d2d2d);
--card-bg: rgba(40, 40, 40, 0.7);
--primary-text: #e0e0e0;
--accent-color: #7c7c7c;
--secondary-accent: #ffffff;
--header-color: #ffffff;
--stats-color: #7c7c7c;
--item-bg: rgba(255, 255, 255, 0.05);
--sponsor-border: #7c7c7c;
--seat-border: #ffffff;
--shadow-color: rgba(0, 0, 0, 0.8);
}
/* 日落主题 */
.theme-sunset {
--primary-bg: linear-gradient(135deg, #0f1c30, #e25822);
--card-bg: rgba(0, 0, 0, 0.4);
--primary-text: #fff5e6;
--accent-color: #ff8c42;
--secondary-accent: #ffd93d;
--header-color: #ffd93d;
--stats-color: #ff8c42;
--item-bg: rgba(255, 255, 255, 0.08);
--sponsor-border: #ff8c42;
--seat-border: #ffd93d;
--shadow-color: rgba(0, 0, 0, 0.6);
}
* {
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;
}
.theme-panel {
position: fixed;
top: 50%;
right: 20px;
transform: translateY(-50%);
display: flex;
flex-direction: column;
gap: 12px;
z-index: 100;
background: var(--card-bg);
padding: 15px;
border-radius: 20px;
box-shadow: 0 5px 20px var(--shadow-color);
backdrop-filter: blur(5px);
}
.theme-btn {
width: 30px;
height: 30px;
border-radius: 50%;
border: 2px solid var(--primary-text);
cursor: pointer;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.theme-btn:hover {
transform: scale(1.15);
box-shadow: 0 0 10px var(--secondary-accent);
}
.theme-btn.active {
transform: scale(1.2);
box-shadow: 0 0 15px var(--secondary-accent);
}
.theme-default {
background: linear-gradient(135deg, #0f1c30, #1a2a6c);
}
.theme-light-btn {
background: linear-gradient(135deg, #f5f7fa, #e4e8f0);
}
.theme-purple-btn {
background: linear-gradient(135deg, #1a1a2e, #4a154b);
}
.theme-green-btn {
background: linear-gradient(135deg, #0a2f1d, #1a3c2b);
}
.theme-red-btn {
background: linear-gradient(135deg, #2a0e0e, #8b0000);
}
.theme-orange-btn {
background: linear-gradient(135deg, #332211, #cc5500);
}
.theme-pink-btn {
background: linear-gradient(135deg, #2e1a2e, #8a2be2);
}
.theme-gold-btn {
background: linear-gradient(135deg, #1a1818, #4a3c2a);
}
.theme-tech-btn {
background: linear-gradient(135deg, #001425, #003a5d);
}
.theme-dark-minimal-btn {
background: linear-gradient(135deg, #0a0a0a, #2d2d2d);
}
.theme-sunset-btn {
background: linear-gradient(135deg, #0f1c30, #e25822);
}
.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 40s 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;
}
.theme-panel {
top: auto;
bottom: 20px;
right: 20px;
flex-direction: row;
transform: none;
}
}