Compare commits
3 Commits
0eaec96b68
...
ad51ced86c
| Author | SHA1 | Date | |
|---|---|---|---|
| ad51ced86c | |||
| e992d8cbe7 | |||
| 1214e48733 |
@@ -0,0 +1,3 @@
|
|||||||
|
public/
|
||||||
|
.hugo_build.lock
|
||||||
|
.idea/
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>错误</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>请求的页面未找到</h1>
|
|
||||||
<p>请检查大小写/url是否打错</p>
|
|
||||||
<a href="http://swe-iss.rth1.xyz/">回到主页</a>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>S.A. XAGuarder</title>
|
|
||||||
<style>
|
|
||||||
.grey-bg-white-text {
|
|
||||||
background-color: grey; /* 灰底 */
|
|
||||||
color: white; /* 白字 */
|
|
||||||
padding: 50px; /* 文本内填充 */
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="grey-bg-white-text">
|
|
||||||
<img src="https://file.atomgit.com/uploads/user/1754052130447_4842.png" alt="Logo Source:atomgit::user_head">
|
|
||||||
先占个位,XAGuarder还要一段时间才能上线,当前已有ip,域名拦截能力
|
|
||||||
<a href="http://saswe.rth1.xyz/XAGuarder/warning.html">拦截页面式样</a>
|
|
||||||
Copyright(C) 2025 S.A. All rights received.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>S.A. XA Defended!</title>
|
|
||||||
<style>
|
|
||||||
.blue-bg-white-text {
|
|
||||||
background-color: red; /* 红底 */
|
|
||||||
color: white; /* 白字 */
|
|
||||||
padding: 50px; /* 文本内填充 */
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="blue-bg-white-text">
|
|
||||||
<img src="https://file.atomgit.com/uploads/user/1754052130447_4842.png" alt="Logo Source:atomgit::user_head">
|
|
||||||
<img src="https://atomgit.com/snoware/res/raw/master/79b6677ccfd646ea936aea3aff6b7702.jpeg">
|
|
||||||
发现不良网站!XAGuarder保护了您。
|
|
||||||
如果这是正常的网站,请检查是否通过当地公安机关备案。
|
|
||||||
Copyright(C) 2025 S.A. All rights received.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: "SNOWARE"
|
||||||
|
layout: "home"
|
||||||
|
---
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
title: "ISS 资源下载"
|
||||||
|
description: "一班 · 自学支持 · 资源下载"
|
||||||
|
accent: "#7a7a9e"
|
||||||
|
---
|
||||||
|
帮助学生查漏补缺、习题重练、预习复习。所有资源仅供自学使用。
|
||||||
|
|
||||||
|
提示:蓝奏云链接密码会自动填入,无需手动输入。
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
title: "文件列表"
|
||||||
|
description: "学科资源文件列表"
|
||||||
|
accent: "#7a7a9e"
|
||||||
|
layout: "filelist"
|
||||||
|
---
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: "我的作品"
|
||||||
|
description: "S.A. 的开源项目与作品展示"
|
||||||
|
accent: "#8a9a7e"
|
||||||
|
---
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
title: "btcli"
|
||||||
|
description: "命令行翻译工具,配备 TUI 界面"
|
||||||
|
accent: "#c8a87a"
|
||||||
|
slug: "btcli"
|
||||||
|
layout: "software-detail"
|
||||||
|
project: "btcli"
|
||||||
|
has_drag_ball: true
|
||||||
|
---
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
title: "MineSentinel"
|
||||||
|
description: "Minecraft 服务器智能守护进程"
|
||||||
|
accent: "#7a9a6e"
|
||||||
|
slug: "minesentinel"
|
||||||
|
layout: "software-detail"
|
||||||
|
project: "minesentinel"
|
||||||
|
---
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
title: "Mint Runtime"
|
||||||
|
description: "安全特性驱动的 Lua 运行时"
|
||||||
|
accent: "#a890b8"
|
||||||
|
slug: "mint"
|
||||||
|
layout: "software-detail"
|
||||||
|
project: "mint"
|
||||||
|
---
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
title: "Reverberation"
|
||||||
|
description: "轻量级文本阅读器"
|
||||||
|
accent: "#8a9a7e"
|
||||||
|
slug: "reverberation"
|
||||||
|
layout: "software-detail"
|
||||||
|
project: "reverberation"
|
||||||
|
---
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: "XAGuarder"
|
||||||
|
description: "网站安全拦截服务"
|
||||||
|
accent: "#b87070"
|
||||||
|
---
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
title: "XA Defended!"
|
||||||
|
description: "XAGuarder 拦截警告页面"
|
||||||
|
layout: "warning"
|
||||||
|
accent: "#b87070"
|
||||||
|
---
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
[[projects]]
|
||||||
|
name = "MineSentinel"
|
||||||
|
slug = "minesentinel"
|
||||||
|
description = "Minecraft 服务器智能守护进程,TCP 端口检测 + 崩溃自动重启 + 防循环冷却期"
|
||||||
|
accent = "#7a9a6e"
|
||||||
|
repo_url = "https://gitee.com/snoware/minesentinel"
|
||||||
|
demo_url = "/softwares/minesentinel/"
|
||||||
|
doc_url = "https://gitee.com/snoware/minesentinel/blob/master/DEPLOY.md"
|
||||||
|
tags = ["Ruby", "Minecraft", "Daemon"]
|
||||||
|
features = [
|
||||||
|
{ title = "TCP 端口检测", desc = "实时监控服务器端口状态,及时发现异常" },
|
||||||
|
{ title = "崩溃自动重启", desc = "服务器崩溃后自动重启,无需人工干预" },
|
||||||
|
{ title = "防循环冷却期", desc = "连续崩溃时进入冷却期,防止无限重启循环" },
|
||||||
|
{ title = "灵活配置", desc = "通过配置文件自定义检测间隔、重启策略等" },
|
||||||
|
{ title = "日志记录", desc = "完整的运行日志,方便排查问题" },
|
||||||
|
{ title = "轻量部署", desc = "Ruby 实现,依赖少,部署简单" }
|
||||||
|
]
|
||||||
|
install = "从 Gitee 获取源码后按 DEPLOY.md 文档部署"
|
||||||
|
license = "开源"
|
||||||
|
author = "S.A. (@snoware)"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "btcli"
|
||||||
|
slug = "btcli"
|
||||||
|
description = "一款命令行翻译工具,支持中文及其他语言,配备 TUI 界面"
|
||||||
|
accent = "#c8a87a"
|
||||||
|
repo_url = "https://gitee.com/ironbayberry/btcli"
|
||||||
|
demo_url = "/softwares/btcli/"
|
||||||
|
doc_url = "https://docs.rs/btcli"
|
||||||
|
tags = ["Rust", "CLI", "Translation", "TUI"]
|
||||||
|
features = [
|
||||||
|
{ title = "CLI 界面", desc = "简洁的命令行翻译,一行命令即可使用" },
|
||||||
|
{ title = "TUI 界面", desc = "交互式终端 UI,实时翻译体验" },
|
||||||
|
{ title = "多语言支持", desc = "支持中文及其他多种语言互译" },
|
||||||
|
{ title = "纯 CLI 模式", desc = "无需 TUI,适合脚本和自动化场景" },
|
||||||
|
{ title = "安全可靠", desc = "Rust 实现,内存安全,无运行时恐慌" },
|
||||||
|
{ title = "跨平台", desc = "支持 Linux、macOS、Windows" }
|
||||||
|
]
|
||||||
|
install = "cargo install btcli 或从源码构建"
|
||||||
|
usage = [
|
||||||
|
{ cmd = "btcli hello", desc = "基础翻译" },
|
||||||
|
{ cmd = "btcli --lang en 你好世界", desc = "指定目标语言" },
|
||||||
|
{ cmd = "btcli --tui", desc = "启动 TUI 界面" }
|
||||||
|
]
|
||||||
|
license = "MPL-2.0"
|
||||||
|
author = "S.A. (@snoware)"
|
||||||
|
has_drag_ball = true
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "Reverberation"
|
||||||
|
slug = "reverberation"
|
||||||
|
description = "轻量级文本阅读器,逐字显示文本内容"
|
||||||
|
accent = "#8a9a7e"
|
||||||
|
repo_url = "https://gitee.com/ironbayberry/reverberation"
|
||||||
|
demo_url = "/softwares/reverberation/"
|
||||||
|
doc_url = "https://docs.rs/reverberation"
|
||||||
|
tags = ["Rust", "CLI", "Chinese"]
|
||||||
|
features = [
|
||||||
|
{ title = "轻量极简", desc = "比 nano 更轻量,比 echo 更实用" },
|
||||||
|
{ title = "逐字显示", desc = "以指定延迟逐字展示文本,适合叙事场景" },
|
||||||
|
{ title = "简单易用", desc = "一行命令即可运行" },
|
||||||
|
{ title = "跨平台", desc = "支持主流操作系统" },
|
||||||
|
{ title = "Rust 实现", desc = "高性能,内存安全" }
|
||||||
|
]
|
||||||
|
install = "cargo install reverberation 或从源码构建"
|
||||||
|
usage = [
|
||||||
|
{ cmd = "reverberation <filename> <delay_ms>", desc = "逐字显示文本文件" }
|
||||||
|
]
|
||||||
|
license = "MPL-2.0"
|
||||||
|
author = "S.A. (@snoware)"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "Mint Runtime"
|
||||||
|
slug = "mint"
|
||||||
|
description = "安全特性驱动的 Lua 运行时,支持 i18n、字节码验证与细粒度访问控制"
|
||||||
|
accent = "#a890b8"
|
||||||
|
repo_url = "https://gitee.com/snoware/mint"
|
||||||
|
demo_url = "/softwares/mint/"
|
||||||
|
doc_url = "https://docs.rs/mintrt"
|
||||||
|
tags = ["Rust", "Lua", "Runtime", "Security", "i18n"]
|
||||||
|
features = [
|
||||||
|
{ title = "字节码验证", desc = "加载前验证 Lua 字节码,防止恶意代码注入" },
|
||||||
|
{ title = "细粒度访问控制", desc = "精确控制脚本可访问的系统资源" },
|
||||||
|
{ title = "i18n 支持", desc = "内置国际化,轻松适配多语言环境" },
|
||||||
|
{ title = "高性能", desc = "Rust 实现,低开销运行 Lua 脚本" },
|
||||||
|
{ title = "易集成", desc = "简洁 API,可快速嵌入到任何 Rust 项目" },
|
||||||
|
{ title = "动态加载", desc = "支持运行时动态加载和卸载脚本模块" }
|
||||||
|
]
|
||||||
|
install = "从 Gitee 获取源码构建,或查看 docs.rs/mintrt 文档"
|
||||||
|
license = "开源"
|
||||||
|
author = "S.A. (@snoware)"
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
[[subjects]]
|
||||||
|
name = "语文"
|
||||||
|
password = "d1iq"
|
||||||
|
url = "https://snowcloud.lanzoum.com/b0zkfchxi"
|
||||||
|
color = "#c89a6e"
|
||||||
|
|
||||||
|
[[subjects]]
|
||||||
|
name = "数学"
|
||||||
|
password = "6rp9"
|
||||||
|
url = "https://snowcloud.lanzoum.com/b0zkf9u4j"
|
||||||
|
color = "#8a9a7e"
|
||||||
|
|
||||||
|
[[subjects]]
|
||||||
|
name = "英语"
|
||||||
|
password = "4wxy"
|
||||||
|
url = "https://snowcloud.lanzoum.com/b0zkfchyj"
|
||||||
|
color = "#a890b8"
|
||||||
|
|
||||||
|
[[subjects]]
|
||||||
|
name = "物理"
|
||||||
|
password = "4n48"
|
||||||
|
url = "https://snowcloud.lanzoum.com/b0zkf9u5a"
|
||||||
|
color = "#c8a87a"
|
||||||
|
|
||||||
|
[[subjects]]
|
||||||
|
name = "化学"
|
||||||
|
password = "kc1b"
|
||||||
|
url = "https://snowcloud.lanzoum.com/b0zkf9tyd"
|
||||||
|
color = "#b87070"
|
||||||
|
|
||||||
|
[[subjects]]
|
||||||
|
name = "生物"
|
||||||
|
password = "dn3m"
|
||||||
|
url = "https://snowcloud.lanzoum.com/b0zkf9u0f"
|
||||||
|
color = "#7a9a6e"
|
||||||
|
|
||||||
|
[[subjects]]
|
||||||
|
name = "政治"
|
||||||
|
password = "4xej"
|
||||||
|
url = "https://snowcloud.lanzoum.com/b0zkf9u6b"
|
||||||
|
color = "#a08060"
|
||||||
|
|
||||||
|
[[subjects]]
|
||||||
|
name = "历史"
|
||||||
|
password = "i757"
|
||||||
|
url = "https://snowcloud.lanzoum.com/b0zkf9u3i"
|
||||||
|
color = "#7e6858"
|
||||||
|
|
||||||
|
[[subjects]]
|
||||||
|
name = "地理"
|
||||||
|
password = "dwrz"
|
||||||
|
url = "https://snowcloud.lanzoum.com/b0zkf9u2h"
|
||||||
|
color = "#6a8a78"
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
baseURL = 'https://swe-iss.rth1.xyz/'
|
||||||
|
relativeURLs = true
|
||||||
|
locale = 'zh-CN'
|
||||||
|
title = 'SNOWARE'
|
||||||
|
copyright = '© 2026 S.A. | SNOWARE'
|
||||||
|
|
||||||
|
[params]
|
||||||
|
author = 'S.A.'
|
||||||
|
description = 'SNOWARE — S.A. 个人站点'
|
||||||
|
logo = '/logo.svg'
|
||||||
|
navLinks = [
|
||||||
|
{ name = '资源下载', url = '/res/' },
|
||||||
|
{ name = '我的作品', url = '/softwares/' },
|
||||||
|
{ name = 'B站空间', url = 'https://bilibili.com/1875249243', external = true }
|
||||||
|
]
|
||||||
|
services = [
|
||||||
|
{ name = 'Gitea', url = 'http://103.217.186.98:3000/', icon = 'git', desc = '代码仓库' },
|
||||||
|
{ name = 'Cloudreve', url = 'http://103.217.186.98:5212/home', icon = 'cloud', desc = '云存储' },
|
||||||
|
{ name = 'Minecraft Server', url = '', icon = 'game', desc = 'QQ 758522192 注明来意' },
|
||||||
|
{ name = '学习与开发团队', url = '', icon = 'team', desc = '加入我们 QQ 758522192' }
|
||||||
|
]
|
||||||
|
|
||||||
|
[markup.goldmark.renderer]
|
||||||
|
unsafe = true
|
||||||
-325
@@ -1,325 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-CN">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>S.A. MainPage</title>
|
|
||||||
<style>
|
|
||||||
* {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: #000;
|
|
||||||
color: #fff;
|
|
||||||
height: 100vh;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 双Canvas背景设置 */
|
|
||||||
#starCanvas {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#trailCanvas {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 内容容器 */
|
|
||||||
.content {
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
height: 100vh;
|
|
||||||
padding: 40px 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Logo样式 */
|
|
||||||
.logo-container {
|
|
||||||
margin-top: 5vh;
|
|
||||||
text-align: center;
|
|
||||||
background: rgba(0, 0, 0, 0.5);
|
|
||||||
padding: 20px;
|
|
||||||
border-radius: 20px;
|
|
||||||
backdrop-filter: blur(10px);
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
||||||
box-shadow: 0 0 30px rgba(100, 150, 255, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
width: 180px;
|
|
||||||
height: 180px;
|
|
||||||
border-radius: 50%;
|
|
||||||
object-fit: cover;
|
|
||||||
border: 3px solid rgba(255, 255, 255, 0.2);
|
|
||||||
box-shadow: 0 0 30px rgba(100, 150, 255, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo-title {
|
|
||||||
margin-top: 15px;
|
|
||||||
font-size: 28px;
|
|
||||||
font-weight: 600;
|
|
||||||
letter-spacing: 2px;
|
|
||||||
color: #fff;
|
|
||||||
text-shadow: 0 0 10px rgba(100, 150, 255, 0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 按钮容器 */
|
|
||||||
.buttons-container {
|
|
||||||
margin-bottom: 10vh;
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 30px;
|
|
||||||
max-width: 600px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
flex: 1;
|
|
||||||
min-width: 220px;
|
|
||||||
padding: 18px 30px;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 600;
|
|
||||||
text-align: center;
|
|
||||||
text-decoration: none;
|
|
||||||
color: white;
|
|
||||||
background: rgba(40, 80, 160, 0.6);
|
|
||||||
border: 2px solid rgba(100, 150, 255, 0.5);
|
|
||||||
border-radius: 50px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
backdrop-filter: blur(5px);
|
|
||||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
|
|
||||||
letter-spacing: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn:hover {
|
|
||||||
background: rgba(60, 120, 220, 0.8);
|
|
||||||
transform: translateY(-5px);
|
|
||||||
box-shadow: 0 8px 20px rgba(100, 150, 255, 0.5);
|
|
||||||
border-color: rgba(150, 200, 255, 0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn:nth-child(2) {
|
|
||||||
background: rgba(160, 40, 80, 0.6);
|
|
||||||
border: 2px solid rgba(255, 100, 150, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn:nth-child(2):hover {
|
|
||||||
background: rgba(220, 60, 120, 0.8);
|
|
||||||
box-shadow: 0 8px 20px rgba(255, 100, 150, 0.5);
|
|
||||||
border-color: rgba(255, 150, 200, 0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 页脚 */
|
|
||||||
.footer {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 20px;
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 14px;
|
|
||||||
color: rgba(255, 255, 255, 0.6);
|
|
||||||
z-index: 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 响应式调整 */
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
.logo {
|
|
||||||
width: 140px;
|
|
||||||
height: 140px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo-title {
|
|
||||||
font-size: 22px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.buttons-container {
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
gap: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
width: 80%;
|
|
||||||
min-width: 200px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<!-- 用于绘制星星本体的画布 -->
|
|
||||||
<canvas id="starCanvas"></canvas>
|
|
||||||
<!-- 用于绘制星轨轨迹的画布 -->
|
|
||||||
<canvas id="trailCanvas"></canvas>
|
|
||||||
|
|
||||||
<!-- 内容区域 -->
|
|
||||||
<div class="content">
|
|
||||||
<div class="logo-container">
|
|
||||||
<img src="https://raw.atomgit.com/snoware/res/raw/main/swe_logo.png" alt="网站Logo" class="logo">
|
|
||||||
<div class="logo-title">SNOWARE</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="buttons-container">
|
|
||||||
<a href="https://swe-iss.rth1.xyz/res" class="btn">[ISS]资源下载</a>
|
|
||||||
<a href="https://www.bilibili.com/video/BV19b411G7hq" class="btn">一起听音乐</a>
|
|
||||||
<a href="https://swe-iss.rth1.xyz/softwares" class="btn">我的作品</a>
|
|
||||||
<a href="https://space.bilibili.com/1875249243" class="btn">B站空间</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="footer">
|
|
||||||
2025 * S.A. | SNOWARE
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// 获取画布元素和上下文
|
|
||||||
const starCanvas = document.getElementById('starCanvas');
|
|
||||||
const starCtx = starCanvas.getContext('2d');
|
|
||||||
const trailCanvas = document.getElementById('trailCanvas');
|
|
||||||
const trailCtx = trailCanvas.getContext('2d');
|
|
||||||
|
|
||||||
let stars = []; // 存储星星数据的数组
|
|
||||||
let animationId = null;
|
|
||||||
|
|
||||||
// 初始化设置
|
|
||||||
function init() {
|
|
||||||
// 设置画布尺寸为窗口大小
|
|
||||||
starCanvas.width = window.innerWidth;
|
|
||||||
starCanvas.height = window.innerHeight;
|
|
||||||
trailCanvas.width = window.innerWidth;
|
|
||||||
trailCanvas.height = window.innerHeight;
|
|
||||||
|
|
||||||
createStars(300); // 创建星星
|
|
||||||
animate(); // 开始动画循环
|
|
||||||
|
|
||||||
// 添加窗口大小调整监听
|
|
||||||
window.addEventListener('resize', handleResize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建星星数组
|
|
||||||
function createStars(count) {
|
|
||||||
const starColors = ['#ffffff', '#a8c9ff', '#fffacd', '#ffb6c1']; // 星星颜色数组
|
|
||||||
|
|
||||||
for (let i = 0; i < count; i++) {
|
|
||||||
// 随机分布在屏幕上
|
|
||||||
const x = Math.random() * starCanvas.width;
|
|
||||||
const y = Math.random() * starCanvas.height;
|
|
||||||
|
|
||||||
stars.push({
|
|
||||||
x: x,
|
|
||||||
y: y,
|
|
||||||
size: Math.random() * 1.5 + 0.5, // 随机大小
|
|
||||||
color: starColors[Math.floor(Math.random() * starColors.length)], // 随机颜色
|
|
||||||
blinkPhase: Math.random() * Math.PI * 2, // 闪烁相位
|
|
||||||
blinkSpeed: Math.random() * 0.02 + 0.01, // 闪烁速度
|
|
||||||
twinkleFactor: Math.random() // 闪烁因子,控制闪烁强度
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 动画循环
|
|
||||||
function animate() {
|
|
||||||
updateStars(); // 更新星星状态
|
|
||||||
draw(); // 绘制画面
|
|
||||||
animationId = requestAnimationFrame(animate); // 继续下一帧动画
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新所有星星的状态(只更新闪烁)
|
|
||||||
function updateStars() {
|
|
||||||
stars.forEach(star => {
|
|
||||||
star.blinkPhase += star.blinkSpeed; // 更新闪烁相位
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 绘制整个场景
|
|
||||||
function draw() {
|
|
||||||
drawBackground();
|
|
||||||
drawStars();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 绘制背景(微弱的星云效果)
|
|
||||||
function drawBackground() {
|
|
||||||
// 在轨迹画布上添加半透明黑色矩形
|
|
||||||
trailCtx.fillStyle = 'rgba(10, 10, 30, 0.1)';
|
|
||||||
trailCtx.fillRect(0, 0, trailCanvas.width, trailCanvas.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 绘制星星
|
|
||||||
function drawStars() {
|
|
||||||
// 清除星星画布
|
|
||||||
starCtx.clearRect(0, 0, starCanvas.width, starCanvas.height);
|
|
||||||
|
|
||||||
stars.forEach(star => {
|
|
||||||
// 计算闪烁效果(使用正弦函数)
|
|
||||||
const blinkIntensity = (Math.sin(star.blinkPhase) + 1) / 2;
|
|
||||||
const twinkleIntensity = blinkIntensity * star.twinkleFactor;
|
|
||||||
const currentSize = star.size * (0.7 + twinkleIntensity * 0.6); // 大小也随闪烁变化
|
|
||||||
|
|
||||||
// 在星星画布上绘制星星本体
|
|
||||||
starCtx.beginPath();
|
|
||||||
starCtx.fillStyle = star.color;
|
|
||||||
starCtx.globalAlpha = 0.6 + twinkleIntensity * 0.4; // 透明度随闪烁变化
|
|
||||||
starCtx.arc(star.x, star.y, currentSize, 0, Math.PI * 2);
|
|
||||||
starCtx.fill();
|
|
||||||
|
|
||||||
// 添加光晕效果
|
|
||||||
const gradient = starCtx.createRadialGradient(
|
|
||||||
star.x, star.y, 0,
|
|
||||||
star.x, star.y, currentSize * 3
|
|
||||||
);
|
|
||||||
gradient.addColorStop(0, star.color);
|
|
||||||
gradient.addColorStop(0.5, star.color.replace(')', ', 0.7)').replace('rgb', 'rgba'));
|
|
||||||
gradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
|
|
||||||
|
|
||||||
starCtx.fillStyle = gradient;
|
|
||||||
starCtx.globalAlpha = 0.3 + twinkleIntensity * 0.3;
|
|
||||||
starCtx.beginPath();
|
|
||||||
starCtx.arc(star.x, star.y, currentSize * 3, 0, Math.PI * 2);
|
|
||||||
starCtx.fill();
|
|
||||||
|
|
||||||
// 重置透明度
|
|
||||||
starCtx.globalAlpha = 1;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理窗口大小调整
|
|
||||||
function handleResize() {
|
|
||||||
// 取消当前动画帧
|
|
||||||
if (animationId) {
|
|
||||||
cancelAnimationFrame(animationId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 重置画布尺寸
|
|
||||||
starCanvas.width = window.innerWidth;
|
|
||||||
starCanvas.height = window.innerHeight;
|
|
||||||
trailCanvas.width = window.innerWidth;
|
|
||||||
trailCanvas.height = window.innerHeight;
|
|
||||||
|
|
||||||
// 清空星星数组并重新创建
|
|
||||||
stars = [];
|
|
||||||
createStars(300); // 重新创建星星
|
|
||||||
|
|
||||||
// 重新开始动画
|
|
||||||
animate();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 页面加载完成后初始化
|
|
||||||
window.addEventListener('load', init);
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>S.A. Mainpage</title>
|
|
||||||
<style>
|
|
||||||
.blue-bg-white-text {
|
|
||||||
background-color: cyan; /* 蓝底 */
|
|
||||||
color: white; /* 白字 */
|
|
||||||
padding: 50px; /* 文本内填充 */
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="blue-bg-white-text">
|
|
||||||
<img src="https://file.atomgit.com/uploads/user/1754052130447_4842.png" alt="Logo Source:atomgit::user_head">
|
|
||||||
<a href="http://saswe.rth1.xyz/res">资源下载/n</a>
|
|
||||||
Copyright(C) 2025 S.A. All rights received.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{{ define "body" }}
|
||||||
|
<section class="error-page">
|
||||||
|
<div class="error-content">
|
||||||
|
<img src="{{ .Site.Params.logo }}" alt="Logo" class="error-logo" width="120" height="120">
|
||||||
|
<h1>404</h1>
|
||||||
|
<p>请求的页面未找到</p>
|
||||||
|
<p class="error-hint">请检查 URL 是否正确</p>
|
||||||
|
<a href="/" class="btn btn-primary">返回主页</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{{ end }}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="{{ .Site.Language.Locale }}">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>{{ if .IsHome }}{{ .Site.Title }}{{ else }}{{ .Title }} — {{ .Site.Title }}{{ end }}</title>
|
||||||
|
<meta name="description" content="{{ with .Description }}{{ . }}{{ else }}{{ .Site.Params.description }}{{ end }}">
|
||||||
|
<link rel="icon" href="/logo.svg" type="image/svg+xml">
|
||||||
|
{{ with .Params.accent }}<meta name="theme-color" content="{{ . }}">{{ end }}
|
||||||
|
<link rel="stylesheet" href="/css/style.css">
|
||||||
|
{{ block "extra_head" . }}{{ end }}
|
||||||
|
</head>
|
||||||
|
<body class="{{ if .IsHome }}home{{ else }}page{{ end }}">
|
||||||
|
<script src="/js/nature-bg.js"></script>
|
||||||
|
{{ partial "nav.html" . }}
|
||||||
|
<main id="main-content">
|
||||||
|
{{ block "body" . }}{{ end }}
|
||||||
|
</main>
|
||||||
|
{{ partial "footer.html" . }}
|
||||||
|
{{ block "extra_scripts" . }}{{ end }}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{{ define "body" }}
|
||||||
|
<section class="page-hero" {{ with .Params.accent }}style="--accent: {{ . }}"{{ end }}>
|
||||||
|
<h1>{{ .Title }}</h1>
|
||||||
|
{{ with .Description }}<p class="subtitle">{{ . }}</p>{{ end }}
|
||||||
|
</section>
|
||||||
|
<section class="page-content container">
|
||||||
|
{{ .Content }}
|
||||||
|
</section>
|
||||||
|
{{ end }}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{{ define "body" }}
|
||||||
|
<section class="page-hero" {{ with .Params.accent }}style="--accent: {{ . }}"{{ end }}>
|
||||||
|
<h1>{{ .Title }}</h1>
|
||||||
|
{{ with .Params.subtitle }}<p class="subtitle">{{ . }}</p>{{ end }}
|
||||||
|
</section>
|
||||||
|
<section class="page-content container">
|
||||||
|
{{ .Content }}
|
||||||
|
</section>
|
||||||
|
{{ end }}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
{{ define "body" }}
|
||||||
|
<div class="home-hero">
|
||||||
|
<div class="logo-wrap">
|
||||||
|
<img src="{{ .Site.Params.logo }}" alt="SNOWARE Logo" class="home-logo" width="160" height="160">
|
||||||
|
</div>
|
||||||
|
<h1 class="home-title">SNOWARE</h1>
|
||||||
|
<div class="home-poem">
|
||||||
|
<p class="poem-line fade-1">群星璀璨而流星划过天际,曳尾长明而星空黯淡无光,我们如何在瞬间探寻永恒的答案?</p>
|
||||||
|
<p class="poem-line fade-2">苦旅漫漫,雾霭蒙蒙,文牒拭作灰烬,家书遥遥无期。</p>
|
||||||
|
<p class="poem-line fade-3">雾开雾散,云卷云舒,潮起潮息,光阴流转而你我不凡之辈,即亡没砂石亦必熠熠生辉</p>
|
||||||
|
<p class="poem-line fade-4">曲折的进步似为唯一的答案,我心永恒,流光跃过风雨,终会与你同行。</p>
|
||||||
|
<p class="poem-sig">S.A. 2026 7.5 @EDT</p>
|
||||||
|
</div>
|
||||||
|
<nav class="home-nav">
|
||||||
|
{{ range .Site.Params.navLinks }}
|
||||||
|
<a href="{{ .url }}" class="home-btn{{ if .external }} external{{ end }}" {{ if .external }}target="_blank" rel="noopener"{{ end }}>
|
||||||
|
{{ .name }}
|
||||||
|
</a>
|
||||||
|
{{ end }}
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
{{ with .Site.Params.services }}
|
||||||
|
<div class="home-services">
|
||||||
|
<h2>服务</h2>
|
||||||
|
<div class="services-grid">
|
||||||
|
{{ range . }}
|
||||||
|
{{ if .url }}
|
||||||
|
<a href="{{ .url }}" class="service-card external" target="_blank" rel="noopener">
|
||||||
|
{{ else }}
|
||||||
|
<div class="service-card no-link">
|
||||||
|
{{ end }}
|
||||||
|
<div class="service-icon">
|
||||||
|
{{ if eq .icon "git" }}
|
||||||
|
<svg viewBox="0 0 24 24"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 00-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0020 4.77 5.07 5.07 0 0019.91 1S18.73.65 16 2.48a13.38 13.38 0 00-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 005 4.77a5.44 5.44 0 00-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 009 18.13V22"/></svg>
|
||||||
|
{{ else if eq .icon "cloud" }}
|
||||||
|
<svg viewBox="0 0 24 24"><path d="M18 10h-1.26A8 8 0 109 20h9a5 5 0 000-10z"/></svg>
|
||||||
|
{{ else if eq .icon "game" }}
|
||||||
|
<svg viewBox="0 0 24 24"><rect x="2" y="6" width="20" height="12" rx="2"/><line x1="6" y1="12" x2="10" y2="12"/><line x1="8" y1="10" x2="8" y2="14"/><circle cx="16" cy="10" r="1" fill="currentColor" stroke="none"/><circle cx="19" cy="12" r="1" fill="currentColor" stroke="none"/></svg>
|
||||||
|
{{ else if eq .icon "team" }}
|
||||||
|
<svg viewBox="0 0 24 24"><path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 00-3-3.87"/><path d="M16 3.13a4 4 0 010 7.75"/></svg>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
<h3>{{ .name }}</h3>
|
||||||
|
<p>{{ .desc }}</p>
|
||||||
|
{{ if .url }}</a>{{ else }}</div>{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<footer class="site-footer">
|
||||||
|
<div class="container">
|
||||||
|
<p>{{ .Site.Copyright }}</p>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<header class="site-nav">
|
||||||
|
<div class="nav-inner container">
|
||||||
|
<a href="/" class="nav-brand">
|
||||||
|
<img src="{{ .Site.Params.logo }}" alt="{{ .Site.Title }}" class="nav-logo" width="32" height="32">
|
||||||
|
<span>{{ .Site.Title }}</span>
|
||||||
|
</a>
|
||||||
|
<nav class="nav-links">
|
||||||
|
{{ range .Site.Params.navLinks }}
|
||||||
|
<a href="{{ .url }}" {{ if .external }}target="_blank" rel="noopener"{{ end }}>{{ .name }}</a>
|
||||||
|
{{ end }}
|
||||||
|
<button class="theme-toggle" id="theme-toggle" title="切换主题">
|
||||||
|
<svg class="theme-icon-warm" viewBox="0 0 24 24" width="18" height="18"><circle cx="12" cy="12" r="5" fill="currentColor" stroke="none"/><line x1="12" y1="1" x2="12" y2="3" stroke="currentColor" stroke-width="2"/><line x1="12" y1="21" x2="12" y2="23" stroke="currentColor" stroke-width="2"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64" stroke="currentColor" stroke-width="2"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78" stroke="currentColor" stroke-width="2"/><line x1="1" y1="12" x2="3" y2="12" stroke="currentColor" stroke-width="2"/><line x1="21" y1="12" x2="23" y2="12" stroke="currentColor" stroke-width="2"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36" stroke="currentColor" stroke-width="2"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22" stroke="currentColor" stroke-width="2"/></svg>
|
||||||
|
<svg class="theme-icon-cyan" viewBox="0 0 24 24" width="18" height="18"><path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z" fill="none" stroke="currentColor" stroke-width="2"/></svg>
|
||||||
|
</button>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<script>
|
||||||
|
(function(){
|
||||||
|
var t = localStorage.getItem('snoware-theme') || 'warm';
|
||||||
|
document.documentElement.setAttribute('data-theme', t);
|
||||||
|
var btn = document.getElementById('theme-toggle');
|
||||||
|
if(btn) btn.addEventListener('click', function(){
|
||||||
|
var cur = document.documentElement.getAttribute('data-theme');
|
||||||
|
var next = cur === 'warm' ? 'cyan' : 'warm';
|
||||||
|
document.documentElement.setAttribute('data-theme', next);
|
||||||
|
localStorage.setItem('snoware-theme', next);
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<a href="{{ .demo_url }}" class="project-card" style="--accent: {{ .accent }}">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3>{{ .name }}</h3>
|
||||||
|
<div class="card-tags">
|
||||||
|
{{ range .tags }}<span class="tag">{{ . }}</span>{{ end }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="card-desc">{{ .description }}</p>
|
||||||
|
<div class="card-links">
|
||||||
|
<span class="card-link primary">查看详情 →</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<a href="{{ .url }}" class="subject-card" target="_blank" rel="noopener" style="--color: {{ .color }}">
|
||||||
|
<div class="subject-icon">
|
||||||
|
<svg viewBox="0 0 24 24" width="40" height="40" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||||
|
<path d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V7"/>
|
||||||
|
<path d="M21 7a2 2 0 00-2-2H5a2 2 0 00-2 2"/>
|
||||||
|
<path d="M12 5v14"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<h3>{{ .name }}</h3>
|
||||||
|
<p class="subject-pw">密码: <code>{{ .password }}</code></p>
|
||||||
|
</a>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{{ define "body" }}
|
||||||
|
<section class="page-hero" style="--accent: #7a7a9e">
|
||||||
|
<h1>学科资源列表</h1>
|
||||||
|
<p class="subtitle">蓝奏云下载 · 点击学科即可跳转</p>
|
||||||
|
</section>
|
||||||
|
<section class="page-content container">
|
||||||
|
<div class="filelist-grid">
|
||||||
|
{{ range hugo.Data.subjects.subjects }}
|
||||||
|
{{ partial "subject-card.html" . }}
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{{ end }}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
{{ define "body" }}
|
||||||
|
<section class="page-hero" style="--accent: #7a7a9e">
|
||||||
|
<h1>{{ .Title }}</h1>
|
||||||
|
<p class="subtitle">{{ .Description }}</p>
|
||||||
|
</section>
|
||||||
|
<section class="page-content container">
|
||||||
|
<div class="res-intro">
|
||||||
|
<p class="res-intro-text">{{ .Content }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="res-actions">
|
||||||
|
<a href="/res/filelist/" class="btn btn-primary btn-lg">下载源:蓝奏云</a>
|
||||||
|
<a href="https://www.alipan.com/s/RMfnGxo6Z9D" class="btn btn-accent btn-lg external" target="_blank" rel="noopener">阿里云盘(需登录)</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="res-features">
|
||||||
|
<div class="feature-card">
|
||||||
|
<div class="feature-icon">📋</div>
|
||||||
|
<h3>查漏补缺</h3>
|
||||||
|
<p>针对性复习薄弱知识点</p>
|
||||||
|
</div>
|
||||||
|
<div class="feature-card">
|
||||||
|
<div class="feature-icon">🔄</div>
|
||||||
|
<h3>习题重练</h3>
|
||||||
|
<p>反复练习巩固学习成果</p>
|
||||||
|
</div>
|
||||||
|
<div class="feature-card">
|
||||||
|
<div class="feature-icon">📖</div>
|
||||||
|
<h3>预习复习</h3>
|
||||||
|
<p>提前预习,高效复习</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{{ end }}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
{{ define "body" }}
|
||||||
|
<section class="page-hero" style="--accent: #8a9a7e">
|
||||||
|
<h1>{{ .Title }}</h1>
|
||||||
|
<p class="subtitle">{{ .Description }}</p>
|
||||||
|
</section>
|
||||||
|
<section class="page-content container">
|
||||||
|
<div class="about-intro">
|
||||||
|
<p>S.A. (@snoware) — 开源爱好者,Rust / Ruby 开发者。致力于构建实用、安全、优雅的命令行工具与服务端软件。</p>
|
||||||
|
<a href="https://gitee.com/snoware" class="btn btn-accent external" target="_blank" rel="noopener">Gitee 主页</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="project-grid">
|
||||||
|
{{ range hugo.Data.projects.projects }}
|
||||||
|
{{ partial "project-card.html" . }}
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{{ end }}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
{{ define "body" }}
|
||||||
|
{{ $slug := .Params.project }}
|
||||||
|
{{ $matched := where hugo.Data.projects.projects "slug" $slug }}
|
||||||
|
{{ with index $matched 0 }}
|
||||||
|
|
||||||
|
<section class="page-hero" style="--accent: {{ .accent }}">
|
||||||
|
<h1>{{ .name }}</h1>
|
||||||
|
<p class="subtitle">{{ .description }}</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="page-content container">
|
||||||
|
<!-- Links -->
|
||||||
|
<div class="sw-links">
|
||||||
|
<a href="{{ .repo_url }}" class="btn btn-accent external" target="_blank" rel="noopener">Gitee 源码</a>
|
||||||
|
{{ with .doc_url }}<a href="{{ . }}" class="btn btn-outline external" target="_blank" rel="noopener">文档</a>{{ end }}
|
||||||
|
{{ if eq .slug "btcli" }}
|
||||||
|
<a href="https://crates.io/crates/btcli" class="btn btn-outline external" target="_blank" rel="noopener">Crates.io</a>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Features -->
|
||||||
|
<div class="sw-features">
|
||||||
|
{{ range .features }}
|
||||||
|
<div class="feature-card">
|
||||||
|
<h3>{{ .title }}</h3>
|
||||||
|
<p>{{ .desc }}</p>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Install -->
|
||||||
|
{{ with .install }}
|
||||||
|
<div class="sw-section">
|
||||||
|
<h2>安装</h2>
|
||||||
|
<div class="sw-code">{{ . }}</div>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
<!-- Usage -->
|
||||||
|
{{ with .usage }}
|
||||||
|
<div class="sw-section">
|
||||||
|
<h2>使用</h2>
|
||||||
|
<div class="usage-list">
|
||||||
|
{{ range . }}
|
||||||
|
<div class="usage-item">
|
||||||
|
<code>{{ .cmd }}</code>
|
||||||
|
<span>{{ .desc }}</span>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
<!-- License -->
|
||||||
|
{{ with .license }}
|
||||||
|
<div class="sw-section">
|
||||||
|
<h2>许可证</h2>
|
||||||
|
<p>{{ . }}</p>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
<!-- Drag ball for btcli -->
|
||||||
|
{{ if .has_drag_ball }}
|
||||||
|
<div class="drag-ball-area">
|
||||||
|
<canvas id="drag-ball" width="200" height="200"></canvas>
|
||||||
|
<p class="drag-hint">拖动小球试试 (¬‿¬)</p>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ define "extra_scripts" }}
|
||||||
|
{{ $slug := .Params.project }}
|
||||||
|
{{ $matched := where hugo.Data.projects.projects "slug" $slug }}
|
||||||
|
{{ with index $matched 0 }}
|
||||||
|
{{ if .has_drag_ball }}
|
||||||
|
<script src="/js/drag-ball.js"></script>
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{{ define "body" }}
|
||||||
|
<section class="page-hero" style="--accent: #b87070">
|
||||||
|
<h1>{{ .Title }}</h1>
|
||||||
|
<p class="subtitle">{{ .Description }}</p>
|
||||||
|
</section>
|
||||||
|
<section class="page-content container">
|
||||||
|
<div class="xag-intro">
|
||||||
|
<img src="{{ .Site.Params.logo }}" alt="XAGuarder" class="xag-logo" width="120" height="120">
|
||||||
|
<h2>XAGuarder</h2>
|
||||||
|
<p>先占个位,XAGuarder 还要一段时间才能上线。当前已具备 IP、域名拦截能力。</p>
|
||||||
|
<a href="/xaguarder/warning/" class="btn btn-accent">查看拦截页面预览</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{{ end }}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
{{ define "body" }}
|
||||||
|
<section class="warning-page" style="--accent: #f44336">
|
||||||
|
<div class="warning-content">
|
||||||
|
<img src="{{ .Site.Params.logo }}" alt="XAGuarder" class="warning-logo" width="120" height="120">
|
||||||
|
<h1>发现不良网站!</h1>
|
||||||
|
<p class="warning-text">XAGuarder 保护了您。</p>
|
||||||
|
<p class="warning-sub">如果这是正常的网站,请检查是否通过当地公安机关备案。</p>
|
||||||
|
<a href="/" class="btn btn-primary">返回主页</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ define "extra_head" }}
|
||||||
|
<style>
|
||||||
|
.warning-page { --accent: #b87070; }
|
||||||
|
</style>
|
||||||
|
{{ end }}
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
[[projects]]
|
|
||||||
name = "MineSentinel"
|
|
||||||
description = "Minecraft 服务器智能守护进程,TCP 端口检测 + 崩溃自动重启 + 防循环冷却期"
|
|
||||||
repo_url = "https://gitee.com/snoware/minesentinel"
|
|
||||||
demo_url = "https://swe-iss.rth1.xyz/softwares/minesentinel"
|
|
||||||
doc_url = "https://gitee.com/snoware/minesentinel/blob/master/DEPLOY.md"
|
|
||||||
tags = ["Ruby", "Minecraft", "Server", "Monitoring", "Daemon", "SNOWARE"]
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
name = "btcli"
|
|
||||||
description = "一款在线命令行翻译工具,支持中文及其他语言,配备TUI界面"
|
|
||||||
repo_url = "https://gitee.com/ironbayberry/btcli"
|
|
||||||
demo_url = "https://swe-iss.rth1.xyz/softwares/btcli"
|
|
||||||
doc_url = "https://docs.rs/btcli"
|
|
||||||
tags = ["Rust", "CLI", "Translation", "TUI", "SASWE"]
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
name = "Reverberation"
|
|
||||||
description = "Story teller, it's more lightweight than nano and more convenient to use than echo."
|
|
||||||
repo_url = "https://gitee.com/ironbayberry/reverberation"
|
|
||||||
demo_url = "https://swe-iss.rth1.xyz/softwares/reverberation"
|
|
||||||
doc_url = "https://docs.rs/reverberation"
|
|
||||||
tags = ["CLI", "Chinese", "open-source", "SASWE", "Rust"]
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
name = "Mint Runtime"
|
|
||||||
description = "Security-featured runtime for Lua with i18n support, bytecode verification, and fine-grained access control."
|
|
||||||
repo_url = "https://gitee.com/snoware/mint"
|
|
||||||
demo_url = "https://swe-iss.rth1.xyz/softwares/mint"
|
|
||||||
doc_url = "https://docs.rs/mintrt"
|
|
||||||
tags = ["CLI", "Chinese", "open-source", "SASWE", "Rust", "Lua", "Runtime", "Security", "i18n"]
|
|
||||||
@@ -1,355 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-CN">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>[ISS] Filelist</title>
|
|
||||||
<style>
|
|
||||||
* {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
|
|
||||||
color: #fff;
|
|
||||||
min-height: 100vh;
|
|
||||||
padding: 20px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
max-width: 1000px;
|
|
||||||
width: 100%;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
header {
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 2.5rem;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
text-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.subtitle {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
opacity: 0.9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-browser {
|
|
||||||
background: rgba(255, 255, 255, 0.1);
|
|
||||||
backdrop-filter: blur(10px);
|
|
||||||
border-radius: 15px;
|
|
||||||
padding: 25px;
|
|
||||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.folder-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
|
||||||
gap: 20px;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.folder-item {
|
|
||||||
background: rgba(255, 255, 255, 0.15);
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 20px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
cursor: pointer;
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
||||||
text-decoration: none;
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.folder-item:hover {
|
|
||||||
background: rgba(255, 255, 255, 0.25);
|
|
||||||
transform: translateY(-5px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.folder-icon {
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
margin-right: 15px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.folder-icon svg {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.2));
|
|
||||||
}
|
|
||||||
|
|
||||||
.folder-content h3 {
|
|
||||||
font-size: 1.3rem;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.folder-content p {
|
|
||||||
opacity: 0.8;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navigation {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
width: 100%;
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-btn {
|
|
||||||
background: rgba(255, 255, 255, 0.2);
|
|
||||||
border: none;
|
|
||||||
color: white;
|
|
||||||
padding: 12px 25px;
|
|
||||||
border-radius: 50px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 1rem;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-btn:hover {
|
|
||||||
background: rgba(255, 255, 255, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-btn:disabled {
|
|
||||||
opacity: 0.5;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-indicator {
|
|
||||||
text-align: center;
|
|
||||||
margin: 10px 0;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 为不同学科添加不同的图标颜色 */
|
|
||||||
.chinese { color: #FF9AA2; }
|
|
||||||
.math { color: #FFB7B2; }
|
|
||||||
.english { color: #FFDAC1; }
|
|
||||||
.physics { color: #E2F0CB; }
|
|
||||||
.chemistry { color: #B5EAD7; }
|
|
||||||
.biology { color: #C7CEEA; }
|
|
||||||
.politics { color: #F8B195; }
|
|
||||||
.history { color: #F67280; }
|
|
||||||
.geography { color: #6C5B7B; }
|
|
||||||
|
|
||||||
/* 响应式设计 */
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
.folder-grid {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 2rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<header>
|
|
||||||
<h1>学科文件</h1>
|
|
||||||
<p class="subtitle">点击学科文件夹查看相关内容,下载源:蓝奏云</p>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div class="file-browser">
|
|
||||||
<div class="folder-grid" id="folderContainer">
|
|
||||||
<!-- 文件夹将通过JavaScript动态生成 -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="page-indicator">
|
|
||||||
页数: <span id="currentPage">1</span> / <span id="totalPages">3</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="navigation">
|
|
||||||
<button class="nav-btn" id="prevBtn">
|
|
||||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M15 18L9 12L15 6" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
</svg>
|
|
||||||
上一页
|
|
||||||
</button>
|
|
||||||
<button class="nav-btn" id="nextBtn">
|
|
||||||
下一页
|
|
||||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M9 18L15 12L9 6" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// 学科数据 - 包含密码信息
|
|
||||||
const subjects = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
name: "语文",
|
|
||||||
description: "密码:d1iq",
|
|
||||||
iconColor: "chinese",
|
|
||||||
url: "https://snowcloud.lanzoum.com/b0zkfchxi"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
name: "数学",
|
|
||||||
description: "密码:6rp9",
|
|
||||||
iconColor: "math",
|
|
||||||
url: "https://snowcloud.lanzoum.com/b0zkf9u4j"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
name: "英语",
|
|
||||||
description: "密码:4wxy",
|
|
||||||
iconColor: "english",
|
|
||||||
url: "https://snowcloud.lanzoum.com/b0zkfchyj"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
name: "物理",
|
|
||||||
description: "密码:4n48",
|
|
||||||
iconColor: "physics",
|
|
||||||
url: "https://snowcloud.lanzoum.com/b0zkf9u5a"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 5,
|
|
||||||
name: "化学",
|
|
||||||
description: "密码:kc1b",
|
|
||||||
iconColor: "chemistry",
|
|
||||||
url: "https://snowcloud.lanzoum.com/b0zkf9tyd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 6,
|
|
||||||
name: "生物",
|
|
||||||
description: "密码:dn3m",
|
|
||||||
iconColor: "biology",
|
|
||||||
url: "https://snowcloud.lanzoum.com/b0zkf9u0f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 7,
|
|
||||||
name: "政治",
|
|
||||||
description: "密码:4xej",
|
|
||||||
iconColor: "politics",
|
|
||||||
url: "https://snowcloud.lanzoum.com/b0zkf9u6b"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 8,
|
|
||||||
name: "历史",
|
|
||||||
description: "密码:i757",
|
|
||||||
iconColor: "history",
|
|
||||||
url: "https://snowcloud.lanzoum.com/b0zkf9u3i"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 9,
|
|
||||||
name: "地理",
|
|
||||||
description: "密码:dwrz",
|
|
||||||
iconColor: "geography",
|
|
||||||
url: "https://snowcloud.lanzoum.com/b0zkf9u2h"
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
// 分页设置
|
|
||||||
const itemsPerPage = 6;
|
|
||||||
let currentPage = 1;
|
|
||||||
const totalPages = Math.ceil(subjects.length / itemsPerPage);
|
|
||||||
|
|
||||||
// DOM元素
|
|
||||||
const folderContainer = document.getElementById('folderContainer');
|
|
||||||
const prevBtn = document.getElementById('prevBtn');
|
|
||||||
const nextBtn = document.getElementById('nextBtn');
|
|
||||||
const currentPageSpan = document.getElementById('currentPage');
|
|
||||||
const totalPagesSpan = document.getElementById('totalPages');
|
|
||||||
|
|
||||||
// 初始化总页数
|
|
||||||
totalPagesSpan.textContent = totalPages;
|
|
||||||
|
|
||||||
// 文件夹图标SVG
|
|
||||||
const folderIconSVG = (colorClass) => `
|
|
||||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V8h16v10z" fill="currentColor"/>
|
|
||||||
</svg>
|
|
||||||
`;
|
|
||||||
|
|
||||||
// 显示当前页的文件夹
|
|
||||||
function displayCurrentPage() {
|
|
||||||
folderContainer.innerHTML = '';
|
|
||||||
currentPageSpan.textContent = currentPage;
|
|
||||||
|
|
||||||
const startIndex = (currentPage - 1) * itemsPerPage;
|
|
||||||
const endIndex = Math.min(startIndex + itemsPerPage, subjects.length);
|
|
||||||
|
|
||||||
for (let i = startIndex; i < endIndex; i++) {
|
|
||||||
const subject = subjects[i];
|
|
||||||
|
|
||||||
// 创建链接元素
|
|
||||||
const folderLink = document.createElement('a');
|
|
||||||
folderLink.className = 'folder-item';
|
|
||||||
folderLink.href = subject.url;
|
|
||||||
folderLink.target = '_blank'; // 在新标签页打开
|
|
||||||
|
|
||||||
folderLink.innerHTML = `
|
|
||||||
<div class="folder-icon ${subject.iconColor}">
|
|
||||||
${folderIconSVG()}
|
|
||||||
</div>
|
|
||||||
<div class="folder-content">
|
|
||||||
<h3>${subject.name}</h3>
|
|
||||||
<p>${subject.description}</p>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
folderContainer.appendChild(folderLink);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新按钮状态
|
|
||||||
prevBtn.disabled = currentPage === 1;
|
|
||||||
nextBtn.disabled = currentPage === totalPages;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 上一页
|
|
||||||
prevBtn.addEventListener('click', () => {
|
|
||||||
if (currentPage > 1) {
|
|
||||||
currentPage--;
|
|
||||||
displayCurrentPage();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 下一页
|
|
||||||
nextBtn.addEventListener('click', () => {
|
|
||||||
if (currentPage < totalPages) {
|
|
||||||
currentPage++;
|
|
||||||
displayCurrentPage();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 初始化显示
|
|
||||||
displayCurrentPage();
|
|
||||||
|
|
||||||
// 添加键盘导航支持
|
|
||||||
document.addEventListener('keydown', (e) => {
|
|
||||||
if (e.key === 'ArrowLeft' && currentPage > 1) {
|
|
||||||
currentPage--;
|
|
||||||
displayCurrentPage();
|
|
||||||
} else if (e.key === 'ArrowRight' && currentPage < totalPages) {
|
|
||||||
currentPage++;
|
|
||||||
displayCurrentPage();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="footer">
|
|
||||||
© 2025 * S.A. | SNOWARE
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
-208
@@ -1,208 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-CN">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>SWE-ISS</title>
|
|
||||||
<style>//AI完成,自行修改
|
|
||||||
* {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
||||||
background: linear-gradient(135deg, #0A2463 0%, #1e3c72 100%);
|
|
||||||
color: #fff;
|
|
||||||
min-height: 100vh;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
padding: 20px;
|
|
||||||
line-height: 1.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
text-align: center;
|
|
||||||
max-width: 800px;
|
|
||||||
width: 100%;
|
|
||||||
padding: 40px 20px;
|
|
||||||
background: rgba(255, 255, 255, 0.05);
|
|
||||||
backdrop-filter: blur(10px);
|
|
||||||
border-radius: 20px;
|
|
||||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 2.5rem;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
font-weight: 700;
|
|
||||||
text-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.subtitle {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
margin-bottom: 40px;
|
|
||||||
color: #a8c9ff;
|
|
||||||
max-width: 600px;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-container {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 30px;
|
|
||||||
margin-top: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 16px 40px;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 600;
|
|
||||||
text-align: center;
|
|
||||||
text-decoration: none;
|
|
||||||
color: white;
|
|
||||||
background: rgba(40, 80, 160, 0.7);
|
|
||||||
border: 2px solid rgba(100, 150, 255, 0.5);
|
|
||||||
border-radius: 50px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
backdrop-filter: blur(5px);
|
|
||||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
|
|
||||||
min-width: 200px;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn:hover {
|
|
||||||
background: rgba(60, 120, 220, 0.9);
|
|
||||||
transform: translateY(-5px);
|
|
||||||
box-shadow: 0 8px 20px rgba(100, 150, 255, 0.4);
|
|
||||||
border-color: rgba(150, 200, 255, 0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn:active {
|
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: 0 5px 10px rgba(100, 150, 255, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary {
|
|
||||||
background: rgba(40, 80, 160, 0.7);
|
|
||||||
border: 2px solid rgba(100, 150, 255, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-secondary {
|
|
||||||
background: rgba(160, 40, 80, 0.7);
|
|
||||||
border: 2px solid rgba(255, 100, 150, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-secondary:hover {
|
|
||||||
background: rgba(220, 60, 120, 0.9);
|
|
||||||
box-shadow: 0 8px 20px rgba(255, 100, 150, 0.4);
|
|
||||||
border-color: rgba(255, 150, 200, 0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
.features {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 30px;
|
|
||||||
margin-top: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature {
|
|
||||||
flex: 1;
|
|
||||||
min-width: 200px;
|
|
||||||
max-width: 250px;
|
|
||||||
padding: 20px;
|
|
||||||
background: rgba(255, 255, 255, 0.05);
|
|
||||||
border-radius: 15px;
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature h3 {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
color: #a8c9ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer {
|
|
||||||
margin-top: 50px;
|
|
||||||
font-size: 14px;
|
|
||||||
color: rgba(255, 255, 255, 0.6);
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 响应式设计 */
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
.container {
|
|
||||||
padding: 30px 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subtitle {
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
padding: 14px 30px;
|
|
||||||
font-size: 16px;
|
|
||||||
min-width: 180px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-container {
|
|
||||||
gap: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 480px) {
|
|
||||||
.button-container {
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 280px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<h1>一班_自学支持_资源下载</h1>
|
|
||||||
<p class="subtitle">不是每位学生都可以在校内完成全部任务,当学业繁重时,这个页面或许会成为你查漏补缺的好帮手。注意:点击后需等待几秒,密码会自行解开</p>
|
|
||||||
|
|
||||||
<div class="button-container">
|
|
||||||
<a href="https://swe-iss.rth1.xyz/res/filelist.html" class="btn btn-primary">下载源:蓝奏云</a>
|
|
||||||
<a href="https://www.alipan.com/s/PbHuzxXvgAi" class="btn btn-secondary">阿里云盘(在线预览,需登录)</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="features">
|
|
||||||
<div class="feature">
|
|
||||||
<h3>查漏补缺</h3>
|
|
||||||
<p>在课上放心紧跟老师思路,笔记可以慢慢补</p>
|
|
||||||
</div>
|
|
||||||
<div class="feature">
|
|
||||||
<h3>习题重练</h3>
|
|
||||||
<p>课上来不及,没做完的题可以现在练</p>
|
|
||||||
</div>
|
|
||||||
<div class="feature">
|
|
||||||
<h3>预习复习</h3>
|
|
||||||
<p>在未来,我有时间的话,老师们也可以把预习课件,提优资源放在这里,欲穷千里目,更上一层楼</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="footer">
|
|
||||||
© 2025 * S.A. | SNOWARE
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>下载您所需要的资源</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>仅自学使用</h1>
|
|
||||||
<a href="https://url88.ctfile.com/d/34021088-156924754-5b7671?p=5992">点此跳转</a>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,688 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-CN">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>btcli - 命令行翻译工具</title>
|
|
||||||
<style>
|
|
||||||
* {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
||||||
line-height: 1.6;
|
|
||||||
color: #333;
|
|
||||||
background: linear-gradient(135deg, #fff8e1, #ffecb3, #ffcc80); /* 暖色渐变:米色到浅黄到橙色 */
|
|
||||||
min-height: 100vh;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 可拖动的小球容器 */
|
|
||||||
.draggable-ball {
|
|
||||||
position: fixed;
|
|
||||||
top: 50%;
|
|
||||||
left: 20px;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
z-index: 10000;
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
cursor: grab;
|
|
||||||
}
|
|
||||||
|
|
||||||
.draggable-ball:active {
|
|
||||||
cursor: grabbing;
|
|
||||||
}
|
|
||||||
|
|
||||||
.draggable-ball-canvas {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
max-width: 1200px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 0 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 导航栏样式 - 暖色调 */
|
|
||||||
header {
|
|
||||||
background-color: #ff8f00; /* 深橙色 */
|
|
||||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
||||||
position: sticky;
|
|
||||||
top: 0;
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: 1rem 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
font-weight: bold;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-links {
|
|
||||||
display: flex;
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-links li {
|
|
||||||
margin-left: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-links a {
|
|
||||||
text-decoration: none;
|
|
||||||
color: rgba(255, 255, 255, 0.9);
|
|
||||||
font-weight: 500;
|
|
||||||
transition: color 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-links a:hover {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 主要内容区域 */
|
|
||||||
main {
|
|
||||||
padding: 2rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 英雄区域 - 暖色调 */
|
|
||||||
.hero {
|
|
||||||
background: linear-gradient(135deg, #ff8f00, #ff6f00); /* 橙色渐变 */
|
|
||||||
color: white;
|
|
||||||
padding: 4rem 0;
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero h1 {
|
|
||||||
font-size: 2.5rem;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero p {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
max-width: 600px;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 按钮链接样式 */
|
|
||||||
.button-container {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 1rem;
|
|
||||||
margin: 2rem 0;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.external-link-btn {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 0.5rem;
|
|
||||||
padding: 0.75rem 1.5rem;
|
|
||||||
background-color: #ff8f00; /* 橙色背景 */
|
|
||||||
color: white;
|
|
||||||
text-decoration: none;
|
|
||||||
border-radius: 4px;
|
|
||||||
transition: background-color 0.3s;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.external-link-btn:hover {
|
|
||||||
background-color: #e65100; /* 深橙色背景 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-icon {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 功能特色区域 */
|
|
||||||
.features {
|
|
||||||
padding: 2rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.features h2 {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 2.5rem;
|
|
||||||
margin-bottom: 3rem;
|
|
||||||
color: #ff8f00; /* 橙色标题 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
|
||||||
gap: 2rem;
|
|
||||||
margin-top: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-card {
|
|
||||||
background-color: #ffecb3; /* 暖黄色背景 */
|
|
||||||
padding: 2rem;
|
|
||||||
border-radius: 10px;
|
|
||||||
text-align: center;
|
|
||||||
box-shadow: 0 5px 15px rgba(255, 143, 0, 0.1); /* 橙色阴影 */
|
|
||||||
transition: transform 0.3s;
|
|
||||||
border: 1px solid rgba(255, 143, 0, 0.2); /* 橙色边框 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-card:hover {
|
|
||||||
transform: translateY(-10px);
|
|
||||||
box-shadow: 0 15px 30px rgba(255, 143, 0, 0.2); /* 更明显的橙色阴影 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-card h3 {
|
|
||||||
color: #ff8f00; /* 橙色标题 */
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
font-size: 1.3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-card p {
|
|
||||||
color: #5d4037; /* 棕色文字 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Gitee 小部件样式 - 暖色调 */
|
|
||||||
.osc_pro_color {color: #5d4037 !important;}
|
|
||||||
.osc_panel_color {background-color: #ffecb3 !important;}
|
|
||||||
.osc_background_color {background-color: #fff8e1 !important;}
|
|
||||||
.osc_border_color {border-color: #ffca28 !important;}
|
|
||||||
.osc_desc_color {color: #5d4037 !important;}
|
|
||||||
.osc_link_color * {color: #ff8f00 !important;}
|
|
||||||
|
|
||||||
/* 安装说明区域 */
|
|
||||||
.installation {
|
|
||||||
padding: 3rem 0;
|
|
||||||
background-color: #fff3e0; /* 暖橘色背景 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.installation h2 {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 2.5rem;
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
color: #ff8f00; /* 橙色标题 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.install-steps {
|
|
||||||
max-width: 800px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.step {
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
background: white;
|
|
||||||
padding: 1.5rem;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 3px 10px rgba(255, 143, 0, 0.1);
|
|
||||||
border-left: 4px solid #ff8f00; /* 橙色左边框 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.step h3 {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
color: #ff8f00;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
background-color: #333;
|
|
||||||
color: #fff;
|
|
||||||
padding: 1rem;
|
|
||||||
border-radius: 5px;
|
|
||||||
overflow-x: auto;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
margin-top: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 使用示例区域 */
|
|
||||||
.usage {
|
|
||||||
padding: 3rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.usage h2 {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 2.5rem;
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
color: #ff8f00; /* 橙色标题 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.usage-examples {
|
|
||||||
max-width: 800px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 0 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.example {
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
background: #ffecb3; /* 暖黄色背景 */
|
|
||||||
padding: 1.5rem;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 3px 10px rgba(255, 143, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.example h3 {
|
|
||||||
margin-bottom: 0.8rem;
|
|
||||||
color: #ff8f00;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 关于区域 */
|
|
||||||
.about {
|
|
||||||
padding: 5rem 0;
|
|
||||||
background-color: #ffecb3; /* 暖黄色背景 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.about h2 {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 2.5rem;
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
color: #ff8f00; /* 橙色标题 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.about p {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
text-align: center;
|
|
||||||
color: #5d4037; /* 棕色文字 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 页脚 - 暖色调 */
|
|
||||||
footer {
|
|
||||||
background-color: #ff8f00; /* 橙色页脚 */
|
|
||||||
color: white;
|
|
||||||
padding: 3rem 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer p {
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 响应式设计 */
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
.nav-links {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero h1 {
|
|
||||||
font-size: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero {
|
|
||||||
padding: 3rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-grid {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav {
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<!-- 可拖动的带颜文字小球 -->
|
|
||||||
<div class="draggable-ball">
|
|
||||||
<canvas id="draggableBall" class="draggable-ball-canvas"></canvas>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<header>
|
|
||||||
<nav>
|
|
||||||
<div class="logo">btcli</div>
|
|
||||||
<ul class="nav-links">
|
|
||||||
<li><a href="#home">首页</a></li>
|
|
||||||
<li><a href="#features">特性</a></li>
|
|
||||||
<li><a href="#installation">安装</a></li>
|
|
||||||
<li><a href="#usage">使用</a></li>
|
|
||||||
<li><a href="#about">关于</a></li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<main>
|
|
||||||
<section id="home" class="hero">
|
|
||||||
<div class="container">
|
|
||||||
<h1>btcli</h1>
|
|
||||||
<p>一款在线命令行翻译工具,支持中文及其他语言,配备TUI界面</p>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- 按钮链接区域 -->
|
|
||||||
<div class="container button-container">
|
|
||||||
<a href="https://gitee.com/Ironbayberry/btcli" target="_blank" class="external-link-btn">
|
|
||||||
<img src="https://gitee.com/favicon.ico" alt="Gitee Icon" class="btn-icon">
|
|
||||||
Gitee
|
|
||||||
</a>
|
|
||||||
<a href="https://crates.io/crates/btcli" target="_blank" class="external-link-btn">
|
|
||||||
<img src="https://crates.io/favicon.ico" alt="Crates.io Icon" class="btn-icon">
|
|
||||||
Crates.io
|
|
||||||
</a>
|
|
||||||
<a href="https://swe-iss.rth1.xyz/softwares/btcli/docs" target="_blank" class="external-link-btn">
|
|
||||||
<img src="https://rust-lang.org/static/images/favicon.svg" alt="Rust Icon" class="btn-icon">
|
|
||||||
Rust docs
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<section id="features" class="features">
|
|
||||||
<div class="container">
|
|
||||||
<h2>功能特性</h2>
|
|
||||||
<div class="feature-grid">
|
|
||||||
<div class="feature-card">
|
|
||||||
<h3>命令行界面 (CLI)</h3>
|
|
||||||
<p>支持丰富的命令行参数,可直接在终端中快速翻译,无需打开图形界面,提高工作效率</p>
|
|
||||||
<ul style="text-align: left; margin-top: 10px;">
|
|
||||||
<li>支持 -s/--source 指定源语言</li>
|
|
||||||
<li>支持 -t/--target 指定目标语言</li>
|
|
||||||
<li>支持 -h/--help 查看帮助信息</li>
|
|
||||||
<li>支持 -v/--version 查看版本信息</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="feature-card">
|
|
||||||
<h3>文本用户界面 (TUI)</h3>
|
|
||||||
<p>直观的文本用户界面,提供友好的交互体验,支持多窗口操作和实时翻译</p>
|
|
||||||
<ul style="text-align: left; margin-top: 10px;">
|
|
||||||
<li>支持多语言配置</li>
|
|
||||||
<li>支持设置页面</li>
|
|
||||||
<li>支持快捷键操作</li>
|
|
||||||
<li>支持剪贴板功能</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="feature-card">
|
|
||||||
<h3>多语言支持</h3>
|
|
||||||
<p>支持中文、英文及多种国际语言之间的互译,覆盖全球主要语系</p>
|
|
||||||
<ul style="text-align: left; margin-top: 10px;">
|
|
||||||
<li>自动检测源语言</li>
|
|
||||||
<li>支持主流语种翻译</li>
|
|
||||||
<li>持续添加新语言</li>
|
|
||||||
<li>高质量翻译引擎</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="feature-card">
|
|
||||||
<h3>纯CLI模式</h3>
|
|
||||||
<p>支持纯命令行操作,适合脚本集成和自动化任务,可无缝集成到各类工作流中</p>
|
|
||||||
<ul style="text-align: left; margin-top: 10px;">
|
|
||||||
<li>无头模式运行</li>
|
|
||||||
<li>支持管道输入</li>
|
|
||||||
<li>支持批处理操作</li>
|
|
||||||
<li>适合CI/CD集成</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="feature-card">
|
|
||||||
<h3>安全可靠</h3>
|
|
||||||
<p>采用百度翻译API,保障翻译质量和数据安全,本地配置文件加密存储</p>
|
|
||||||
<ul style="text-align: left; margin-top: 10px;">
|
|
||||||
<li>API密钥本地存储</li>
|
|
||||||
<li>HTTPS加密传输</li>
|
|
||||||
<li>无数据记录</li>
|
|
||||||
<li>开源可验证</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="feature-card">
|
|
||||||
<h3>跨平台支持</h3>
|
|
||||||
<p>基于Rust开发,支持Windows、macOS、Linux等多种操作系统</p>
|
|
||||||
<ul style="text-align: left; margin-top: 10px;">
|
|
||||||
<li>Windows x86_64</li>
|
|
||||||
<li>Linux x86_64</li>
|
|
||||||
<li>macOS Intel/Apple Silicon</li>
|
|
||||||
<li>ARM架构支持</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="installation" class="installation">
|
|
||||||
<div class="container">
|
|
||||||
<h2>安装</h2>
|
|
||||||
<div class="install-steps">
|
|
||||||
<div class="step">
|
|
||||||
<h3>通过Cargo安装</h3>
|
|
||||||
<pre><code>cargo install btcli</code></pre>
|
|
||||||
</div>
|
|
||||||
<div class="step">
|
|
||||||
<h3>从源码构建</h3>
|
|
||||||
<pre><code>git clone https://gitee.com/Ironbayberry/btcli.git
|
|
||||||
cd btcli
|
|
||||||
cargo build --release</code></pre>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="usage" class="usage">
|
|
||||||
<div class="container">
|
|
||||||
<h2>使用方法</h2>
|
|
||||||
<div class="usage-examples">
|
|
||||||
<div class="example">
|
|
||||||
<h3>基础翻译</h3>
|
|
||||||
<pre><code>btcli "Hello, world!"</code></pre>
|
|
||||||
</div>
|
|
||||||
<div class="example">
|
|
||||||
<h3>指定语言</h3>
|
|
||||||
<pre><code>btcli -s en -t zh "Hello, world!"
|
|
||||||
(默认会保存到设置)</code></pre>
|
|
||||||
</div>
|
|
||||||
<div class="example">
|
|
||||||
<h3>启动TUI界面</h3>
|
|
||||||
<pre><code>btcli</code></pre>
|
|
||||||
</div>
|
|
||||||
<div class="example">
|
|
||||||
<h3>显示帮助</h3>
|
|
||||||
<pre><code>btcli --help</code></pre>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="about" class="about">
|
|
||||||
<div class="container">
|
|
||||||
<h2>关于项目</h2>
|
|
||||||
<p>btcli是一个开源的命令行翻译工具,专为中文和其他语言的翻译而设计。项目采用Rust语言编写,注重性能和安全性。</p>
|
|
||||||
<p>作者: S.A. (@snoware)</p>
|
|
||||||
<p>许可证: MPL-2.0</p>
|
|
||||||
<p>项目主页: <a href="https://gitee.com/Ironbayberry/btcli" style="color: #ff8f00; text-decoration: underline;" target="_blank">https://gitee.com/Ironbayberry/btcli</a></p>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- Gitee 仓库小部件 -->
|
|
||||||
<div class="container">
|
|
||||||
<div id="osc-gitee-widget-tag"></div>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<div class="container">
|
|
||||||
<p>© 2026 S.A. (@snoware). 使用 MPL-2.0 许可证发布.</p>
|
|
||||||
<p>项目主页: <a href="https://swe-iss.rth1.xyz/softwares/btcli" style="color: white; text-decoration: underline;" target="_blank">https://swe-iss.rth1.xyz/softwares/btcli</a></p>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// Gitee 仓库小部件
|
|
||||||
(function() {
|
|
||||||
var origin = 'https://gitee.com';
|
|
||||||
var widgetUrl = origin + '/Ironbayberry/btcli/widget_preview';
|
|
||||||
var script = document.createElement('script');
|
|
||||||
script.type = 'text/javascript';
|
|
||||||
script.async = true;
|
|
||||||
script.src = widgetUrl;
|
|
||||||
var s = document.getElementsByTagName('script')[0];
|
|
||||||
s.parentNode.insertBefore(script, s);
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
<script>
|
|
||||||
// 绘制可拖动的带颜文字小球
|
|
||||||
const canvas = document.getElementById('draggableBall');
|
|
||||||
const ctx = canvas.getContext('2d');
|
|
||||||
|
|
||||||
// 设置canvas尺寸
|
|
||||||
canvas.width = 40;
|
|
||||||
canvas.height = 40;
|
|
||||||
|
|
||||||
// 绘制小球
|
|
||||||
function drawBall() {
|
|
||||||
// 清除画布
|
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
||||||
|
|
||||||
// 绘制小球背景
|
|
||||||
const centerX = canvas.width / 2;
|
|
||||||
const centerY = canvas.height / 2;
|
|
||||||
const radius = 15;
|
|
||||||
|
|
||||||
// 创建渐变效果
|
|
||||||
const gradient = ctx.createRadialGradient(
|
|
||||||
centerX - 5, centerY - 5, 1,
|
|
||||||
centerX, centerY, radius
|
|
||||||
);
|
|
||||||
gradient.addColorStop(0, '#ffeb3b'); // 黄色
|
|
||||||
gradient.addColorStop(1, '#ff9800'); // 橙色
|
|
||||||
|
|
||||||
// 绘制圆球
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);
|
|
||||||
ctx.fillStyle = gradient;
|
|
||||||
ctx.fill();
|
|
||||||
|
|
||||||
// 添加边框
|
|
||||||
ctx.strokeStyle = '#e65100';
|
|
||||||
ctx.lineWidth = 1;
|
|
||||||
ctx.stroke();
|
|
||||||
|
|
||||||
// 绘制颜文字 "(¬‿¬)"
|
|
||||||
ctx.font = 'bold 12px Arial';
|
|
||||||
ctx.fillStyle = '#333';
|
|
||||||
ctx.textAlign = 'center';
|
|
||||||
ctx.textBaseline = 'middle';
|
|
||||||
ctx.fillText('(¬‿¬)', centerX, centerY + 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 调用绘制函数
|
|
||||||
drawBall();
|
|
||||||
|
|
||||||
// 拖动功能
|
|
||||||
let isDragging = false;
|
|
||||||
let offsetX, offsetY;
|
|
||||||
|
|
||||||
canvas.parentElement.addEventListener('mousedown', startDrag);
|
|
||||||
document.addEventListener('mousemove', drag);
|
|
||||||
document.addEventListener('mouseup', stopDrag);
|
|
||||||
|
|
||||||
// 触摸设备支持
|
|
||||||
canvas.parentElement.addEventListener('touchstart', touchStart);
|
|
||||||
document.addEventListener('touchmove', touchMove);
|
|
||||||
document.addEventListener('touchend', touchEnd);
|
|
||||||
|
|
||||||
function startDrag(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
isDragging = true;
|
|
||||||
|
|
||||||
const rect = canvas.getBoundingClientRect();
|
|
||||||
offsetX = e.clientX - rect.left;
|
|
||||||
offsetY = e.clientY - rect.top;
|
|
||||||
}
|
|
||||||
|
|
||||||
function drag(e) {
|
|
||||||
if (!isDragging) return;
|
|
||||||
|
|
||||||
const x = e.clientX - offsetX;
|
|
||||||
const y = e.clientY - offsetY;
|
|
||||||
|
|
||||||
// 更新小球位置
|
|
||||||
canvas.parentElement.style.left = `${x}px`;
|
|
||||||
canvas.parentElement.style.top = `${y}px`;
|
|
||||||
canvas.parentElement.style.transform = 'none'; // 取消初始的transform
|
|
||||||
}
|
|
||||||
|
|
||||||
function stopDrag() {
|
|
||||||
isDragging = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 触摸事件处理
|
|
||||||
function touchStart(e) {
|
|
||||||
const touch = e.touches[0];
|
|
||||||
const mouseEvent = new MouseEvent('mousedown', {
|
|
||||||
clientX: touch.clientX,
|
|
||||||
clientY: touch.clientY
|
|
||||||
});
|
|
||||||
canvas.dispatchEvent(mouseEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
function touchMove(e) {
|
|
||||||
const touch = e.touches[0];
|
|
||||||
const mouseEvent = new MouseEvent('mousemove', {
|
|
||||||
clientX: touch.clientX,
|
|
||||||
clientY: touch.clientY
|
|
||||||
});
|
|
||||||
document.dispatchEvent(mouseEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
function touchEnd() {
|
|
||||||
const mouseEvent = new MouseEvent('mouseup', {});
|
|
||||||
document.dispatchEvent(mouseEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 平滑滚动效果
|
|
||||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
|
||||||
anchor.addEventListener('click', function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
const targetId = this.getAttribute('href');
|
|
||||||
if (targetId === '#') return;
|
|
||||||
|
|
||||||
const targetElement = document.querySelector(targetId);
|
|
||||||
if (targetElement) {
|
|
||||||
window.scrollTo({
|
|
||||||
top: targetElement.offsetTop - 80, // 减去导航栏高度
|
|
||||||
behavior: 'smooth'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 导航栏高亮当前部分
|
|
||||||
window.addEventListener('scroll', () => {
|
|
||||||
const sections = document.querySelectorAll('section');
|
|
||||||
const navLinks = document.querySelectorAll('.nav-links a');
|
|
||||||
|
|
||||||
let current = '';
|
|
||||||
|
|
||||||
sections.forEach(section => {
|
|
||||||
const sectionTop = section.offsetTop;
|
|
||||||
const sectionHeight = section.clientHeight;
|
|
||||||
|
|
||||||
if (pageYOffset >= (sectionTop - 100)) {
|
|
||||||
current = section.getAttribute('id');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
navLinks.forEach(link => {
|
|
||||||
link.classList.remove('active');
|
|
||||||
if (link.getAttribute('href') === `#${current}`) {
|
|
||||||
link.classList.add('active');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 页面加载完成后执行
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
console.log('btcli 详情页面已加载');
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
@@ -1,438 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-CN">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>S.A. - 我的作品</title>
|
|
||||||
<style>
|
|
||||||
* {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
||||||
line-height: 1.6;
|
|
||||||
color: #333;
|
|
||||||
background: linear-gradient(135deg, #e1f5fe, #f3e5f5);
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
max-width: 1200px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 0 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 导航栏样式 */
|
|
||||||
header {
|
|
||||||
background-color: #009688; /* 青色主色调 */
|
|
||||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
||||||
position: sticky;
|
|
||||||
top: 0;
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: 1rem 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
font-weight: bold;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-links {
|
|
||||||
display: flex;
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-links li {
|
|
||||||
margin-left: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-links a {
|
|
||||||
text-decoration: none;
|
|
||||||
color: rgba(255, 255, 255, 0.9);
|
|
||||||
font-weight: 500;
|
|
||||||
transition: color 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-links a:hover {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 主要内容区域 */
|
|
||||||
main {
|
|
||||||
padding: 2rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 英雄区域 */
|
|
||||||
.hero {
|
|
||||||
background: linear-gradient(135deg, #009688, #2196F3); /* 青蓝渐变 */
|
|
||||||
color: white;
|
|
||||||
padding: 4rem 0;
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero h1 {
|
|
||||||
font-size: 2.5rem;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero p {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
max-width: 600px;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 项目区域 */
|
|
||||||
.projects {
|
|
||||||
padding: 2rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.projects h2 {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 2.5rem;
|
|
||||||
margin-bottom: 3rem;
|
|
||||||
color: #009688; /* 青色标题 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.project-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
|
||||||
gap: 2rem;
|
|
||||||
margin-top: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.project-card {
|
|
||||||
background-color: #E0F7FA; /* 青色透明背景 */
|
|
||||||
padding: 2rem;
|
|
||||||
border-radius: 10px;
|
|
||||||
text-align: center;
|
|
||||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
|
|
||||||
transition: transform 0.3s;
|
|
||||||
border: 1px solid rgba(0, 150, 136, 0.2); /* 青色边框 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.project-card:hover {
|
|
||||||
transform: translateY(-10px);
|
|
||||||
box-shadow: 0 15px 30px rgba(0, 150, 136, 0.2); /* 青色阴影 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.project-card h3 {
|
|
||||||
color: #009688; /* 青色标题 */
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
font-size: 1.3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.project-card h3 a {
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.project-card h3 a:hover {
|
|
||||||
color: #2196F3; /* 蓝色悬停效果 */
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.project-card .description {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.project-card .tags {
|
|
||||||
margin: 1rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag {
|
|
||||||
display: inline-block;
|
|
||||||
background-color: #009688; /* 青色标签 */
|
|
||||||
color: white;
|
|
||||||
padding: 0.3rem 0.8rem;
|
|
||||||
border-radius: 20px;
|
|
||||||
font-size: 0.8rem;
|
|
||||||
margin: 0.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.project-card .links {
|
|
||||||
margin-top: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.project-card .links a {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 0.5rem;
|
|
||||||
padding: 0.5rem 1rem;
|
|
||||||
background-color: #009688; /* 青色按钮 */
|
|
||||||
color: white;
|
|
||||||
text-decoration: none;
|
|
||||||
border-radius: 5px;
|
|
||||||
transition: background-color 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.project-card .links a:hover {
|
|
||||||
background-color: #2196F3; /* 蓝色悬停 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 关于区域 */
|
|
||||||
.about {
|
|
||||||
padding: 5rem 0;
|
|
||||||
background-color: #E1F5FE; /* 淡青背景 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.about h2 {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 2.5rem;
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
color: #009688; /* 青色标题 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.about p {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 页脚 */
|
|
||||||
footer {
|
|
||||||
background-color: #009688; /* 青色页脚 */
|
|
||||||
color: white;
|
|
||||||
padding: 3rem 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer p {
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 响应式设计 */
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
.nav-links {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero h1 {
|
|
||||||
font-size: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero {
|
|
||||||
padding: 3rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.project-grid {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav {
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<link rel="icon" href="../favicon.ico" type="image/x-icon">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<header>
|
|
||||||
<nav>
|
|
||||||
<div class="logo">S.A. - 我的作品</div>
|
|
||||||
<ul class="nav-links">
|
|
||||||
<li><a href="/">首页</a></li>
|
|
||||||
<li><a href="#projects">项目</a></li>
|
|
||||||
<li><a href="#about">关于</a></li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<main>
|
|
||||||
<section id="home" class="hero">
|
|
||||||
<div class="container">
|
|
||||||
<h1>S.A. - 我的作品</h1>
|
|
||||||
<p>欢迎来到 S.A. 的开源项目展示页面</p>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="projects" class="projects">
|
|
||||||
<div class="container">
|
|
||||||
<h2>我的作品</h2>
|
|
||||||
<div id="projects-container" class="project-grid">
|
|
||||||
<!-- 项目将通过JavaScript动态加载 -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>-->
|
|
||||||
|
|
||||||
<section id="about" class="about">
|
|
||||||
<div class="container">
|
|
||||||
<h2>关于</h2>
|
|
||||||
<p>这里展示了 S.A. (@snoware) 的个人作品集。所有项目都采用了现代化的技术栈。</p>
|
|
||||||
<p>欢迎访问我的 <a href="https://gitee.com/Ironbayberry/" target="_blank" style="color: #009688; text-decoration: underline;">Gitee 个人主页</a> 查看更多项目。</p>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<div class="container">
|
|
||||||
<p>© 2026 S.A. (@snoware). All rights reserved.</p>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// 用于存储项目数据
|
|
||||||
let projectsData = [];
|
|
||||||
|
|
||||||
// 加载 TOML 文件并渲染项目
|
|
||||||
async function loadProjects() {
|
|
||||||
try {
|
|
||||||
// 从同目录下的 projects.txt 文件加载数据
|
|
||||||
const response = await fetch('projects.txt');
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`无法加载项目数据: ${response.status} ${response.statusText}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const tomlText = await response.text();
|
|
||||||
|
|
||||||
// 简单的 TOML 解析器(由于不能引入外部库,我们使用简化的解析方法)
|
|
||||||
parseToml(tomlText);
|
|
||||||
renderProjects();
|
|
||||||
} catch (error) {
|
|
||||||
console.error('加载项目数据时出错:', error);
|
|
||||||
const container = document.getElementById('projects-container');
|
|
||||||
container.innerHTML = `<p class="error">加载项目失败: ${error.message}</p>`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 简化的 TOML 解析器
|
|
||||||
function parseToml(tomlText) {
|
|
||||||
// 将 TOML 文本转换为 JavaScript 对象
|
|
||||||
const lines = tomlText.split('\n');
|
|
||||||
let currentProject = null;
|
|
||||||
projectsData = [];
|
|
||||||
|
|
||||||
for (const line of lines) {
|
|
||||||
const trimmedLine = line.trim();
|
|
||||||
|
|
||||||
// 检测项目开始 [[projects]]
|
|
||||||
if (trimmedLine.startsWith('[[projects]]')) {
|
|
||||||
currentProject = {};
|
|
||||||
projectsData.push(currentProject);
|
|
||||||
} else if (currentProject && trimmedLine.includes('=')) {
|
|
||||||
const [key, value] = trimmedLine.split('=');
|
|
||||||
const cleanKey = key.trim();
|
|
||||||
let cleanValue = value.trim();
|
|
||||||
|
|
||||||
// 处理字符串值(去除引号)
|
|
||||||
if (cleanValue.startsWith('"') && cleanValue.endsWith('"')) {
|
|
||||||
cleanValue = cleanValue.substring(1, cleanValue.length - 1);
|
|
||||||
}
|
|
||||||
// 处理数组值
|
|
||||||
else if (cleanValue.startsWith('[') && cleanValue.endsWith(']')) {
|
|
||||||
cleanValue = cleanValue.substring(1, cleanValue.length - 1)
|
|
||||||
.split(',')
|
|
||||||
.map(item => item.trim().replace(/"/g, ''));
|
|
||||||
}
|
|
||||||
|
|
||||||
currentProject[cleanKey] = cleanValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 渲染项目到页面
|
|
||||||
function renderProjects() {
|
|
||||||
const container = document.getElementById('projects-container');
|
|
||||||
|
|
||||||
if (!projectsData || projectsData.length === 0) {
|
|
||||||
container.innerHTML = '<p>暂无项目数据</p>';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 生成项目卡片HTML
|
|
||||||
const projectsHTML = projectsData.map(project => {
|
|
||||||
// 处理URL中的模板变量
|
|
||||||
const processedDemoUrl = project.demo_url ? project.demo_url.replace(/\{\$rthSuffix\}/g, '') : null;
|
|
||||||
const processedRepoUrl = project.repo_url ? project.repo_url.replace(/\{\$rthSuffix\}/g, '') : null;
|
|
||||||
const processedDocUrl = project.doc_url ? project.doc_url.replace(/\{\$rthSuffix\}/g, '') : null;
|
|
||||||
|
|
||||||
return `
|
|
||||||
<div class="project-card">
|
|
||||||
<h3><a href="${processedDemoUrl || processedRepoUrl || '#'}" target="_blank">${project.name || '未知项目'}</a></h3>
|
|
||||||
<p class="description">${project.description || '暂无描述'}</p>
|
|
||||||
<div class="tags">
|
|
||||||
${(project.tags || []).map(tag => `<span class="tag">${tag}</span>`).join('')}
|
|
||||||
</div>
|
|
||||||
<div class="links">
|
|
||||||
${processedRepoUrl ? `<a href="${processedRepoUrl}" target="_blank">代码仓库</a>` : ''}
|
|
||||||
${processedDemoUrl ? `<a href="${processedDemoUrl}" target="_blank">演示</a>` : ''}
|
|
||||||
${processedDocUrl ? `<a href="${processedDocUrl}" target="_blank">文档</a>` : ''}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`}).join('');
|
|
||||||
|
|
||||||
container.innerHTML = projectsHTML;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 平滑滚动效果
|
|
||||||
function setupSmoothScrolling() {
|
|
||||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
|
||||||
anchor.addEventListener('click', function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
const targetId = this.getAttribute('href');
|
|
||||||
if (targetId === '#') return;
|
|
||||||
|
|
||||||
const targetElement = document.querySelector(targetId);
|
|
||||||
if (targetElement) {
|
|
||||||
window.scrollTo({
|
|
||||||
top: targetElement.offsetTop - 80, // 减去导航栏高度
|
|
||||||
behavior: 'smooth'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 导航栏高亮当前部分
|
|
||||||
function setupActiveNavigation() {
|
|
||||||
window.addEventListener('scroll', () => {
|
|
||||||
const sections = document.querySelectorAll('section');
|
|
||||||
const navLinks = document.querySelectorAll('.nav-links a');
|
|
||||||
|
|
||||||
let current = '';
|
|
||||||
|
|
||||||
sections.forEach(section => {
|
|
||||||
const sectionTop = section.offsetTop;
|
|
||||||
const sectionHeight = section.clientHeight;
|
|
||||||
|
|
||||||
if (pageYOffset >= (sectionTop - 100)) {
|
|
||||||
current = section.getAttribute('id');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
navLinks.forEach(link => {
|
|
||||||
link.classList.remove('active');
|
|
||||||
if (link.getAttribute('href') === `#${current}`) {
|
|
||||||
link.classList.add('active');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 页面加载完成后执行
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
loadProjects(); // 加载项目数据
|
|
||||||
setupSmoothScrolling(); // 设置平滑滚动
|
|
||||||
setupActiveNavigation(); // 设置导航高亮
|
|
||||||
|
|
||||||
console.log('S.A. 作品集页面已加载');
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,371 +0,0 @@
|
|||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-CN">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Mint Runtime - 安全的 Lua 运行时</title>
|
|
||||||
<script src='https://gitee.com/snoware/mint/widget_preview' async defer></script>
|
|
||||||
<style>
|
|
||||||
* {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
||||||
line-height: 1.6;
|
|
||||||
color: #333;
|
|
||||||
background: linear-gradient(135deg, #00bcd4 0%, #26a69a 100%);
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
max-width: 1200px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
header {
|
|
||||||
text-align: center;
|
|
||||||
padding: 60px 20px;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo-container {
|
|
||||||
margin-bottom: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo-container svg {
|
|
||||||
max-width: 200px;
|
|
||||||
height: auto;
|
|
||||||
filter: drop-shadow(2px 2px 4px rgba(0,0,0,0.3));
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 3rem;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.subtitle {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
opacity: 0.95;
|
|
||||||
margin-bottom: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.features {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
|
||||||
gap: 30px;
|
|
||||||
margin-top: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-card {
|
|
||||||
background: white;
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 30px;
|
|
||||||
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
|
|
||||||
transition: transform 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-card:hover {
|
|
||||||
transform: translateY(-5px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-card h3 {
|
|
||||||
color: #0097a7;
|
|
||||||
font-size: 1.5rem;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-card p {
|
|
||||||
color: #666;
|
|
||||||
line-height: 1.8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cta-section {
|
|
||||||
text-align: center;
|
|
||||||
margin-top: 60px;
|
|
||||||
padding: 40px 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 15px 40px;
|
|
||||||
background: white;
|
|
||||||
color: #0097a7;
|
|
||||||
text-decoration: none;
|
|
||||||
border-radius: 30px;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
margin: 10px;
|
|
||||||
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
cursor: pointer;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn:hover {
|
|
||||||
transform: scale(1.05);
|
|
||||||
box-shadow: 0 8px 20px rgba(0,0,0,0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary {
|
|
||||||
background: #00bcd4;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal {
|
|
||||||
display: none;
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-color: rgba(0,0,0,0.7);
|
|
||||||
z-index: 1000;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal.show {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-content {
|
|
||||||
background: white;
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 40px;
|
|
||||||
max-width: 500px;
|
|
||||||
width: 90%;
|
|
||||||
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
|
|
||||||
position: relative;
|
|
||||||
animation: modalSlideIn 0.3s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes modalSlideIn {
|
|
||||||
from {
|
|
||||||
transform: translateY(-50px);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: translateY(0);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-close {
|
|
||||||
position: absolute;
|
|
||||||
top: 15px;
|
|
||||||
right: 20px;
|
|
||||||
font-size: 28px;
|
|
||||||
cursor: pointer;
|
|
||||||
color: #999;
|
|
||||||
transition: color 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-close:hover {
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-title {
|
|
||||||
color: #0097a7;
|
|
||||||
font-size: 1.8rem;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-body {
|
|
||||||
color: #666;
|
|
||||||
line-height: 1.8;
|
|
||||||
margin-bottom: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.download-info {
|
|
||||||
background: #f5f5f5;
|
|
||||||
padding: 20px;
|
|
||||||
border-radius: 8px;
|
|
||||||
border-left: 4px solid #00bcd4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.download-link {
|
|
||||||
color: #00bcd4;
|
|
||||||
text-decoration: none;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.download-link:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.password-info {
|
|
||||||
margin-top: 15px;
|
|
||||||
padding: 10px;
|
|
||||||
background: #fff3cd;
|
|
||||||
border-radius: 5px;
|
|
||||||
color: #856404;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gitee-widget-container {
|
|
||||||
margin-bottom: 60px;
|
|
||||||
padding: 30px 20px;
|
|
||||||
text-align: center;
|
|
||||||
background: rgba(46, 47, 41, 0.95);
|
|
||||||
border-radius: 10px;
|
|
||||||
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
#osc-gitee-widget-tag {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.osc_pro_color {color: #eae9d7 !important;}
|
|
||||||
.osc_panel_color {background-color: #2e2f29 !important;}
|
|
||||||
.osc_background_color {background-color: #272822 !important;}
|
|
||||||
.osc_border_color {border-color: #484a45 !important;}
|
|
||||||
.osc_desc_color {color: #eae9d7 !important;}
|
|
||||||
.osc_link_color * {color: #747571 !important;}
|
|
||||||
|
|
||||||
footer {
|
|
||||||
text-align: center;
|
|
||||||
padding: 40px 20px;
|
|
||||||
color: white;
|
|
||||||
opacity: 0.8;
|
|
||||||
margin-top: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.links {
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.links a {
|
|
||||||
color: white;
|
|
||||||
text-decoration: none;
|
|
||||||
margin: 0 15px;
|
|
||||||
opacity: 0.9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.links a:hover {
|
|
||||||
opacity: 1;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<header>
|
|
||||||
<div class="logo-container">
|
|
||||||
<svg viewBox="0 0 10 8" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<style>
|
|
||||||
:root {
|
|
||||||
--line-color: #ffffff;
|
|
||||||
--line-width: 0.6;
|
|
||||||
--scale: 10;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<g transform="scale(var(--scale))">
|
|
||||||
<path d="M0,0.1 H10" stroke="var(--line-color)" stroke-width="var(--line-width)" fill="none" />
|
|
||||||
<path d="M0,2 H3" stroke="var(--line-color)" stroke-width="var(--line-width)" fill="none" />
|
|
||||||
<path d="M0,4 H3 L4,2 L6,6 L7,4 H10" stroke="var(--line-color)" stroke-width="var(--line-width)" fill="none" />
|
|
||||||
<path d="M7,6 H10" stroke="var(--line-color)" stroke-width="var(--line-width)" fill="none" />
|
|
||||||
<path d="M0,7.9 H10" stroke="var(--line-color)" stroke-width="var(--line-width)" fill="none" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<h1>🍃 Mint Runtime</h1>
|
|
||||||
<p class="subtitle">安全特性驱动的 Lua 运行时环境</p>
|
|
||||||
<p style="font-size: 1.2rem; margin-top: 20px; font-weight: bold; letter-spacing: 3px;">开放 · 平等 · 共享</p>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<!-- Gitee 仓库预览部件 -->
|
|
||||||
<div class="gitee-widget-container">
|
|
||||||
<div id="osc-gitee-widget-tag"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="features">
|
|
||||||
<div class="feature-card">
|
|
||||||
<h3>🔒 安全保障</h3>
|
|
||||||
<p>提供强大的安全隔离机制,支持字节码限制、环境修改防护、深度外部调用钩子等多层次安全特性,确保代码执行的安全性。</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="feature-card">
|
|
||||||
<h3>⚡ 高性能</h3>
|
|
||||||
<p>基于 Rust 构建,结合 Lua 5.5 的高性能引擎,通过 LTO 链接时优化和代码生成单元优化,提供卓越的执行效率。</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="feature-card">
|
|
||||||
<h3>🌍 国际化支持</h3>
|
|
||||||
<p>内置 i10n 国际化框架,支持多语言日志和输出翻译,让全球开发者都能轻松使用。</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="feature-card">
|
|
||||||
<h3>📦 易于集成</h3>
|
|
||||||
<p>简洁的 API 设计,完善的文档支持,可快速集成到您的项目中。支持 Cargo 包管理,一键安装使用。</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="feature-card">
|
|
||||||
<h3>🛠️ 灵活配置</h3>
|
|
||||||
<p>支持 RON 配置文件格式,可自定义运行时行为、安全策略、日志级别等参数,满足各种使用场景。</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="feature-card">
|
|
||||||
<h3>📊 动态加载</h3>
|
|
||||||
<p>支持模块动态加载和日志速率限制,提供更细粒度的控制和资源管理能力。</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="cta-section">
|
|
||||||
<button onclick="openDownloadModal()" class="btn btn-primary">⬇️ 下载软件</button>
|
|
||||||
<a href="https://docs.rs/mintrt" class="btn">📖 查看文档</a>
|
|
||||||
<a href="https://gitee.com/snoware/mint" class="btn">⭐ Gitee 源码</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 下载对话框 -->
|
|
||||||
<div id="downloadModal" class="modal">
|
|
||||||
<div class="modal-content">
|
|
||||||
<span class="modal-close" onclick="closeDownloadModal()">×</span>
|
|
||||||
<h2 class="modal-title">⬇️ 下载 Mint Runtime</h2>
|
|
||||||
<div class="modal-body">
|
|
||||||
<div class="download-info">
|
|
||||||
<p><strong>下载地址:</strong></p>
|
|
||||||
<p><a href="https://snowcloud.lanzoum.com/b0zkqeipe" target="_blank" class="download-link">https://snowcloud.lanzoum.com/b0zkqeipe</a></p>
|
|
||||||
|
|
||||||
<div class="password-info">
|
|
||||||
<strong>🔐 提取码:</strong><code style="font-size: 1.2em; background: white; padding: 5px 10px; border-radius: 3px; margin-left: 10px;">guc5</code>
|
|
||||||
<p style="margin-top: 8px; font-size: 0.9em;">(部分作品)</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p style="margin-top: 20px; color: #666; font-size: 0.9em;">💡 提示:如果链接无法访问,请通过 Gitee 仓库获取最新版本。</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<p>© 2026 Mint Runtime. Licensed under MPL-2.0 OR Commercial</p>
|
|
||||||
<div class="links">
|
|
||||||
<a href="https://docs.rs/mintrt">API 文档</a>
|
|
||||||
<a href="https://gitee.com/snoware/mint/issues">问题反馈</a>
|
|
||||||
<a href="https://gitee.com/snoware/mint">贡献代码</a>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
function openDownloadModal() {
|
|
||||||
document.getElementById('downloadModal').classList.add('show');
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeDownloadModal() {
|
|
||||||
document.getElementById('downloadModal').classList.remove('show');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 点击模态框外部关闭
|
|
||||||
window.onclick = function(event) {
|
|
||||||
const modal = document.getElementById('downloadModal');
|
|
||||||
if (event.target === modal) {
|
|
||||||
closeDownloadModal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
[[projects]]
|
|
||||||
name = "MineSentinel"
|
|
||||||
description = "Minecraft 服务器智能守护进程,TCP 端口检测 + 崩溃自动重启 + 防循环冷却期"
|
|
||||||
repo_url = "https://gitee.com/snoware/minesentinel"
|
|
||||||
demo_url = "https://swe-iss.rth1.xyz/softwares/minesentinel"
|
|
||||||
doc_url = "https://gitee.com/snoware/minesentinel/blob/master/DEPLOY.md"
|
|
||||||
tags = ["Ruby", "Minecraft", "Server", "Monitoring", "Daemon", "SNOWARE"]
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
name = "btcli"
|
|
||||||
description = "一款在线命令行翻译工具,支持中文及其他语言,配备TUI界面"
|
|
||||||
repo_url = "https://gitee.com/ironbayberry/btcli"
|
|
||||||
demo_url = "https://swe-iss.rth1.xyz/softwares/btcli"
|
|
||||||
doc_url = "https://docs.rs/btcli"
|
|
||||||
tags = ["Rust", "CLI", "Translation", "TUI", "SASWE"]
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
name = "Reverberation"
|
|
||||||
description = "Story teller, it's more lightweight than nano and more convenient to use than echo."
|
|
||||||
repo_url = "https://gitee.com/ironbayberry/reverberation"
|
|
||||||
demo_url = "https://swe-iss.rth1.xyz/softwares/reverberation"
|
|
||||||
doc_url = "https://docs.rs/reverberation"
|
|
||||||
tags = ["CLI", "Chinese", "open-source", "SASWE", "Rust"]
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
name = "Mint Runtime"
|
|
||||||
description = "Security-featured runtime for Lua with i18n support, bytecode verification, and fine-grained access control."
|
|
||||||
repo_url = "https://gitee.com/snoware/mint"
|
|
||||||
demo_url = "https://swe-iss.rth1.xyz/softwares/mint"
|
|
||||||
doc_url = "https://docs.rs/mintrt"
|
|
||||||
tags = ["CLI", "Chinese", "open-source", "SASWE", "Rust", "Lua", "Runtime", "Security", "i18n"]
|
|
||||||
@@ -1,226 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-CN">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Reverberation - 轻量级文本阅读器</title>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
|
||||||
color: #333;
|
|
||||||
line-height: 1.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
max-width: 800px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
header {
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
padding: 20px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
color: #2c3e50;
|
|
||||||
font-size: 2.5em;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tagline {
|
|
||||||
font-size: 1.2em;
|
|
||||||
color: #7f8c8d;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
background: white;
|
|
||||||
border-radius: 10px;
|
|
||||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
||||||
padding: 25px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
color: #3498db;
|
|
||||||
border-bottom: 2px solid #eee;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
padding-left: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.usage {
|
|
||||||
background-color: #f8f9fa;
|
|
||||||
border-left: 4px solid #3498db;
|
|
||||||
padding: 15px;
|
|
||||||
font-family: monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
.author {
|
|
||||||
text-align: center;
|
|
||||||
margin-top: 30px;
|
|
||||||
color: #7f8c8d;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
.license {
|
|
||||||
background-color: #e8f4fd;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 15px;
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.buttons {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin: 20px 0;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button {
|
|
||||||
background-color: #3498db;
|
|
||||||
color: white;
|
|
||||||
padding: 12px 16px;
|
|
||||||
text-decoration: none;
|
|
||||||
border-radius: 5px;
|
|
||||||
font-weight: bold;
|
|
||||||
transition: background-color 0.3s;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
flex: 1;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button:hover {
|
|
||||||
background-color: #2980b9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.widget-section {
|
|
||||||
text-align: center;
|
|
||||||
margin: 30px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.osc_pro_color {color: #4183c4 !important;}
|
|
||||||
.osc_panel_color {background-color: #ffffff !important;}
|
|
||||||
.osc_background_color {background-color: #ffffff !important;}
|
|
||||||
.osc_border_color {border-color: #e3e9ed !important;}
|
|
||||||
.osc_desc_color {color: #666666 !important;}
|
|
||||||
.osc_link_color * {color: #9b9b9b !important;}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<header>
|
|
||||||
<h1>Reverberation</h1>
|
|
||||||
<div class="tagline">轻量级文本阅读器,比nano更轻便,比echo更实用</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div class="widget-section">
|
|
||||||
<script src='https://gitee.com/ironbayberry/reverberation/widget_preview' async defer></script>
|
|
||||||
<div id="osc-gitee-widget-tag"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="buttons">
|
|
||||||
<a href="https://gitee.com/ironbayberry/reverberation" target="_blank" class="button">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
|
|
||||||
<path d="M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0zm0 22.5c-5.799 0-10.5-4.701-10.5-10.5S6.201 1.5 12 1.5 22.5 6.201 22.5 12 17.799 22.5 12 22.5z"/>
|
|
||||||
<circle cx="7.5" cy="12" r="1.5"/>
|
|
||||||
<circle cx="12" cy="12" r="1.5"/>
|
|
||||||
<circle cx="16.5" cy="12" r="1.5"/>
|
|
||||||
</svg>
|
|
||||||
Gitee
|
|
||||||
</a>
|
|
||||||
<a href="https://crates.io/crates/reverberation" target="_blank" class="button">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
|
|
||||||
<path d="M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0zm0 22.5c-5.799 0-10.5-4.701-10.5-10.5S6.201 1.5 12 1.5 22.5 6.201 22.5 12 17.799 22.5 12 22.5z"/>
|
|
||||||
<path d="M16.5 8.25H7.5c-.828 0-1.5.672-1.5 1.5v4.5c0 .828.672 1.5 1.5 1.5h9c.828 0 1.5-.672 1.5-1.5v-4.5c0-.828-.672-1.5-1.5-1.5zM8.25 12.75h6v1.5h-6v-1.5z"/>
|
|
||||||
</svg>
|
|
||||||
Crates.io
|
|
||||||
</a>
|
|
||||||
<a href="https://docs.rs/reverberation" target="_blank" class="button">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
|
|
||||||
<path d="M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0zm0 22.5c-5.799 0-10.5-4.701-10.5-10.5S6.201 1.5 12 1.5 22.5 6.201 22.5 12 17.799 22.5 12 22.5z"/>
|
|
||||||
<path d="M12 4.5c-4.136 0-7.5 3.364-7.5 7.5s3.364 7.5 7.5 7.5 7.5-3.364 7.5-7.5-3.364-7.5-7.5-7.5zm0 13.5c-3.308 0-6-2.692-6-6s2.692-6 6-6 6 2.692 6 6-2.692 6-6 6z"/>
|
|
||||||
<path d="M12 7.5c-.828 0-1.5.672-1.5 1.5s.672 1.5 1.5 1.5 1.5-.672 1.5-1.5-.672-1.5-1.5-1.5z"/>
|
|
||||||
</svg>
|
|
||||||
Docs.rs
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<main>
|
|
||||||
<div class="card">
|
|
||||||
<h2>项目简介</h2>
|
|
||||||
<p>Reverberation 是一款轻量级的命令行工具,可以逐字显示文本内容,并带有可配置的延迟时间。它设计简洁,易于使用,适合展示文本内容或逐步阅读文本。</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
<h2>功能特性</h2>
|
|
||||||
<ul>
|
|
||||||
<li>逐字显示文本内容</li>
|
|
||||||
<li>可配置字符显示间隔时间</li>
|
|
||||||
<li>轻量级设计,资源占用少</li>
|
|
||||||
<li>简单易用的命令行界面</li>
|
|
||||||
<li>支持任意文本文件格式</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
<h2>使用方法</h2>
|
|
||||||
<p>在命令行中运行以下命令:</p>
|
|
||||||
<div class="usage">
|
|
||||||
reverberation <filename> <delay_ms>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><strong>filename</strong>: 要逐字显示的文本文件</li>
|
|
||||||
<li><strong>delay_ms</strong>: 每个字符之间的延迟时间(毫秒)</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p>获取帮助信息:</p>
|
|
||||||
<div class="usage">
|
|
||||||
reverberation --help
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
<h2>构建方法</h2>
|
|
||||||
<p>使用 Cargo 构建发布版本:</p>
|
|
||||||
<div class="usage">
|
|
||||||
cargo build --release
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card">
|
|
||||||
<h2>安装方法</h2>
|
|
||||||
<p>使用 Cargo 一键安装:</p>
|
|
||||||
<div class="usage">
|
|
||||||
cargo install reverberation
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card license">
|
|
||||||
<h2>许可证</h2>
|
|
||||||
<p>此项目采用 Mozilla Public License Version 2.0 许可证。</p>
|
|
||||||
<p>完整的许可证文本可在项目根目录下的 LICENSE 文件中找到。</p>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<footer class="author">
|
|
||||||
Designed by S.A. | (C) SNOWARE 2026
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -0,0 +1,458 @@
|
|||||||
|
/* ===== SNOWARE — Dual Theme ===== */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--bg: #1a1710;
|
||||||
|
--bg-soft: #242016;
|
||||||
|
--bg-card: #2c2818;
|
||||||
|
--accent: #c8a87a;
|
||||||
|
--accent-warm: #e8c9a0;
|
||||||
|
--accent-cool: #8a9a7e;
|
||||||
|
--text: #e0d8c8;
|
||||||
|
--text-muted: #9e9585;
|
||||||
|
--text-dim: #6b6358;
|
||||||
|
--border: rgba(200,168,122,0.12);
|
||||||
|
--border-hover: rgba(200,168,122,0.28);
|
||||||
|
--radius: 10px;
|
||||||
|
--font: 'Segoe UI', system-ui, -apple-system, sans-serif;
|
||||||
|
--mono: 'Cascadia Code', 'Fira Code', monospace;
|
||||||
|
--transition: 0.25s ease;
|
||||||
|
--nav-bg: rgba(26,23,16,0.92);
|
||||||
|
--logo-border: rgba(200,168,122,0.3);
|
||||||
|
--logo-bg: rgba(44,40,24,0.5);
|
||||||
|
--btn-hover-bg: rgba(200,168,122,0.08);
|
||||||
|
--service-hover-bg: rgba(200,168,122,0.06);
|
||||||
|
--code-bg: rgba(255,255,255,0.05);
|
||||||
|
--code-inline-bg: rgba(255,255,255,0.06);
|
||||||
|
--warning-bg: rgba(180,60,50,0.06);
|
||||||
|
--warning-border: rgba(180,60,50,0.25);
|
||||||
|
--warning-h: #b84040;
|
||||||
|
--noise-svg: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.03'/%3E%3C/svg%3E");
|
||||||
|
--btn-accent-bg: rgba(200,168,122,0.1);
|
||||||
|
--btn-accent-hover-bg: rgba(200,168,122,0.18);
|
||||||
|
--subject-inline-bg: rgba(255,255,255,0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Macaron Cyan theme (dark) */
|
||||||
|
[data-theme="cyan"] {
|
||||||
|
--bg: #101820;
|
||||||
|
--bg-soft: #161e2c;
|
||||||
|
--bg-card: #1c2636;
|
||||||
|
--accent: #5cb8e4;
|
||||||
|
--accent-warm: #81d4fa;
|
||||||
|
--accent-cool: #7ec8e3;
|
||||||
|
--text: #c8dce8;
|
||||||
|
--text-muted: #8aa4b8;
|
||||||
|
--text-dim: #5a7a90;
|
||||||
|
--border: rgba(92,184,228,0.12);
|
||||||
|
--border-hover: rgba(92,184,228,0.28);
|
||||||
|
--nav-bg: rgba(16,24,32,0.92);
|
||||||
|
--logo-border: rgba(92,184,228,0.35);
|
||||||
|
--logo-bg: rgba(28,38,54,0.5);
|
||||||
|
--btn-hover-bg: rgba(92,184,228,0.08);
|
||||||
|
--service-hover-bg: rgba(92,184,228,0.06);
|
||||||
|
--code-bg: rgba(255,255,255,0.04);
|
||||||
|
--code-inline-bg: rgba(255,255,255,0.06);
|
||||||
|
--warning-bg: rgba(180,60,50,0.06);
|
||||||
|
--warning-border: rgba(180,60,50,0.25);
|
||||||
|
--warning-h: #c04040;
|
||||||
|
--noise-svg: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.03'/%3E%3C/svg%3E");
|
||||||
|
--btn-accent-bg: rgba(92,184,228,0.1);
|
||||||
|
--btn-accent-hover-bg: rgba(92,184,228,0.18);
|
||||||
|
--subject-inline-bg: rgba(255,255,255,0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
||||||
|
html { scroll-behavior: smooth; }
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: var(--font);
|
||||||
|
background: transparent;
|
||||||
|
color: var(--text);
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
line-height: 1.7;
|
||||||
|
transition: color var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container { max-width: 920px; margin: 0 auto; padding: 0 24px; }
|
||||||
|
|
||||||
|
/* ===== Theme Toggle ===== */
|
||||||
|
.theme-toggle {
|
||||||
|
background: none; border: none; cursor: pointer;
|
||||||
|
padding: 4px; color: var(--text-muted);
|
||||||
|
transition: color var(--transition);
|
||||||
|
display: flex; align-items: center; justify-content: center;
|
||||||
|
}
|
||||||
|
.theme-toggle:hover { color: var(--accent); }
|
||||||
|
[data-theme="warm"] .theme-icon-warm,
|
||||||
|
[data-theme="cyan"] .theme-icon-cyan { display: block; }
|
||||||
|
[data-theme="warm"] .theme-icon-cyan,
|
||||||
|
[data-theme="cyan"] .theme-icon-warm { display: none; }
|
||||||
|
|
||||||
|
/* Logo color shift for cyan theme — sepia+hue-rotate for precise warm→cool conversion */
|
||||||
|
[data-theme="cyan"] .nav-logo,
|
||||||
|
[data-theme="cyan"] .home-logo,
|
||||||
|
[data-theme="cyan"] .xag-logo,
|
||||||
|
[data-theme="cyan"] .warning-logo,
|
||||||
|
[data-theme="cyan"] .error-logo {
|
||||||
|
filter: sepia(0.6) hue-rotate(190deg) saturate(1.5) brightness(1.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Navigation ===== */
|
||||||
|
.site-nav {
|
||||||
|
position: sticky; top: 0; z-index: 100;
|
||||||
|
background: var(--nav-bg);
|
||||||
|
backdrop-filter: blur(14px);
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
padding: 10px 0;
|
||||||
|
transition: background-color var(--transition), border-color var(--transition);
|
||||||
|
}
|
||||||
|
.nav-inner { display: flex; align-items: center; justify-content: space-between; }
|
||||||
|
.nav-brand {
|
||||||
|
display: flex; align-items: center; gap: 10px;
|
||||||
|
color: var(--text); font-weight: 700; font-size: 17px; text-decoration: none;
|
||||||
|
transition: color var(--transition);
|
||||||
|
}
|
||||||
|
.nav-brand img { border-radius: 50%; }
|
||||||
|
.nav-links { display: flex; gap: 22px; align-items: center; }
|
||||||
|
.nav-links a {
|
||||||
|
color: var(--text-muted); text-decoration: none; font-size: 13.5px;
|
||||||
|
transition: color var(--transition); position: relative;
|
||||||
|
}
|
||||||
|
.nav-links a:hover { color: var(--accent-warm); }
|
||||||
|
.nav-links a::after {
|
||||||
|
content: ''; position: absolute; bottom: -3px; left: 0;
|
||||||
|
width: 0; height: 1.5px; background: var(--accent);
|
||||||
|
transition: width var(--transition);
|
||||||
|
}
|
||||||
|
.nav-links a:hover::after { width: 100%; }
|
||||||
|
|
||||||
|
/* ===== Homepage ===== */
|
||||||
|
.home-hero {
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex; flex-direction: column;
|
||||||
|
align-items: center; justify-content: center;
|
||||||
|
padding: 60px 24px;
|
||||||
|
gap: 32px;
|
||||||
|
}
|
||||||
|
.home-hero .logo-wrap { text-align: center; }
|
||||||
|
.home-hero .home-logo {
|
||||||
|
width: 160px; height: 160px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 2px solid var(--logo-border);
|
||||||
|
background: var(--logo-bg);
|
||||||
|
backdrop-filter: blur(8px);
|
||||||
|
transition: border-color var(--transition), background-color var(--transition);
|
||||||
|
}
|
||||||
|
.home-title {
|
||||||
|
font-size: 44px; font-weight: 700; letter-spacing: 6px;
|
||||||
|
color: var(--accent-warm);
|
||||||
|
margin: 0;
|
||||||
|
transition: color var(--transition);
|
||||||
|
}
|
||||||
|
/* Poem section */
|
||||||
|
.home-poem {
|
||||||
|
text-align: center;
|
||||||
|
max-width: 560px;
|
||||||
|
margin: 0 auto;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.poem-line {
|
||||||
|
color: var(--text-muted);
|
||||||
|
font-size: 14.5px;
|
||||||
|
line-height: 2;
|
||||||
|
opacity: 0;
|
||||||
|
animation: poemFadeIn 1.2s ease forwards;
|
||||||
|
transition: color var(--transition);
|
||||||
|
}
|
||||||
|
.poem-line.fade-1 { animation-delay: 0.3s; color: var(--accent-warm); font-size: 15px; }
|
||||||
|
.poem-line.fade-2 { animation-delay: 0.9s; }
|
||||||
|
.poem-line.fade-3 { animation-delay: 1.5s; color: var(--accent-warm); font-size: 15px; }
|
||||||
|
.poem-line.fade-4 { animation-delay: 2.1s; }
|
||||||
|
.poem-sig {
|
||||||
|
color: var(--text-dim);
|
||||||
|
font-size: 12px;
|
||||||
|
margin-top: 14px;
|
||||||
|
opacity: 0;
|
||||||
|
animation: poemFadeIn 1s ease 2.7s forwards;
|
||||||
|
font-family: var(--mono);
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
@keyframes poemFadeIn {
|
||||||
|
from { opacity: 0; transform: translateY(10px); }
|
||||||
|
to { opacity: 1; transform: translateY(0); }
|
||||||
|
}
|
||||||
|
.home-poem::before {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
width: 60px;
|
||||||
|
height: 1px;
|
||||||
|
background: linear-gradient(to right, transparent, var(--accent), transparent);
|
||||||
|
margin: 0 auto 20px auto;
|
||||||
|
opacity: 0;
|
||||||
|
animation: poemFadeIn 0.8s ease 0.1s forwards;
|
||||||
|
}
|
||||||
|
.home-poem::after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
width: 60px;
|
||||||
|
height: 1px;
|
||||||
|
background: linear-gradient(to right, transparent, var(--accent), transparent);
|
||||||
|
margin: 20px auto 0 auto;
|
||||||
|
opacity: 0;
|
||||||
|
animation: poemFadeIn 0.8s ease 3.2s forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Homepage nav buttons */
|
||||||
|
.home-nav { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; }
|
||||||
|
.home-btn {
|
||||||
|
padding: 11px 26px; border-radius: 8px;
|
||||||
|
background: var(--bg-card); border: 1px solid var(--border);
|
||||||
|
color: var(--text); text-decoration: none; font-size: 14px; font-weight: 500;
|
||||||
|
transition: all var(--transition);
|
||||||
|
}
|
||||||
|
.home-btn:hover {
|
||||||
|
border-color: var(--border-hover);
|
||||||
|
background: var(--btn-hover-bg);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Services section on homepage */
|
||||||
|
.home-services {
|
||||||
|
margin-top: 48px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.home-services h2 {
|
||||||
|
font-size: 15px; color: var(--text-dim); font-weight: 500;
|
||||||
|
letter-spacing: 2px; text-transform: uppercase; margin-bottom: 20px;
|
||||||
|
transition: color var(--transition);
|
||||||
|
}
|
||||||
|
.services-grid {
|
||||||
|
display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px;
|
||||||
|
max-width: 720px; margin: 0 auto;
|
||||||
|
}
|
||||||
|
.service-card {
|
||||||
|
padding: 20px 16px; border-radius: var(--radius);
|
||||||
|
background: var(--bg-card); border: 1px solid var(--border);
|
||||||
|
text-decoration: none; color: var(--text);
|
||||||
|
transition: all var(--transition);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.service-card:hover {
|
||||||
|
border-color: var(--border-hover);
|
||||||
|
background: var(--service-hover-bg);
|
||||||
|
}
|
||||||
|
.service-icon {
|
||||||
|
display: flex; justify-content: center; margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.service-icon svg { width: 28px; height: 28px; stroke: var(--accent); fill: none; stroke-width: 1.8; }
|
||||||
|
.service-card h3 { font-size: 14px; color: var(--accent-warm); margin-bottom: 4px; }
|
||||||
|
.service-card p { font-size: 12.5px; color: var(--text-muted); }
|
||||||
|
.service-card.no-link { cursor: default; }
|
||||||
|
.service-card.no-link:hover { background: var(--bg-card); border-color: var(--border); transform: none; }
|
||||||
|
|
||||||
|
/* ===== Page Hero ===== */
|
||||||
|
.page-hero {
|
||||||
|
text-align: center; padding: 72px 24px 36px;
|
||||||
|
}
|
||||||
|
.page-hero h1 {
|
||||||
|
font-size: 36px; font-weight: 700;
|
||||||
|
color: var(--accent-warm); margin-bottom: 6px;
|
||||||
|
transition: color var(--transition);
|
||||||
|
}
|
||||||
|
.page-hero .subtitle { color: var(--text-muted); font-size: 16px; }
|
||||||
|
|
||||||
|
/* ===== Page Content ===== */
|
||||||
|
.page-content { padding: 16px 24px 60px; }
|
||||||
|
|
||||||
|
/* ===== Buttons ===== */
|
||||||
|
.btn {
|
||||||
|
display: inline-block; padding: 9px 22px; border-radius: 8px;
|
||||||
|
font-size: 14px; font-weight: 500; text-decoration: none;
|
||||||
|
transition: all var(--transition); cursor: pointer;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
}
|
||||||
|
.btn-primary { background: var(--accent); color: var(--bg); border-color: var(--accent); }
|
||||||
|
.btn-primary:hover { background: var(--accent-warm); }
|
||||||
|
.btn-accent {
|
||||||
|
background: var(--btn-accent-bg); color: var(--accent);
|
||||||
|
border-color: var(--border-hover);
|
||||||
|
}
|
||||||
|
.btn-accent:hover { background: var(--btn-accent-hover-bg); }
|
||||||
|
.btn-outline { background: transparent; color: var(--text-muted); border-color: var(--border); }
|
||||||
|
.btn-outline:hover { border-color: var(--text-muted); color: var(--text); }
|
||||||
|
.btn-lg { padding: 13px 30px; font-size: 16px; }
|
||||||
|
|
||||||
|
/* ===== Cards ===== */
|
||||||
|
.card-base {
|
||||||
|
background: var(--bg-card);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius);
|
||||||
|
backdrop-filter: blur(6px);
|
||||||
|
transition: all var(--transition);
|
||||||
|
}
|
||||||
|
.card-base:hover { border-color: var(--border-hover); }
|
||||||
|
|
||||||
|
.feature-card {
|
||||||
|
padding: 22px; text-align: center;
|
||||||
|
}
|
||||||
|
.feature-card h3 { color: var(--accent-warm); font-size: 15px; margin-bottom: 6px; }
|
||||||
|
.feature-card p { color: var(--text-muted); font-size: 13px; }
|
||||||
|
.feature-icon { font-size: 28px; margin-bottom: 10px; color: var(--accent); }
|
||||||
|
|
||||||
|
/* ===== Resources Section ===== */
|
||||||
|
.res-intro { text-align: center; margin-bottom: 28px; }
|
||||||
|
.res-intro-text { color: var(--text); font-size: 15px; }
|
||||||
|
.res-actions {
|
||||||
|
display: flex; gap: 14px; justify-content: center;
|
||||||
|
margin-bottom: 36px; flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.res-features {
|
||||||
|
display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-top: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== File List ===== */
|
||||||
|
.filelist-grid {
|
||||||
|
display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px;
|
||||||
|
}
|
||||||
|
.subject-card {
|
||||||
|
display: flex; flex-direction: column; align-items: center; gap: 8px;
|
||||||
|
padding: 24px 16px;
|
||||||
|
background: var(--bg-card);
|
||||||
|
border: 1px solid color-mix(in srgb, var(--color) 20%, transparent);
|
||||||
|
border-radius: var(--radius);
|
||||||
|
text-decoration: none; color: var(--text);
|
||||||
|
transition: all var(--transition);
|
||||||
|
}
|
||||||
|
.subject-card:hover {
|
||||||
|
border-color: var(--color);
|
||||||
|
background: color-mix(in srgb, var(--color) 6%, var(--bg-card));
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
.subject-icon svg { width: 36px; height: 36px; stroke: var(--color); fill: none; stroke-width: 1.5; }
|
||||||
|
.subject-card h3 { font-size: 17px; }
|
||||||
|
.subject-pw { font-size: 12.5px; color: var(--text-muted); }
|
||||||
|
.subject-pw code {
|
||||||
|
background: var(--subject-inline-bg); padding: 2px 7px; border-radius: 4px;
|
||||||
|
color: var(--color); font-family: var(--mono);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Software Section ===== */
|
||||||
|
.about-intro {
|
||||||
|
text-align: center; margin-bottom: 36px; padding: 22px;
|
||||||
|
background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius);
|
||||||
|
}
|
||||||
|
.about-intro p { color: var(--text-muted); margin-bottom: 14px; }
|
||||||
|
.project-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; }
|
||||||
|
.project-card {
|
||||||
|
display: flex; flex-direction: column; gap: 10px; padding: 24px;
|
||||||
|
background: var(--bg-card);
|
||||||
|
border: 1px solid color-mix(in srgb, var(--accent) 15%, transparent);
|
||||||
|
border-radius: var(--radius);
|
||||||
|
text-decoration: none; color: var(--text);
|
||||||
|
transition: all var(--transition);
|
||||||
|
}
|
||||||
|
.project-card:hover {
|
||||||
|
border-color: var(--accent);
|
||||||
|
background: color-mix(in srgb, var(--accent) 4%, var(--bg-card));
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
.card-header { display: flex; justify-content: space-between; align-items: flex-start; }
|
||||||
|
.card-header h3 { font-size: 18px; color: var(--accent-warm); }
|
||||||
|
.card-tags { display: flex; gap: 5px; flex-wrap: wrap; }
|
||||||
|
.tag {
|
||||||
|
font-size: 11px; padding: 2px 9px; border-radius: 50px;
|
||||||
|
background: color-mix(in srgb, var(--accent) 12%, var(--bg-card));
|
||||||
|
color: var(--accent); border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
|
||||||
|
}
|
||||||
|
.card-desc { color: var(--text-muted); font-size: 13.5px; }
|
||||||
|
.card-links { margin-top: auto; }
|
||||||
|
.card-link { font-size: 13.5px; color: var(--accent); }
|
||||||
|
|
||||||
|
/* ===== Software Detail ===== */
|
||||||
|
.sw-links { display: flex; gap: 10px; justify-content: center; margin-bottom: 36px; flex-wrap: wrap; }
|
||||||
|
.sw-features { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-bottom: 36px; }
|
||||||
|
.sw-section {
|
||||||
|
margin-bottom: 28px; padding: 22px;
|
||||||
|
background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius);
|
||||||
|
}
|
||||||
|
.sw-section h2 { color: var(--accent-warm); margin-bottom: 10px; font-size: 20px; }
|
||||||
|
.sw-code {
|
||||||
|
background: var(--code-bg); padding: 10px 16px; border-radius: 6px;
|
||||||
|
font-family: var(--mono); font-size: 13px; overflow-x: auto; color: var(--text);
|
||||||
|
}
|
||||||
|
.usage-list { display: flex; flex-direction: column; gap: 10px; }
|
||||||
|
.usage-item { display: flex; gap: 10px; align-items: center; }
|
||||||
|
.usage-item code {
|
||||||
|
background: var(--code-inline-bg); padding: 5px 10px; border-radius: 5px;
|
||||||
|
font-family: var(--mono); font-size: 12.5px; white-space: nowrap;
|
||||||
|
}
|
||||||
|
.usage-item span { color: var(--text-muted); font-size: 13px; }
|
||||||
|
|
||||||
|
/* ===== Drag Ball ===== */
|
||||||
|
.drag-ball-area {
|
||||||
|
text-align: center; padding: 22px; margin: 36px 0;
|
||||||
|
background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius);
|
||||||
|
}
|
||||||
|
.drag-hint { color: var(--text-muted); font-size: 13px; margin-top: 6px; }
|
||||||
|
|
||||||
|
/* ===== XAGuarder ===== */
|
||||||
|
.xag-intro {
|
||||||
|
text-align: center; padding: 36px;
|
||||||
|
background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius);
|
||||||
|
max-width: 560px; margin: 0 auto;
|
||||||
|
}
|
||||||
|
.xag-logo { border-radius: 50%; margin-bottom: 14px; }
|
||||||
|
.xag-intro h2 { margin-bottom: 14px; color: var(--accent-warm); }
|
||||||
|
.xag-intro p { color: var(--text-muted); margin-bottom: 18px; }
|
||||||
|
|
||||||
|
/* ===== Warning Page ===== */
|
||||||
|
.warning-page {
|
||||||
|
min-height: 80vh; display: flex; align-items: center; justify-content: center;
|
||||||
|
}
|
||||||
|
.warning-content {
|
||||||
|
text-align: center; padding: 50px;
|
||||||
|
background: var(--warning-bg); border: 2px solid var(--warning-border);
|
||||||
|
border-radius: var(--radius); max-width: 480px;
|
||||||
|
transition: background-color var(--transition), border-color var(--transition);
|
||||||
|
}
|
||||||
|
.warning-logo { border-radius: 50%; margin-bottom: 18px; }
|
||||||
|
.warning-content h1 { color: var(--warning-h); font-size: 26px; margin-bottom: 14px; }
|
||||||
|
.warning-text { font-size: 16px; color: var(--text); margin-bottom: 6px; }
|
||||||
|
.warning-sub { color: var(--text-muted); font-size: 13px; margin-bottom: 22px; }
|
||||||
|
|
||||||
|
/* ===== Error Page ===== */
|
||||||
|
.error-page { min-height: 80vh; display: flex; align-items: center; justify-content: center; }
|
||||||
|
.error-content { text-align: center; }
|
||||||
|
.error-logo { border-radius: 50%; margin-bottom: 18px; }
|
||||||
|
.error-content h1 { font-size: 64px; color: var(--accent); margin-bottom: 10px; }
|
||||||
|
.error-content p { color: var(--text-muted); }
|
||||||
|
.error-hint { font-size: 13px; margin-bottom: 22px; }
|
||||||
|
|
||||||
|
/* ===== Footer ===== */
|
||||||
|
.site-footer {
|
||||||
|
text-align: center; padding: 22px;
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
color: var(--text-dim); font-size: 12.5px; margin-top: auto;
|
||||||
|
transition: border-color var(--transition), color var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Responsive ===== */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.nav-inner { flex-direction: column; gap: 10px; }
|
||||||
|
.nav-links { gap: 14px; }
|
||||||
|
.home-title { font-size: 30px; letter-spacing: 4px; }
|
||||||
|
.home-hero .home-logo { width: 120px; height: 120px; }
|
||||||
|
.services-grid { grid-template-columns: 1fr 1fr; max-width: 360px; }
|
||||||
|
.page-hero h1 { font-size: 26px; }
|
||||||
|
.project-grid { grid-template-columns: 1fr; }
|
||||||
|
.filelist-grid { grid-template-columns: repeat(2, 1fr); }
|
||||||
|
.res-features, .sw-features { grid-template-columns: 1fr 1fr; }
|
||||||
|
}
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.services-grid { grid-template-columns: 1fr; max-width: 280px; }
|
||||||
|
.filelist-grid { grid-template-columns: 1fr; }
|
||||||
|
.res-features, .sw-features { grid-template-columns: 1fr; }
|
||||||
|
.sw-links { flex-direction: column; align-items: center; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
(function () {
|
||||||
|
const canvas = document.getElementById('drag-ball');
|
||||||
|
if (!canvas) return;
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
const W = 200, H = 200;
|
||||||
|
canvas.width = W;
|
||||||
|
canvas.height = H;
|
||||||
|
|
||||||
|
let ballX = W / 2, ballY = H / 2;
|
||||||
|
let dragging = false;
|
||||||
|
let offsetX = 0, offsetY = 0;
|
||||||
|
|
||||||
|
function drawBall() {
|
||||||
|
ctx.clearRect(0, 0, W, H);
|
||||||
|
const r = 30;
|
||||||
|
const grad = ctx.createRadialGradient(ballX, ballY, 0, ballX, ballY, r);
|
||||||
|
grad.addColorStop(0, '#ffb300');
|
||||||
|
grad.addColorStop(1, '#ff6f00');
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(ballX, ballY, r, 0, Math.PI * 2);
|
||||||
|
ctx.fillStyle = grad;
|
||||||
|
ctx.fill();
|
||||||
|
ctx.fillStyle = '#fff';
|
||||||
|
ctx.font = '14px sans-serif';
|
||||||
|
ctx.textAlign = 'center';
|
||||||
|
ctx.textBaseline = 'middle';
|
||||||
|
ctx.fillText('(¬‿¬)', ballX, ballY);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPos(e) {
|
||||||
|
const rect = canvas.getBoundingClientRect();
|
||||||
|
const scaleX = W / rect.width;
|
||||||
|
const scaleY = H / rect.height;
|
||||||
|
if (e.touches) {
|
||||||
|
return {
|
||||||
|
x: (e.touches[0].clientX - rect.left) * scaleX,
|
||||||
|
y: (e.touches[0].clientY - rect.top) * scaleY
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
x: (e.clientX - rect.left) * scaleX,
|
||||||
|
y: (e.clientY - rect.top) * scaleY
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.addEventListener('mousedown', (e) => {
|
||||||
|
const pos = getPos(e);
|
||||||
|
const dist = Math.hypot(pos.x - ballX, pos.y - ballY);
|
||||||
|
if (dist < 30) { dragging = true; offsetX = pos.x - ballX; offsetY = pos.y - ballY; }
|
||||||
|
});
|
||||||
|
canvas.addEventListener('touchstart', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const pos = getPos(e);
|
||||||
|
const dist = Math.hypot(pos.x - ballX, pos.y - ballY);
|
||||||
|
if (dist < 30) { dragging = true; offsetX = pos.x - ballX; offsetY = pos.y - ballY; }
|
||||||
|
}, { passive: false });
|
||||||
|
|
||||||
|
window.addEventListener('mousemove', (e) => {
|
||||||
|
if (!dragging) return;
|
||||||
|
const pos = getPos(e);
|
||||||
|
ballX = Math.max(30, Math.min(W - 30, pos.x - offsetX));
|
||||||
|
ballY = Math.max(30, Math.min(H - 30, pos.y - offsetY));
|
||||||
|
drawBall();
|
||||||
|
});
|
||||||
|
window.addEventListener('touchmove', (e) => {
|
||||||
|
if (!dragging) return;
|
||||||
|
const pos = getPos(e);
|
||||||
|
ballX = Math.max(30, Math.min(W - 30, pos.x - offsetX));
|
||||||
|
ballY = Math.max(30, Math.min(H - 30, pos.y - offsetY));
|
||||||
|
drawBall();
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener('mouseup', () => { dragging = false; });
|
||||||
|
window.addEventListener('touchend', () => { dragging = false; });
|
||||||
|
|
||||||
|
drawBall();
|
||||||
|
})();
|
||||||
@@ -0,0 +1,216 @@
|
|||||||
|
// SNOWARE — Dynamic Nature Background (Stars + Mountains + Meteors)
|
||||||
|
(function(){
|
||||||
|
var canvas = document.createElement('canvas');
|
||||||
|
canvas.id = 'nature-bg';
|
||||||
|
canvas.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;z-index:-1;pointer-events:none;';
|
||||||
|
document.body.prepend(canvas);
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
var stars = [], shootingStars = [];
|
||||||
|
var W, H;
|
||||||
|
var lastShooting = 0;
|
||||||
|
|
||||||
|
function resize(){
|
||||||
|
W = canvas.width = window.innerWidth;
|
||||||
|
H = canvas.height = window.innerHeight;
|
||||||
|
initStars();
|
||||||
|
}
|
||||||
|
|
||||||
|
function initStars(){
|
||||||
|
stars = [];
|
||||||
|
var count = Math.floor(W * H / 2800);
|
||||||
|
for(var i = 0; i < count; i++){
|
||||||
|
stars.push({
|
||||||
|
x: Math.random() * W,
|
||||||
|
y: Math.random() * H * 0.55,
|
||||||
|
r: Math.random() * 1.5 + 0.3,
|
||||||
|
a: Math.random() * 0.6 + 0.2,
|
||||||
|
speed: Math.random() * 0.008 + 0.002,
|
||||||
|
phase: Math.random() * Math.PI * 2
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addShootingStar(){
|
||||||
|
shootingStars.push({
|
||||||
|
x: Math.random() * W * 0.6 + W * 0.1,
|
||||||
|
y: Math.random() * H * 0.25,
|
||||||
|
len: Math.random() * 120 + 60,
|
||||||
|
speed: Math.random() * 6 + 4,
|
||||||
|
angle: Math.random() * 0.25 + 0.15,
|
||||||
|
a: 1,
|
||||||
|
life: 0,
|
||||||
|
sparks: []
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTheme(){
|
||||||
|
return document.documentElement.getAttribute('data-theme') || 'warm';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getColors(){
|
||||||
|
var t = getTheme();
|
||||||
|
if(t === 'cyan'){
|
||||||
|
return {
|
||||||
|
sky1: '#0a1525', sky2: '#101828', sky3: '#182436',
|
||||||
|
star: '#c8dff0', starBright: '#81d4fa',
|
||||||
|
mtn1: '#0e1826', mtn2: '#162230', mtn3: '#1e2e40',
|
||||||
|
mtnLine: 'rgba(92,184,228,0.12)', mtnSnow: 'rgba(200,220,240,0.08)',
|
||||||
|
shoot: '#81d4fa', shootGlow: 'rgba(129,212,250,0.2)'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
sky1: '#0a0c08', sky2: '#141210', sky3: '#1a1710',
|
||||||
|
star: '#d4c0a0', starBright: '#e8c9a0',
|
||||||
|
mtn1: '#0e0c08', mtn2: '#181610', mtn3: '#242014',
|
||||||
|
mtnLine: 'rgba(200,168,122,0.08)', mtnSnow: 'rgba(232,201,160,0.06)',
|
||||||
|
shoot: '#e8c9a0', shootGlow: 'rgba(232,201,160,0.15)'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawSky(c){
|
||||||
|
var g = ctx.createLinearGradient(0, 0, 0, H);
|
||||||
|
g.addColorStop(0, c.sky1);
|
||||||
|
g.addColorStop(0.35, c.sky2);
|
||||||
|
g.addColorStop(1, c.sky3);
|
||||||
|
ctx.fillStyle = g;
|
||||||
|
ctx.fillRect(0, 0, W, H);
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawStars(c, t){
|
||||||
|
for(var i = 0; i < stars.length; i++){
|
||||||
|
var s = stars[i];
|
||||||
|
var twinkle = Math.sin(t * s.speed + s.phase) * 0.3 + 0.7;
|
||||||
|
var alpha = s.a * twinkle;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(s.x, s.y, s.r, 0, Math.PI * 2);
|
||||||
|
ctx.fillStyle = s.r > 1.2 ? c.starBright : c.star;
|
||||||
|
ctx.globalAlpha = alpha;
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
ctx.globalAlpha = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawShootingStars(c, t){
|
||||||
|
// More frequent meteors: every 3-7 seconds
|
||||||
|
if(t - lastShooting > 3000 + Math.random() * 4000){
|
||||||
|
addShootingStar();
|
||||||
|
lastShooting = t;
|
||||||
|
}
|
||||||
|
for(var i = shootingStars.length - 1; i >= 0; i--){
|
||||||
|
var s = shootingStars[i];
|
||||||
|
s.life += 1;
|
||||||
|
s.x += s.speed;
|
||||||
|
s.y += s.speed * s.angle;
|
||||||
|
s.a -= 0.008;
|
||||||
|
if(s.a <= 0){ shootingStars.splice(i, 1); continue; }
|
||||||
|
|
||||||
|
// Head glow
|
||||||
|
ctx.save();
|
||||||
|
ctx.globalAlpha = s.a * 0.6;
|
||||||
|
var headGlow = ctx.createRadialGradient(s.x, s.y, 0, s.x, s.y, 8);
|
||||||
|
headGlow.addColorStop(0, c.shoot);
|
||||||
|
headGlow.addColorStop(1, 'transparent');
|
||||||
|
ctx.fillStyle = headGlow;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(s.x, s.y, 8, 0, Math.PI * 2);
|
||||||
|
ctx.fill();
|
||||||
|
|
||||||
|
// Main trail
|
||||||
|
ctx.globalAlpha = s.a;
|
||||||
|
ctx.strokeStyle = c.shoot;
|
||||||
|
ctx.lineWidth = 1.8;
|
||||||
|
ctx.lineCap = 'round';
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(s.x, s.y);
|
||||||
|
var tailX = s.x - s.len * Math.cos(s.angle);
|
||||||
|
var tailY = s.y - s.len * Math.sin(s.angle);
|
||||||
|
ctx.lineTo(tailX, tailY);
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
// Wide glow trail
|
||||||
|
ctx.globalAlpha = s.a * 0.25;
|
||||||
|
ctx.lineWidth = 6;
|
||||||
|
ctx.strokeStyle = c.shoot;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(s.x, s.y);
|
||||||
|
ctx.lineTo(s.x - s.len * 0.5 * Math.cos(s.angle), s.y - s.len * 0.5 * Math.sin(s.angle));
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
// Secondary thin glow trail
|
||||||
|
ctx.globalAlpha = s.a * 0.12;
|
||||||
|
ctx.lineWidth = 12;
|
||||||
|
ctx.strokeStyle = c.shootGlow;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(s.x, s.y);
|
||||||
|
ctx.lineTo(s.x - s.len * 0.3 * Math.cos(s.angle), s.y - s.len * 0.3 * Math.sin(s.angle));
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawMountainLayer(yBase, height, color, lineColor, snowPatches, seed){
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(0, yBase);
|
||||||
|
var step = 3;
|
||||||
|
for(var x = 0; x <= W; x += step){
|
||||||
|
var h = 0;
|
||||||
|
h += Math.sin(x * 0.003 + seed) * height * 0.5;
|
||||||
|
h += Math.sin(x * 0.007 + seed * 2) * height * 0.3;
|
||||||
|
h += Math.sin(x * 0.015 + seed * 3) * height * 0.15;
|
||||||
|
ctx.lineTo(x, yBase - Math.abs(h));
|
||||||
|
}
|
||||||
|
ctx.lineTo(W, H);
|
||||||
|
ctx.lineTo(0, H);
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.fillStyle = color;
|
||||||
|
ctx.fill();
|
||||||
|
// subtle outline
|
||||||
|
ctx.strokeStyle = lineColor;
|
||||||
|
ctx.lineWidth = 1;
|
||||||
|
ctx.stroke();
|
||||||
|
// snow patches on peaks
|
||||||
|
if(snowPatches > 0){
|
||||||
|
ctx.globalAlpha = snowPatches;
|
||||||
|
ctx.fillStyle = lineColor;
|
||||||
|
for(var x = 0; x <= W; x += step){
|
||||||
|
var h = 0;
|
||||||
|
h += Math.sin(x * 0.003 + seed) * height * 0.5;
|
||||||
|
h += Math.sin(x * 0.007 + seed * 2) * height * 0.3;
|
||||||
|
h += Math.sin(x * 0.015 + seed * 3) * height * 0.15;
|
||||||
|
var peakY = yBase - Math.abs(h);
|
||||||
|
if(Math.abs(h) > height * 0.6){
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(x, peakY + 2, 2 + Math.random(), 0, Math.PI * 2);
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.globalAlpha = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawMountains(c){
|
||||||
|
// far layer
|
||||||
|
drawMountainLayer(H * 0.65, H * 0.18, c.mtn1, c.mtnLine, c.mtnSnow, 1.2);
|
||||||
|
// mid layer
|
||||||
|
drawMountainLayer(H * 0.72, H * 0.14, c.mtn2, c.mtnLine, 0, 3.7);
|
||||||
|
// near layer
|
||||||
|
drawMountainLayer(H * 0.82, H * 0.10, c.mtn3, c.mtnLine, 0, 7.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var startTime = performance.now();
|
||||||
|
function render(){
|
||||||
|
var t = (performance.now() - startTime) / 1000;
|
||||||
|
var c = getColors();
|
||||||
|
ctx.clearRect(0, 0, W, H);
|
||||||
|
drawSky(c);
|
||||||
|
drawStars(c, t);
|
||||||
|
drawShootingStars(c, performance.now());
|
||||||
|
drawMountains(c);
|
||||||
|
requestAnimationFrame(render);
|
||||||
|
}
|
||||||
|
|
||||||
|
resize();
|
||||||
|
window.addEventListener('resize', resize);
|
||||||
|
render();
|
||||||
|
})();
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="bgGrad" x1="0" y1="0" x2="1" y2="1">
|
||||||
|
<stop offset="0%" stop-color="#2c2818"/>
|
||||||
|
<stop offset="100%" stop-color="#1a1710"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="snowGrad" x1="0" y1="0" x2="0" y2="1">
|
||||||
|
<stop offset="0%" stop-color="#e8c9a0"/>
|
||||||
|
<stop offset="100%" stop-color="#a08850"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<!-- Circle background -->
|
||||||
|
<circle cx="100" cy="100" r="96" fill="url(#bgGrad)"/>
|
||||||
|
<circle cx="100" cy="100" r="96" fill="none" stroke="#c8a87a" stroke-opacity="0.3" stroke-width="1.5"/>
|
||||||
|
|
||||||
|
<!-- Central hexagon -->
|
||||||
|
<polygon points="100,84 113.86,92 113.86,108 100,116 86.14,108 86.14,92"
|
||||||
|
fill="none" stroke="url(#snowGrad)" stroke-width="2.5" stroke-linejoin="round"/>
|
||||||
|
|
||||||
|
<!-- Y template: pointing upward from top vertex, then rotated 60° × 6 -->
|
||||||
|
<!-- Each Y: stem from vertex outward → diamond on axis → two branch arms -->
|
||||||
|
<g stroke="url(#snowGrad)" stroke-width="3" stroke-linecap="round" fill="url(#snowGrad)">
|
||||||
|
|
||||||
|
<!-- Y at 0° (top) -->
|
||||||
|
<g transform="rotate(0,100,100)">
|
||||||
|
<line x1="100" y1="84" x2="100" y2="38"/>
|
||||||
|
<!-- Diamond embedded on stem axis -->
|
||||||
|
<polygon points="100,54 106,60 100,66 94,60" stroke="none"/>
|
||||||
|
<!-- Y branch arms -->
|
||||||
|
<line x1="100" y1="48" x2="82" y2="32"/>
|
||||||
|
<line x1="100" y1="48" x2="118" y2="32"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Y at 60° -->
|
||||||
|
<g transform="rotate(60,100,100)">
|
||||||
|
<line x1="100" y1="84" x2="100" y2="38"/>
|
||||||
|
<polygon points="100,54 106,60 100,66 94,60" stroke="none"/>
|
||||||
|
<line x1="100" y1="48" x2="82" y2="32"/>
|
||||||
|
<line x1="100" y1="48" x2="118" y2="32"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Y at 120° -->
|
||||||
|
<g transform="rotate(120,100,100)">
|
||||||
|
<line x1="100" y1="84" x2="100" y2="38"/>
|
||||||
|
<polygon points="100,54 106,60 100,66 94,60" stroke="none"/>
|
||||||
|
<line x1="100" y1="48" x2="82" y2="32"/>
|
||||||
|
<line x1="100" y1="48" x2="118" y2="32"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Y at 180° -->
|
||||||
|
<g transform="rotate(180,100,100)">
|
||||||
|
<line x1="100" y1="84" x2="100" y2="38"/>
|
||||||
|
<polygon points="100,54 106,60 100,66 94,60" stroke="none"/>
|
||||||
|
<line x1="100" y1="48" x2="82" y2="32"/>
|
||||||
|
<line x1="100" y1="48" x2="118" y2="32"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Y at 240° -->
|
||||||
|
<g transform="rotate(240,100,100)">
|
||||||
|
<line x1="100" y1="84" x2="100" y2="38"/>
|
||||||
|
<polygon points="100,54 106,60 100,66 94,60" stroke="none"/>
|
||||||
|
<line x1="100" y1="48" x2="82" y2="32"/>
|
||||||
|
<line x1="100" y1="48" x2="118" y2="32"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Y at 300° -->
|
||||||
|
<g transform="rotate(300,100,100)">
|
||||||
|
<line x1="100" y1="84" x2="100" y2="38"/>
|
||||||
|
<polygon points="100,54 106,60 100,66 94,60" stroke="none"/>
|
||||||
|
<line x1="100" y1="48" x2="82" y2="32"/>
|
||||||
|
<line x1="100" y1="48" x2="118" y2="32"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Center dot -->
|
||||||
|
<circle cx="100" cy="100" r="3.5" fill="url(#snowGrad)" fill-opacity="0.5"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.9 KiB |
Reference in New Issue
Block a user