Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d7505e5b0c | ||
|
|
a2de47355c | ||
|
|
1668c84436 | ||
|
|
a664c423fa | ||
|
|
9523db458c | ||
|
|
bd46afc3d6 | ||
|
|
e6ba5eb3fb | ||
|
|
cf92e08278 | ||
|
|
8d19e63ceb |
11
.claude/launch.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": "0.0.1",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "local",
|
||||
"runtimeExecutable": "npx",
|
||||
"runtimeArgs": ["http-server", ".", "-p", "3000", "-c-1"],
|
||||
"port": 3000
|
||||
}
|
||||
]
|
||||
}
|
||||
23
.claude/settings.local.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"mcp__Claude_Preview__preview_start",
|
||||
"WebFetch(domain:cdnjs.cloudflare.com)",
|
||||
"Bash(curl -L -o \"D:\\\\UserData\\\\Desktop\\\\my_proj\\\\www.iletter.top\\\\static\\\\js\\\\three.min.js\" \"https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js\")",
|
||||
"Bash(curl -L -o sun.jpg \"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b4/The_Sun_by_the_Atmospheric_Imaging_Assembly_of_NASA%27s_Solar_Dynamics_Observatory_-_20100819.jpg/1200px-The_Sun_by_the_Atmospheric_Imaging_Assembly_of_NASA%27s_Solar_Dynamics_Observatory_-_20100819.jpg\")",
|
||||
"Bash(curl -L -o earth.jpg \"https://upload.wikimedia.org/wikipedia/commons/thumb/c/cb/The_Blue_Marble_%28remastered%29.jpg/1200px-The_Blue_Marble_%28remastered%29.jpg\")",
|
||||
"Bash(curl -L -o mars.jpg \"https://upload.wikimedia.org/wikipedia/commons/thumb/0/0c/Mars_-_August_30_2021_-_Flipped.jpg/1200px-Mars_-_August_30_2021_-_Flipped.jpg\")",
|
||||
"Bash(curl -L -o saturn.jpg \"https://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/Saturn_during_Equinox.jpg/1200px-Saturn_during_Equinox.jpg\")",
|
||||
"Bash(curl -L -o jupiter.jpg \"https://upload.wikimedia.org/wikipedia/commons/thumb/c/c1/Jupiter_New_Horizons.jpg/1200px-Jupiter_New_Horizons.jpg\")",
|
||||
"Bash(curl -sL \"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b4/The_Sun_by_the_Atmospheric_Imaging_Assembly_of_NASA%27s_Solar_Dynamics_Observatory_-_20100819.jpg/600px-The_Sun_by_the_Atmospheric_Imaging_Assembly_of_NASA%27s_Solar_Dynamics_Observatory_-_20100819.jpg\" -o sun.jpg)",
|
||||
"Bash(curl -sL \"https://images.unsplash.com/photo-1506318137071-a8e063b4bec0?w=300\" -o sun.jpg)",
|
||||
"Bash(curl -sL \"https://images.unsplash.com/photo-1614730321146-b6fa6a46bcb4?w=300\" -o earth.jpg)",
|
||||
"Bash(curl -sL \"https://images.unsplash.com/photo-1614728894747-a83421e2b9c9?w=300\" -o mars.jpg)",
|
||||
"Bash(curl -sL \"https://images.unsplash.com/photo-1614732414444-096e5f1122d5?w=300\" -o saturn.jpg)",
|
||||
"Bash(curl -sL \"https://images.unsplash.com/photo-1614313913007-2b4ae8ce32d6?w=300\" -o jupiter.jpg)",
|
||||
"Bash(curl -sL \"https://images.unsplash.com/photo-1446776811953-b23d57bd21aa?w=2048&q=80\" -o moon.jpg)",
|
||||
"Bash(curl -sL \"https://svs.gsfc.nasa.gov/vis/a000000/a004700/a004720/lroc_color_poles_4096.jpg\" -o moon.jpg)",
|
||||
"Bash(curl -sL \"https://upload.wikimedia.org/wikipedia/commons/thumb/d/db/Moonmap_from_clementine_data.png/1280px-Moonmap_from_clementine_data.png\" -o moon.png)"
|
||||
]
|
||||
}
|
||||
}
|
||||
67
README.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# 白荼个人主页 (BaiTu Homepage)
|
||||
|
||||
这是一个简约风格的个人主页项目,采用纯 HTML/CSS/JavaScript 构建,旨在展示个人信息、开发作品、常用工具以及生活随笔。
|
||||
|
||||
## 项目特点
|
||||
|
||||
- **信纸风格**:独特的信纸视觉设计,营造“见字如面”的沉浸式阅读体验。
|
||||
- **极简主义**:采用纯 HTML/CSS/JavaScript 构建,无繁重框架,加载迅速。
|
||||
- **多语言支持**:内置中英文切换功能,满足不同访问者的需求。
|
||||
- **动态内容**:
|
||||
- **闲言碎语**:通过 Memos API 实时同步生活点滴。
|
||||
- **历史足迹**:基于 ECharts 的交互式地图,记录走过的城市。
|
||||
- **我的网站/工具/游戏**:动态加载并展示个人作品集和常用资源。
|
||||
- **交互体验**:
|
||||
- 全局搜索功能(支持 Google, Baidu, DuckDuckGo, Yandex)。
|
||||
- 留言板与博客文章预览弹窗。
|
||||
- “旅途剪影”相册模块,支持瀑布流展示与图片轮播。
|
||||
- **性能优化**:使用 Nginx 缓存静态资源,集成 Umami 进行轻量级数据统计。
|
||||
|
||||
## 快速开始
|
||||
|
||||
1. **克隆仓库**
|
||||
```bash
|
||||
git clone https://github.com/dellevin/iletter-homepage.git
|
||||
cd iletter-homepage
|
||||
```
|
||||
|
||||
2. **本地运行**
|
||||
由于项目包含一些动态数据加载(如 Memos 接口),建议在本地服务器环境下运行。你可以使用 Python 快速启动一个简易服务器:
|
||||
```bash
|
||||
python -m http.server 8080
|
||||
```
|
||||
然后在浏览器中访问 `http://localhost:8080`。
|
||||
|
||||
## 目录结构
|
||||
|
||||
```text
|
||||
.
|
||||
├── static/
|
||||
│ ├── css/ # 样式文件
|
||||
│ ├── js/ # JavaScript 逻辑(含多语言配置)
|
||||
│ ├── img/ # 图片资源(含相册、图标等)
|
||||
│ └── font/ # 字体文件
|
||||
├── scripts/ # 自动化脚本(如照片索引生成)
|
||||
├── index.html # 主页面入口
|
||||
└── README.md # 项目说明
|
||||
```
|
||||
|
||||
## 技术栈
|
||||
|
||||
- **前端核心**:HTML5, CSS3, Vanilla JavaScript
|
||||
- **图表库**:ECharts (用于地图足迹可视化)
|
||||
- **网络请求**:Axios
|
||||
- **后端接口**:Memos API (闲言碎语), 自建评论系统
|
||||
- **统计与防护**:Umami, 堡塔云 WAF
|
||||
|
||||
## 人生相册自动化
|
||||
|
||||
项目包含 `scripts/generate-photos-json.py` 脚本,用于自动扫描 `static/img/photos/` 目录并生成 `photos.json` 索引文件,方便前端快速加载最新照片。
|
||||
|
||||
## 贡献与反馈
|
||||
|
||||
如果你对项目有任何建议或发现了 Bug,欢迎在 [GitHub Issues](https://github.com/dellevin/iletter-homepage/issues) 中提出。
|
||||
|
||||
## 许可证
|
||||
|
||||
本项目仅供学习交流使用。
|
||||
21
index.html
@@ -28,6 +28,8 @@
|
||||
<!-- <script defer src="https://umami.iletter.top/anyjs" data-website-id="ae6cd64c-5900-49c9-9c22-95cedc24a508"></script> -->
|
||||
<!-- ECharts 库 -->
|
||||
<script src="./static/js/echarts/echarts.min.js"></script>
|
||||
<!-- Three.js 用于星空预览 -->
|
||||
<script src="./static/js/three.min.js"></script>
|
||||
<!-- 多语言 -->
|
||||
<script src="./static/js/language/zh.js"></script>
|
||||
<script src="./static/js/language/en.js"></script>
|
||||
@@ -37,6 +39,7 @@
|
||||
@import url("./static/css/memos.css");
|
||||
@import url("./static/css/game_dialog.css");
|
||||
@import url("./static/css/guestbook.css");
|
||||
@import url("./static/css/galaxy.css");
|
||||
</style>
|
||||
<title data-i18n="page_title">白荼 - BAITU</title>
|
||||
</head>
|
||||
@@ -171,10 +174,23 @@
|
||||
<div class="full-modal-content">
|
||||
<div class="guestbook-header">
|
||||
<h2 data-i18n="photo_album_title">旅途剪影</h2>
|
||||
<button id="photo-album-close" class="guestbook-close" title="关闭">×</button>
|
||||
<div class="header-controls">
|
||||
<div class="mode-switch-container">
|
||||
<button id="mode-switch" class="mode-switch-btn" title="切换模式">
|
||||
<span class="mode-label active" data-mode="galaxy">星空模式</span>
|
||||
<span class="mode-label" data-mode="waterfall">瀑布模式</span>
|
||||
</button>
|
||||
</div>
|
||||
<button id="photo-album-close" class="guestbook-close" title="关闭">×</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="guestbook-body photo-album-body">
|
||||
<!-- 照片网格将在这里动态加载 -->
|
||||
<!-- 照片网格将在这里动态加载(瀑布模式) -->
|
||||
</div>
|
||||
<!-- 星空模式画布 -->
|
||||
<div id="galaxy-canvas-wrapper" class="galaxy-canvas-wrapper">
|
||||
<canvas id="galaxy-canvas"></canvas>
|
||||
<div class="galaxy-tip">滚轮缩放 | 拖拽旋转 | 点击星星查看照片</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -508,6 +524,7 @@
|
||||
<script src="./static/js/guestbook.js"></script>
|
||||
<script src="./static/js/blog_posts.js"></script>
|
||||
<script src="./static/js/photo_album.js"></script>
|
||||
<script src="./static/js/galaxy.js"></script>
|
||||
<script src="./static/js/tabchange.js"></script>
|
||||
</body>
|
||||
|
||||
|
||||
531
static/css/galaxy.css
Normal file
@@ -0,0 +1,531 @@
|
||||
/* ==================== 星空预览样式 ==================== */
|
||||
|
||||
/* 星空模式切换按钮(在弹窗header中) - 透明玻璃效果 + 黑色字体 */
|
||||
.galaxy-toggle-btn {
|
||||
display: none; /* 隐藏旧按钮 */
|
||||
}
|
||||
|
||||
/* 模式切换容器 */
|
||||
.mode-switch-container {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
/* 模式切换按钮 */
|
||||
.mode-switch-btn {
|
||||
display: flex;
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
border: 1px solid rgba(0, 0, 0, 0.15);
|
||||
border-radius: 6px;
|
||||
padding: 2px;
|
||||
cursor: pointer;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.mode-label {
|
||||
padding: 6px 12px;
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
border-radius: 4px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.mode-label.active {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.mode-label:hover:not(.active) {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* 瀑布模式容器 */
|
||||
.waterfall-wrapper {
|
||||
display: none;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 20px;
|
||||
background: linear-gradient(180deg, #f5f5f5 0%, #fff 100%);
|
||||
}
|
||||
|
||||
.waterfall-wrapper.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.waterfall-container {
|
||||
column-count: 3;
|
||||
column-gap: 16px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* 星空模式header样式 */
|
||||
.galaxy-mode-header {
|
||||
background: rgba(10, 10, 46, 0.95) !important;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1) !important;
|
||||
}
|
||||
|
||||
.galaxy-mode-header h2 {
|
||||
color: #fff !important;
|
||||
text-shadow: 0 0 10px rgba(255, 215, 0, 0.5), 0 1px 2px rgba(0, 0, 0, 0.5) !important;
|
||||
}
|
||||
|
||||
.galaxy-mode-header .guestbook-close {
|
||||
background: rgba(255, 255, 255, 0.1) !important;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2) !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.galaxy-mode-header .guestbook-close:hover {
|
||||
background: rgba(255, 0, 0, 0.5) !important;
|
||||
border-color: rgba(255, 0, 0, 0.6) !important;
|
||||
}
|
||||
|
||||
.galaxy-mode-header .mode-switch-btn {
|
||||
background: rgba(255, 255, 255, 0.1) !important;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2) !important;
|
||||
}
|
||||
|
||||
.galaxy-mode-header .mode-label {
|
||||
color: rgba(255, 255, 255, 0.7) !important;
|
||||
}
|
||||
|
||||
.galaxy-mode-header .mode-label.active {
|
||||
background: rgba(255, 255, 255, 0.2) !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.waterfall-item {
|
||||
break-inside: avoid;
|
||||
margin-bottom: 16px;
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
|
||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.waterfall-item:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.waterfall-item img {
|
||||
width: 100%;
|
||||
display: block;
|
||||
border-radius: 12px 12px 0 0;
|
||||
}
|
||||
|
||||
.waterfall-item-info {
|
||||
padding: 12px;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 900px) {
|
||||
.waterfall-container {
|
||||
column-count: 2;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.waterfall-container {
|
||||
column-count: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.header-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 星空画布容器(在弹窗内) */
|
||||
.galaxy-canvas-wrapper {
|
||||
display: none;
|
||||
flex: 1;
|
||||
position: relative;
|
||||
background: radial-gradient(ellipse at center, #1a1a3e 0%, #0a0a2e 50%, #050520 100%);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.galaxy-canvas-wrapper.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* 星空背景动画 - 繁杂无序 */
|
||||
.galaxy-canvas-wrapper::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-image: url('../img/planets/bg.jpg');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.galaxy-canvas-wrapper canvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.galaxy-tip {
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
padding: 8px 16px;
|
||||
border-radius: 20px;
|
||||
font-size: 12px;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.galaxy-canvas-wrapper.active .galaxy-tip {
|
||||
opacity: 1;
|
||||
animation: fadeInOut 3s ease-in-out forwards;
|
||||
}
|
||||
|
||||
@keyframes fadeInOut {
|
||||
0%, 100% { opacity: 0; }
|
||||
20%, 80% { opacity: 1; }
|
||||
}
|
||||
|
||||
/* 星空模式独立按钮(旧版本,保留备用) */
|
||||
.galaxy-mode-btn {
|
||||
background: transparent;
|
||||
border: none;
|
||||
padding: 8px 12px;
|
||||
cursor: pointer;
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
transition: all 0.3s ease;
|
||||
border-radius: 8px;
|
||||
position: relative;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.galaxy-mode-btn:hover {
|
||||
background: rgba(255, 215, 0, 0.1);
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.galaxy-mode-btn svg {
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.galaxy-mode-btn:hover svg {
|
||||
transform: rotate(15deg);
|
||||
}
|
||||
|
||||
/* 星空预览容器 */
|
||||
.galaxy-container {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, #0a0a2e 0%, #16162e 50%, #0d0d3d 100%);
|
||||
z-index: 10000;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.galaxy-container.active {
|
||||
display: flex;
|
||||
animation: galaxyFadeIn 0.5s ease;
|
||||
}
|
||||
|
||||
@keyframes galaxyFadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 星空头部 */
|
||||
.galaxy-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 16px 24px;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
backdrop-filter: blur(10px);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
z-index: 10001;
|
||||
}
|
||||
|
||||
.galaxy-header h2 {
|
||||
color: #FFD700;
|
||||
font-size: 20px;
|
||||
margin: 0;
|
||||
text-shadow: 0 0 10px rgba(255, 215, 0, 0.5);
|
||||
}
|
||||
|
||||
.galaxy-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.galaxy-tip {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.galaxy-close-btn {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
color: #fff;
|
||||
font-size: 24px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
cursor: pointer;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.galaxy-close-btn:hover {
|
||||
background: rgba(255, 0, 0, 0.5);
|
||||
border-color: rgba(255, 0, 0, 0.6);
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
/* 星空画布 */
|
||||
#galaxy-canvas {
|
||||
flex: 1;
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
#galaxy-canvas:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
/* 星星点击提示 */
|
||||
.star-tooltip {
|
||||
position: fixed;
|
||||
background: rgba(0, 0, 0, 0.88);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
border-radius: 10px;
|
||||
padding: 14px 18px;
|
||||
pointer-events: none;
|
||||
z-index: 10002;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s ease, transform 0.2s ease;
|
||||
max-width: 320px;
|
||||
backdrop-filter: blur(12px);
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.star-tooltip.visible {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.star-tooltip img {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
object-fit: cover;
|
||||
border-radius: 8px;
|
||||
border: 2px solid rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.star-tooltip p {
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
margin: 10px 0 0;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
/* 星星放大弹窗 */
|
||||
.star-lightbox {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.92);
|
||||
z-index: 10003;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.star-lightbox.active {
|
||||
display: flex;
|
||||
animation: lightboxFadeIn 0.25s ease;
|
||||
}
|
||||
|
||||
@keyframes lightboxFadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.star-lightbox-container {
|
||||
position: relative;
|
||||
max-width: 90vw;
|
||||
max-height: 85vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.star-lightbox img {
|
||||
max-width: 90vw;
|
||||
max-height: 80vh;
|
||||
object-fit: contain;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.1);
|
||||
animation: imageZoomIn 0.25s ease;
|
||||
}
|
||||
|
||||
@keyframes imageZoomIn {
|
||||
from {
|
||||
transform: scale(0.9);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.star-lightbox-close {
|
||||
position: absolute;
|
||||
top: -50px;
|
||||
right: -10px;
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
color: #fff;
|
||||
font-size: 24px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
cursor: pointer;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.3s ease;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.star-lightbox-close:hover {
|
||||
background: rgba(255, 255, 255, 0.25);
|
||||
transform: rotate(90deg);
|
||||
border-color: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
.star-lightbox-info {
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
font-size: 14px;
|
||||
margin-top: 16px;
|
||||
padding: 8px 16px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 20px;
|
||||
backdrop-filter: blur(10px);
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.star-lightbox-nav {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
color: #fff;
|
||||
font-size: 24px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
cursor: pointer;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.3s ease;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.star-lightbox-nav:hover {
|
||||
background: rgba(255, 255, 255, 0.25);
|
||||
border-color: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
.star-lightbox-nav.prev {
|
||||
left: -70px;
|
||||
}
|
||||
|
||||
.star-lightbox-nav.next {
|
||||
right: -70px;
|
||||
}
|
||||
|
||||
.star-lightbox-counter {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
font-size: 12px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
/* 加载动画 */
|
||||
.galaxy-loading {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
color: #FFD700;
|
||||
font-size: 18px;
|
||||
text-shadow: 0 0 20px rgba(255, 215, 0, 0.5);
|
||||
animation: pulse 1.5s infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% {
|
||||
opacity: 0.6;
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.galaxy-header {
|
||||
padding: 12px 16px;
|
||||
}
|
||||
|
||||
.galaxy-header h2 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.galaxy-tip {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.star-lightbox img {
|
||||
max-width: 95%;
|
||||
}
|
||||
}
|
||||
@@ -744,6 +744,7 @@
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
padding: 15px 20px;
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
|
||||
.guestbook-item {
|
||||
|
||||
|
Before Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 490 KiB |
|
Before Width: | Height: | Size: 248 KiB |
|
Before Width: | Height: | Size: 722 KiB |
|
Before Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 304 KiB |
|
Before Width: | Height: | Size: 442 KiB |
|
Before Width: | Height: | Size: 473 KiB |
|
Before Width: | Height: | Size: 345 KiB |
|
Before Width: | Height: | Size: 352 KiB |
|
Before Width: | Height: | Size: 156 KiB |
|
Before Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 41 KiB |
@@ -23,20 +23,7 @@
|
||||
"2799e89f4632184d151941741b59257f.jpg",
|
||||
"4c5a2a39e6ae9e01bf2ea9860ae8e41f.jpg",
|
||||
"3e0ad66c001c9894c26eac4b98601c73.jpg",
|
||||
"20955b34b4cbc661f3ec7ff2eda0b815.jpg",
|
||||
"1 (7).jpg",
|
||||
"1 (11).jpg",
|
||||
"1 (9).jpg",
|
||||
"1 (6).jpg",
|
||||
"1 (5).jpg",
|
||||
"1 (4).jpg",
|
||||
"1 (3).jpg",
|
||||
"1 (2).jpg",
|
||||
"1 (1).jpg",
|
||||
"1 (8).jpg",
|
||||
"1 (13).jpg",
|
||||
"1 (10).jpg",
|
||||
"1 (12).jpg"
|
||||
"20955b34b4cbc661f3ec7ff2eda0b815.jpg"
|
||||
],
|
||||
"total": 37,
|
||||
"lastUpdated": "2026-05-18 02:36:56"
|
||||
|
||||
BIN
static/img/planets/bg.jpg
Normal file
|
After Width: | Height: | Size: 409 KiB |
BIN
static/img/planets/earth.jpg
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
static/img/planets/moon.jpg
Normal file
|
After Width: | Height: | Size: 320 KiB |
@@ -40,8 +40,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 处理滚动事件
|
||||
// 处理滚动事件(仅针对预览面板)
|
||||
function handleScroll(e) {
|
||||
// 如果滚动的是全屏弹窗,则不触发自动加载
|
||||
if (e.target.closest('#blog-posts-full-modal')) return;
|
||||
|
||||
const { scrollTop, scrollHeight, clientHeight } = e.target;
|
||||
// 距离底部 50px 时触发加载
|
||||
if (scrollHeight - scrollTop - clientHeight < 50) {
|
||||
@@ -140,6 +143,7 @@
|
||||
}
|
||||
|
||||
fullHtml = containerHtml;
|
||||
// 弹窗界面保留“点击加载更多”按钮
|
||||
if (hasMore) {
|
||||
fullHtml += `<button class="load-more-btn" onclick="window.loadMoreBlogPosts()">点击加载更多</button>`;
|
||||
} else {
|
||||
@@ -188,18 +192,29 @@
|
||||
toRemove.remove();
|
||||
}
|
||||
|
||||
// 在当前容器后添加新的加载更多按钮或提示
|
||||
if (hasMore) {
|
||||
const btn = document.createElement('button');
|
||||
btn.className = 'load-more-btn';
|
||||
btn.textContent = '点击加载更多';
|
||||
btn.onclick = window.loadMoreBlogPosts;
|
||||
container.after(btn);
|
||||
// 区分预览面板和全屏弹窗:预览面板不显示按钮,全屏弹窗显示按钮
|
||||
const isPreview = container.closest('#blog-posts-preview');
|
||||
if (!isPreview) {
|
||||
if (hasMore) {
|
||||
const btn = document.createElement('button');
|
||||
btn.className = 'load-more-btn';
|
||||
btn.textContent = '点击加载更多';
|
||||
btn.onclick = window.loadMoreBlogPosts;
|
||||
container.after(btn);
|
||||
} else {
|
||||
const tip = document.createElement('div');
|
||||
tip.className = 'load-complete';
|
||||
tip.textContent = '已显示全部';
|
||||
container.after(tip);
|
||||
}
|
||||
} else {
|
||||
const tip = document.createElement('div');
|
||||
tip.className = 'load-complete';
|
||||
tip.textContent = '已显示全部';
|
||||
container.after(tip);
|
||||
// 预览面板仅显示完成提示
|
||||
if (!hasMore) {
|
||||
const tip = document.createElement('div');
|
||||
tip.className = 'load-complete';
|
||||
tip.textContent = '已显示全部';
|
||||
container.after(tip);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
1039
static/js/galaxy.js
Normal file
@@ -13,14 +13,15 @@ const translationsEN = {
|
||||
greeting: "",
|
||||
my_name: "BaiTu",
|
||||
about_me_p1:
|
||||
"My name is <strong>BaiTu</strong>, from Hengshui, Hebei, a native northerner. I graduated from an obscure second-tier university with a major in Information Management and Information Systems. I self-studied development technologies like Java, Vue, Linux, MySQL, Python, and some software reverse engineering techniques. I also have basic skills in PS, PR, and AE. I have experience with systems, networking, PLCs, microcontrollers, server maintenance, and managing public accounts and websites. In short, I know a little bit about many things. Others might think I'm an expert, but actually, I'm just a rookie. However, I won't give up and will strive to become an expert. As Liu Lian from NARAKA said, \"The most important skill in the world is perseverance.\"",
|
||||
"My name is <strong>BaiTu</strong>, from Hengshui, Hebei, a native northerner. I graduated from a second-tier university with a major in Information Management and Information Systems. I self-taught development languages like Java, Vue ecosystem, Python, as well as operations and database technologies like Linux, MySQL, Redis, and Nginx. I also dabble in software reverse engineering, PS, PR, AE production, and other fancy stuff. I've built systems, crimped network cables, worked with PLCs, played with microcontrollers, repaired servers (physically 🤭), operated public accounts, and maintained and managed websites. You could say I know a bit of everything, but just a tiny bit. Others may think I'm a pro, but I'm actually just a noob. Still, I won't give up and will keep striving to become a pro. As Liu Lian from NARAKA said, \"The most important skill in the world is perseverance.\"",
|
||||
about_me_p2:
|
||||
'My hobbies usually involve playing games, reading books, watching anime, and I prefer staying indoors. I hate repetitive and simple work, so I often write small tools to make life easier because laziness drives my productivity. I frequently lurk on various forums and blogs, shouting "666" or "Amazing" under tech bloggers. My own blog updates sporadically, mainly recording daily life notes and technical challenges encountered.',
|
||||
'My hobbies are playing games, reading books, and watching anime — a complete homebody who hates going out. I hate repetitive and simple work, so I often write small tools to slack off. After all, laziness is my primary productivity. I frequently lurk on various forums and blogs, shouting "666" or "Amazing" under tech bloggers. My own blog updates sporadically, mainly recording daily life notes and technical challenges encountered.',
|
||||
about_me_p3:
|
||||
'This site follows a minimalist style, using pure HTML. Umami tracks UV/PV at the bottom. The Memos section uses the Memos API. It also employs Baota Cloud WAF protection and nginx caching for static resources. If you are interested, you can directly download the source code from <a href="https://gitea.iletter.top/dellevin/BaiTu-homepage" target="_blank">https://gitea.iletter.top/dellevin/BaiTu-homepage </a> and use it, or through F12 view website source code download.',
|
||||
'This site follows a minimalist letter-style design, using pure HTML. Umami tracks UV/PV at the bottom. The Memos section uses the Memos API. The guestbook is self-built, and blog posts use the Typecho Restful plugin (customized by me). It also employs Baota Cloud WAF protection and nginx caching for static resources. If you are interested, you can directly download the source code from <a href="https://github.com/dellevin/iletter-homepage" target="_blank">https://github.com/dellevin/iletter-homepage </a> and use it, or download by viewing the website source code through F12.',
|
||||
about_me_p4:
|
||||
"As a 99er programmer, I am glad to still have great passion for technology after starting work! If you share the same interest in technology, I would love to meet you! Let's progress and grow together!",
|
||||
// 联系方式
|
||||
|
||||
// 联系方式
|
||||
contact_intro: "Feel free to reach out via the following methods:",
|
||||
email_label: "Email:",
|
||||
wechat_label: "WeChat:",
|
||||
|
||||
@@ -13,14 +13,13 @@ const translationsZH = {
|
||||
greeting: "见字如面,展信舒颜。",
|
||||
my_name: "白荼",
|
||||
about_me_p1:
|
||||
"我叫<strong>白荼</strong>,河北衡水人,土生土长的北方汉子,毕业于一所不知名的二本院校。信息管理与信息系统专业。自学java、vue、linux、mysql、python等开发技术和一些软件逆向技术,同时还略懂些PS图片、PR视频、AE特效制作。做过系统,剪过网线,搞过plc,耍过单片机,维护修理过服务器,运营过公众号和网站等等。可谓是会,但只会一点点。别人都觉得我是个大佬,其实我就是个小菜鸡。但我不会气馁,努力成为一个大佬的。正如永劫无间刘炼的一句话“天下万般之绝学,莫过于恒心。”",
|
||||
"我叫<strong>白荼</strong>,河北衡水人,土生土长的北方汉子,毕业于一所二本院校。信息管理与信息系统专业。自学的java、vue全家桶、python等开发语言,还有linux、mysql、redis、nginx等运维和数据库的技术,同时还略懂些软件逆向,PS、PR、AE制作等其他花里胡哨的东西。做系统,剪网线,搞过PLC,耍过单片机,修过服务器(物理层面🤭),运营过公众号,维护管理过网站等等。可谓是会,但只会一点点。别人都觉得我是个大佬,其实我就是个小菜鸡。但我不会气馁,努力成为一个大佬的。正如永劫无间刘炼的一句话“天下万般之绝学,莫过于恒心。”",
|
||||
about_me_p2:
|
||||
'平时的爱好也就是玩玩游戏,看看书,刷刷动漫,不爱出门,肥宅一个。讨厌重复简单的工作,会想办法偷懒写写自己的顺手的小工具什么的,毕竟懒惰是我的生产力。我也经常混迹于各大网络论坛博客并在各个技术博主下面直呼"大佬666"、"大佬牛牛牛"。自己的博客也在断断续续中更新。主要是记录生活随笔和碰到的技术难题。',
|
||||
'平时的爱好就是玩玩游戏,看看书,刷刷动漫,一个彻头彻尾的不爱出门的肥宅。讨厌重复简单的工作,会想办法偷懒写一下小工具什么的,毕竟懒惰是我的第一生产力。我也经常混迹于各大网络论坛博客并在各个技术博主下面直呼"大佬666"、"大佬牛牛牛"。自己的博客也在断断续续中更新。主要是记录生活随笔和碰到的技术难题。',
|
||||
about_me_p3:
|
||||
'本站秉承简约风格,采用纯HTML,Umami做网站底部的uv/pv ,闲言碎语模块使用memos接口。同时使用堡塔云WAF防护,nginx缓存加速网站静态资源。如果您有兴趣,可以直接下载本站的 <a href="https://gitea.iletter.top/dellevin/BaiTu-homepage" target="_blank">https://gitea.iletter.top/dellevin/BaiTu-homepage </a> 并使用,或者通过F12查看网站源代码下载。',
|
||||
'本站秉承书信形式的简约风格,采用纯HTML,Umami做网站底部的uv/pv ,闲言碎语模块使用memos接口,留言板自己写的,博客文章使用的是typecho的Restful插件(自己魔改了一下)。同时使用堡塔云WAF防护,nginx缓存加速网站静态资源。如果您有兴趣,可以直接下载本站的 <a href="https://github.com/dellevin/iletter-homepage" target="_blank">https://github.com/dellevin/iletter-homepage </a> 并使用,或者通过F12查看网站源代码进行下载。',
|
||||
about_me_p4:
|
||||
"作为一个99年的码农,很庆幸我在工作之后还对技术有着极大的热情!如果你也对技术有着同样的兴趣,也很希望认识你!一同进步共同成长!",
|
||||
|
||||
// 联系方式
|
||||
contact_intro: "欢迎通过以下方式与我联系:",
|
||||
email_label: "邮箱:",
|
||||
|
||||
6
static/js/three.min.js
vendored
Normal file
@@ -168,9 +168,9 @@ const toolsData = [
|
||||
desc_en: "Who writes a diary, seriously?!",
|
||||
},
|
||||
{
|
||||
name_zh: "Ollama",
|
||||
desc_zh: "本地部署对话AI,微调模型,32b是4070遭不住",
|
||||
name_en: "Ollama",
|
||||
name_zh: "Ollama / llama.cpp",
|
||||
desc_zh: "本地部署对话AI,微调模型",
|
||||
name_en: "Ollama / llama.cpp",
|
||||
desc_en:
|
||||
"Locally deployed conversational AI, fine-tuning models. 32b is too much for a 4070.",
|
||||
},
|
||||
@@ -207,6 +207,39 @@ const toolsData = [
|
||||
name_en: "QtScrcpy",
|
||||
desc_en: "LAN phone control tool, remote adb is awesome.",
|
||||
},
|
||||
{
|
||||
name_zh: "Snipaste",
|
||||
desc_zh: "很厉害的强大且好用的截屏工具",
|
||||
name_en: "Snipaste",
|
||||
desc_en: "Very powerful and useful screenshot tool.",
|
||||
},
|
||||
{
|
||||
name_zh: "Redis Desktop Manager",
|
||||
desc_zh: "超级好用的Redis数据库管理工具",
|
||||
name_en: "Redis Desktop Manager",
|
||||
desc_en: "Redis database management tool.",
|
||||
},
|
||||
{
|
||||
name_zh: "Snipaste",
|
||||
desc_zh: "很厉害的强大且好用的截屏工具",
|
||||
name_en: "Snipaste",
|
||||
desc_en: "Very powerful and useful screenshot tool.",
|
||||
},{
|
||||
name_zh: "Everything",
|
||||
desc_zh: "windows搜索文件利器,毫秒搜索,快速定位",
|
||||
name_en: "Everything",
|
||||
desc_en: "windows search file利器,millisecond search, quickly locate files",
|
||||
},{
|
||||
name_zh: "RaiDrive",
|
||||
desc_zh: "好用爱用的网盘挂载",
|
||||
name_en: "RaiDrive",
|
||||
desc_en: "Good and loved netdisk mount",
|
||||
},{
|
||||
name_zh: "Ultimate Vocal Remover",
|
||||
desc_zh: "音频转换提取,十分好用",
|
||||
name_en: "Ultimate Vocal Remover",
|
||||
desc_en: "Audio conversion and extraction, very useful.",
|
||||
}
|
||||
];
|
||||
|
||||
// ========== 渲染工具列表的函数 ==========
|
||||
|
||||