From bcbae992a316bf5b40333b3f033a8d955831179a Mon Sep 17 00:00:00 2001 From: xiaomai Date: Tue, 16 Sep 2025 23:48:44 +0800 Subject: [PATCH] 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. --- .gitignore | 1 + .../index.html | 0 .../script.js | 0 .../style.css | 0 20250916/archive/sponsor-list-v2/index.html | 48 +++ 20250916/archive/sponsor-list-v2/script.js | 92 ++++++ 20250916/archive/sponsor-list-v2/style.css | 237 +++++++++++++ 20250916/data/seats.json | 8 +- 20250916/data/sponsors.json | 2 +- 20250916/ppt/config/banquet.json | 14 +- 20250916/ppt/templates/cover.css | 2 +- 20250916/ppt/templates/cover.html | 4 +- 20250916/ppt/templates/speech.css | 3 +- 20250916/sponsor-list/index.html | 49 +-- 20250916/sponsor-list/script.js | 191 ++++++----- 20250916/sponsor-list/style.css | 311 ++++++------------ 16 files changed, 612 insertions(+), 350 deletions(-) create mode 100644 .gitignore rename 20250916/archive/{sponsor-list => sponsor-list-v1}/index.html (100%) rename 20250916/archive/{sponsor-list => sponsor-list-v1}/script.js (100%) rename 20250916/archive/{sponsor-list => sponsor-list-v1}/style.css (100%) create mode 100644 20250916/archive/sponsor-list-v2/index.html create mode 100644 20250916/archive/sponsor-list-v2/script.js create mode 100644 20250916/archive/sponsor-list-v2/style.css diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..600d2d3 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vscode \ No newline at end of file diff --git a/20250916/archive/sponsor-list/index.html b/20250916/archive/sponsor-list-v1/index.html similarity index 100% rename from 20250916/archive/sponsor-list/index.html rename to 20250916/archive/sponsor-list-v1/index.html diff --git a/20250916/archive/sponsor-list/script.js b/20250916/archive/sponsor-list-v1/script.js similarity index 100% rename from 20250916/archive/sponsor-list/script.js rename to 20250916/archive/sponsor-list-v1/script.js diff --git a/20250916/archive/sponsor-list/style.css b/20250916/archive/sponsor-list-v1/style.css similarity index 100% rename from 20250916/archive/sponsor-list/style.css rename to 20250916/archive/sponsor-list-v1/style.css diff --git a/20250916/archive/sponsor-list-v2/index.html b/20250916/archive/sponsor-list-v2/index.html new file mode 100644 index 0000000..fb02d56 --- /dev/null +++ b/20250916/archive/sponsor-list-v2/index.html @@ -0,0 +1,48 @@ + + + + + + 赞助人名单 + + + + +
+
+

赞助人名单

+ + +
+ +
+
+

赞助金额

+
+
+
+
+
+

席位赞助 (RM2000)

+
+
+
+
+
+ + +
+ + + diff --git a/20250916/archive/sponsor-list-v2/script.js b/20250916/archive/sponsor-list-v2/script.js new file mode 100644 index 0000000..c194c13 --- /dev/null +++ b/20250916/archive/sponsor-list-v2/script.js @@ -0,0 +1,92 @@ +// 自动更新年份 +document.getElementById( + "footerText" +).innerHTML = `© ${new Date().getFullYear()} Tootaio.com 保留所有权利。| 由 Tootaio 制作。`; + +// 页面初始化 +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 = `${s.name}RM ${Number( + s.amount + ).toLocaleString()}`; + 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 = `${s.name}${s.seat} 席`; + 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); + }); diff --git a/20250916/archive/sponsor-list-v2/style.css b/20250916/archive/sponsor-list-v2/style.css new file mode 100644 index 0000000..040879a --- /dev/null +++ b/20250916/archive/sponsor-list-v2/style.css @@ -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; + } +} diff --git a/20250916/data/seats.json b/20250916/data/seats.json index 3ee8972..0fed790 100644 --- a/20250916/data/seats.json +++ b/20250916/data/seats.json @@ -9,7 +9,7 @@ { "name": "颜凯伟", "seat": 1 }, { "name": "陈家晟", "seat": 1 }, { "name": "永和工业有限公司", "seat": 1 }, - { "name": "三泰kopitiam", "seat": 1 }, + { "name": "三泰 Kopitiam", "seat": 1 }, { "name": "林文庆", "seat": 1 }, { "name": "居銮dw", "seat": 1 }, { "name": "居銮阿童", "seat": 1 }, @@ -29,19 +29,19 @@ { "name": "鼎盛集团", "seat": 1 }, { "name": "潘联国", "seat": 1 }, { "name": "刘云鳞", "seat": 1 }, - { "name": "klevin ou", "seat": 1 }, + { "name": "Klevin Ou", "seat": 1 }, { "name": "吴厚雄", "seat": 1 }, { "name": "黄金林", "seat": 1 }, { "name": "Sin Chu Hin BP", "seat": 1 }, { "name": "LT Group", "seat": 1 }, - { "name": "永平天保公", "seat": 1 }, + { "name": "永平天保宮", "seat": 1 }, { "name": "永平福满家美食阁", "seat": 1 }, { "name": "颜汉龙", "seat": 1 }, { "name": "明義柅轮电池服务", "seat": 1 }, { "name": "MDL AUTO WERKZ", "seat": 1 }, { "name": "柔中汽车机件有限公司", "seat": 1 }, { "name": "永兴石灰", "seat": 1 }, - { "name": "winbox", "seat": 1 }, + { "name": "Winbox", "seat": 1 }, { "name": "南利企业", "seat": 1 }, { "name": "戴祖发", "seat": 1 }, { "name": "大丰洪顺堂", "seat": 1 }, diff --git a/20250916/data/sponsors.json b/20250916/data/sponsors.json index f462daa..3d71fdd 100644 --- a/20250916/data/sponsors.json +++ b/20250916/data/sponsors.json @@ -37,7 +37,7 @@ { "name": "林22", "amount": 500 }, { "name": "謝明忠", "amount": 500 }, { "name": "許忠礼", "amount": 500 }, - { "name": "four season fruity sdn bhd", "amount": 500 }, + { "name": "Four Season Fruity Sdn Bhd", "amount": 500 }, { "name": "陈文毅", "amount": 500 }, { "name": "青海茶餐室", "amount": 500 }, { "name": "八子", "amount": 200 } diff --git a/20250916/ppt/config/banquet.json b/20250916/ppt/config/banquet.json index 5c2c28f..490db59 100644 --- a/20250916/ppt/config/banquet.json +++ b/20250916/ppt/config/banquet.json @@ -1,16 +1,10 @@ { - "manifest": "/templates/manifest.json", + "manifest": "./templates/manifest.json", "slides": [ { "type": "cover", "template": "cover", - "data": { - "title": "柔佛永平关圣公联谊会", - "subtitle": "筹募活动基金联欢晚会", - "date": "2025年9月16日", - "location": "永平富华冷气酒家" - }, - "background": "https://picsum.photos/1920/1080?grayscale" + "background": "./images/Background.jpg" }, { "type": "speech", @@ -22,7 +16,7 @@ "avatar": "images/林添顺.jpg", "bio": "马华公会(MCA)领袖,现任柔佛州永平区州议员兼州行政议会卫生及环境委员会主席。青年政治人物,积极推动民生与公共服务改善,关注教育、环境及社区发展。" }, - "background": "https://picsum.photos/1920/1080?grayscale&random=1", + "background": "./images/blank.jpg", "overrideCss": "overrides/zhanghua.css" }, { @@ -34,7 +28,7 @@ "avatar": "images/关圣公致辞2.jpg", "bio": "嘉宾介绍" }, - "background": "https://picsum.photos/1920/1080?grayscale&random=2", + "background": "./images/blank.jpg", "overrideCss": "overrides/limei.css" } ] diff --git a/20250916/ppt/templates/cover.css b/20250916/ppt/templates/cover.css index fa31ab5..a22f7f6 100644 --- a/20250916/ppt/templates/cover.css +++ b/20250916/ppt/templates/cover.css @@ -3,7 +3,7 @@ height: 100%; display: flex; position: relative; - background: linear-gradient(rgba(0, 0, 0, 0.45), rgba(0, 0, 0, 0.45)); + /* background: linear-gradient(rgba(0, 0, 0, 0.45), rgba(0, 0, 0, 0.45)); */ } .cover-inner { diff --git a/20250916/ppt/templates/cover.html b/20250916/ppt/templates/cover.html index a256007..d4d36a9 100644 --- a/20250916/ppt/templates/cover.html +++ b/20250916/ppt/templates/cover.html @@ -1,10 +1,10 @@
-
+
diff --git a/20250916/ppt/templates/speech.css b/20250916/ppt/templates/speech.css index eeb6fde..cada86e 100644 --- a/20250916/ppt/templates/speech.css +++ b/20250916/ppt/templates/speech.css @@ -17,8 +17,9 @@ width: 90%; box-shadow: 0 25px 50px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 215, 0, 0.1); border: 1px solid rgba(255, 255, 255, 0.08); - position: relative; + position: absolute; overflow: hidden; + top: 50%; } .speech-card::before { diff --git a/20250916/sponsor-list/index.html b/20250916/sponsor-list/index.html index fb02d56..a37fb85 100644 --- a/20250916/sponsor-list/index.html +++ b/20250916/sponsor-list/index.html @@ -1,47 +1,20 @@ - + - 赞助人名单 - - + Sponsor List + - + + +
-
-

赞助人名单

- - -
- -
-
-

赞助金额

-
-
-
-
-
-

席位赞助 (RM2000)

-
-
-
-
-
- - +
+

柔 佛 永 平 關 聖 宮 聯 誼 會

+

赞助者名单 Sponsor List

+
+
diff --git a/20250916/sponsor-list/script.js b/20250916/sponsor-list/script.js index c194c13..36f903e 100644 --- a/20250916/sponsor-list/script.js +++ b/20250916/sponsor-list/script.js @@ -1,92 +1,115 @@ -// 自动更新年份 -document.getElementById( - "footerText" -).innerHTML = `© ${new Date().getFullYear()} Tootaio.com 保留所有权利。| 由 Tootaio 制作。`; - -// 页面初始化 -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 = `${s.name}RM ${Number( - s.amount - ).toLocaleString()}`; - 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 = `${s.name}${s.seat} 席`; - 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}`) - ); - } +/** + * 格式化金额,默认 MYR (RM) + * @param {Number|String} amount 金额 + * @param {String} currency 币种(ISO 4217),默认 MYR + * @param {String} locale 语言地区,默认 "ms-MY" + * @returns {String} 格式化后的金额 + */ +function formatCurrency(amount, currency = "MYR", locale = "ms-MY") { + const num = Number(amount); + if (isNaN(num)) return String(amount); // 非数字直接返回原值 + return new Intl.NumberFormat(locale, { + style: "currency", + currency, + }).format(num); } -// 🚀 动态加载 JSON 数据 +const sponsorListDiv = document.getElementById("sponsorList"); + 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); +]).then(([sponsors, seats]) => { + const sponsorList = sponsors.map((item) => ({ + name: item.name, + amount: formatCurrency(item.amount), // 使用 Intl API + })); - // 备用 mock 数据(防止页面空白) - const mockSponsors = [ - { name: "亮湘厨中国烧烤", amount: 8000 }, - { name: "星空科技集团", amount: 15000 }, - { name: "未来教育基金会", amount: 20000 }, - ]; - const mockSeats = [ - { name: "郑来兴", seat: 1 }, - { name: "未来教育基金会", seat: 5 }, - ]; + const seatList = seats.map((item) => ({ + name: item.name, + amount: `${item.seat} 席`, + })); - initSponsorsAndSeats(mockSponsors, mockSeats); + [...sponsorList, ...seatList].forEach((entry) => { + const card = document.createElement("div"); + card.className = "sponsor-item card"; + card.innerHTML = `

${entry.name}

${entry.amount}

`; + sponsorListDiv.appendChild(card); }); +}); + +// ================= Canvas 背景 ================= +const canvas = document.getElementById("background"); +const ctx = canvas.getContext("2d"); + +function resizeCanvas() { + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; +} +resizeCanvas(); +window.addEventListener("resize", resizeCanvas); + +class Point { + constructor() { + this.radius = Math.random() * 4 + 2; + this.x = Math.random() * canvas.width; + this.y = Math.random() * canvas.height; + this.xSpeed = (Math.random() - 0.5) * 60; + this.ySpeed = (Math.random() - 0.5) * 60; + this.color = `hsl(${Math.random() * 360}, 100%, 50%)`; + this.lastDrawTime = null; + } + + draw() { + const now = Date.now(); + if (this.lastDrawTime) { + const dt = (now - this.lastDrawTime) / 1000; + this.x += this.xSpeed * dt; + this.y += this.ySpeed * dt; + } + if (this.x < 0 || this.x > canvas.width) this.xSpeed *= -1; + if (this.y < 0 || this.y > canvas.height) this.ySpeed *= -1; + + ctx.beginPath(); + ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2); + ctx.fillStyle = this.color; + ctx.shadowBlur = 15; + ctx.shadowColor = this.color; + ctx.fill(); + this.lastDrawTime = now; + } +} + +class Graph { + constructor(pointCount = 70, maxDistance = 120) { + this.points = Array.from({ length: pointCount }, () => new Point()); + this.maxDist = maxDistance; + } + + draw() { + requestAnimationFrame(() => this.draw()); + ctx.clearRect(0, 0, canvas.width, canvas.height); + + for (let i = 0; i < this.points.length; i++) { + const p1 = this.points[i]; + p1.draw(); + for (let j = i + 1; j < this.points.length; j++) { + const p2 = this.points[j]; + const dx = p1.x - p2.x; + const dy = p1.y - p2.y; + const dist = Math.sqrt(dx * dx + dy * dy); + if (dist < this.maxDist) { + const alpha = 1 - dist / this.maxDist; + ctx.beginPath(); + ctx.moveTo(p1.x, p1.y); + ctx.lineTo(p2.x, p2.y); + ctx.strokeStyle = `rgba(255, 255, 255, ${alpha})`; + ctx.lineWidth = 2 * alpha; + ctx.stroke(); + } + } + } + } +} + +new Graph().draw(); diff --git a/20250916/sponsor-list/style.css b/20250916/sponsor-list/style.css index 5bcb1ec..e91f95b 100644 --- a/20250916/sponsor-list/style.css +++ b/20250916/sponsor-list/style.css @@ -1,237 +1,130 @@ -: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; + margin: 0; + padding: 0; + font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, + Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; + color: #fff; + overflow: hidden; /* 隐藏全局滚动条 */ +} + +canvas { + position: fixed; + top: 0; + left: 0; + z-index: -1; + width: 100vw; + height: 100vh; + background: linear-gradient(270deg, #600000, #606000); + background-size: 600% 600%; + /* animation: background 30s ease infinite; */ + background: url("sponsor-bg.jpg") no-repeat center center fixed; + background-size: cover; } .container { - max-width: 1800px; - margin: auto; - position: relative; + width: 100%; + overflow: hidden; + position: relative; + box-sizing: border-box; } -.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); +header { + text-align: center; + margin: 0 0 20px; + position: sticky; /* 保持在页面顶部 */ + top: 0; + z-index: 1; /* 确保在滚动列表之上 */ + padding: 10px 0; + background-color: rgb(48, 0, 0, 0.3); + box-shadow: 0px 8px 4px 2px rgba(0, 0, 0, 0.5); } -.footer { - margin-top: 30px; - padding: 20px; +header h1 { + font-size: 3rem; + color: #f1c40f; + text-shadow: 0 0 10px #f39c12; + animation: pulse 3s infinite alternate ease-in-out; } -h1 { - font-size: 2rem; - color: var(--header-color); - margin-bottom: 15px; - text-shadow: 0 2px 10px var(--shadow-color); - letter-spacing: 1.5px; +header h2 { + text-align: center; + font-size: 2rem; + margin: 0 0 20px; + color: #87f10f; + text-shadow: 0 0 10px #25f312; + animation: bounce 1.5s infinite alternate ease-in-out; } -a { - color: var(--accent-color); - text-decoration: none; - transition: color 0.3s ease; +.card { + margin: 32px auto; + padding: 16px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + backdrop-filter: blur(5px); + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2); + width: 90%; + text-align: center; + transition: transform 0.3s ease, box-shadow 0.3s ease; } -.subtitle { - font-size: 1.5rem; - color: var(--primary-text); - opacity: 0.9; - margin-bottom: 25px; +.card:hover { + transform: scale(1.05); + box-shadow: 0 8px 15px rgba(0, 0, 0, 0.3); } -.stats { - display: flex; - justify-content: center; - gap: 50px; - margin: 25px 0; +.sponsor-item h2 { + font-size: 4.5rem; + margin: 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; +.sponsor-item p { + font-size: 4rem; + margin: 0; + color: #f1c40f; + font-weight: bolder; } -.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; +.scrolling-list { + display: flex; + flex-direction: column; + animation: scroll 240s linear infinite; + overflow: hidden; /* 确保列表自身不显示滚动条 */ } @keyframes scroll { - 0% { - transform: translateY(0); - } - 100% { - transform: translateY(-50%); - } + 0% { + transform: translateY(3%); + } + + 100% { + transform: translateY(-100%); + } } -/* 响应式设计 */ -@media (max-width: 1200px) { - .main-content { - grid-template-columns: 1fr; - } - - h1 { - font-size: 3rem; - } - - .stats { - gap: 20px; - } +@keyframes pulse { + 0% { + transform: scale(1); + text-shadow: 0 0 10px #f39c12, 0 0 20px #f39c12; + } + 100% { + transform: scale(1.2); + text-shadow: 0 0 20px #f1c40f, 0 0 40px #f39c12; + } } -@media (max-width: 768px) { - .stats { - flex-direction: column; - gap: 15px; - } - - .header, - .footer { - padding: 20px; - } - - .section { - padding: 20px; - height: 500px; - } - - .scroll-container { - height: 400px; - } +@keyframes bounce { + 0% { + transform: translateY(0); + text-shadow: 0 0 10px #25f312, 0 0 20px #87f10f; + } + 100% { + transform: translateY(-10px); + text-shadow: 0 0 20px #87f10f, 0 0 40px #25f312; + } } + +@keyframes background { + 0%{background-position:0% 50%} + 50%{background-position:100% 50%} + 100%{background-position:0% 50%} +} \ No newline at end of file