From 26423f7d3b724e5a4d2a03a6d260357cc65193ff Mon Sep 17 00:00:00 2001 From: hehh Date: Thu, 20 Nov 2025 17:14:31 +0800 Subject: [PATCH] =?UTF-8?q?feat(css):=20=E5=AE=9E=E7=8E=B0=E7=8E=B0?= =?UTF-8?q?=E4=BB=A3=E5=8C=96=E6=AF=9B=E7=8E=BB=E7=92=83=E6=95=88=E6=9E=9C?= =?UTF-8?q?=E5=92=8C=E5=8A=A8=E6=80=81=E4=B8=BB=E9=A2=98=E7=B3=BB=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 引入CSS变量系统,定义完整的色彩和样式变量 - 应用radial-gradient和linear-gradient创建动态背景效果 - 实现backdrop-filter毛玻璃效果,增强视觉层次感 - 添加悬停交互反馈和过渡动画 - 统一文字颜色和背景透明度处理 - 优化移动端显示效果和响应式设计 - 增强阴影效果和边框样式一致性 - 添加orbit轨道动画和相位控制 - 改进渐变色应用和文本填充效果 - 优化技术栈标签云的视觉表现 --- about.html | 9 +- css/about.css | 551 ++++++++++++++++++++++++++++++----------- data/articles.json | 44 ++++ data/github_repos.json | 32 +++ data/github_user.json | 19 ++ js/about.js | 351 +++++++++++++------------- js/main.js | 2 +- 7 files changed, 694 insertions(+), 314 deletions(-) create mode 100644 data/articles.json create mode 100644 data/github_repos.json create mode 100644 data/github_user.json diff --git a/about.html b/about.html index 073f5f4..3fa92fd 100644 --- a/about.html +++ b/about.html @@ -116,6 +116,8 @@ Python JavaScript Spring Boot + WebFlux + Reactor TypeScript Spring Cloud Go @@ -144,7 +146,10 @@ Transformers Scikit-learn Ollama + Dify + Spring AI ClickHouse + Postgresql
@@ -196,6 +201,8 @@

开源项目

用代码改变世界

+
+
@@ -291,7 +298,7 @@ ×

微信公众号

- + 微信公众号二维码

扫码关注获取最新技术文章

diff --git a/css/about.css b/css/about.css index b3baeb6..b019ead 100644 --- a/css/about.css +++ b/css/about.css @@ -5,13 +5,34 @@ box-sizing: border-box; } +:root { + --ink: #0D0F12; + --slate: #121417; + --pearl: #F2F3F5; + --glass-blur: 20px; + --glass-alpha: 0.12; + --glass-alpha-strong: 0.16; + --glass-border: rgba(255, 255, 255, 0.16); + --text-strong: #ffffff; + --text-soft: rgba(255, 255, 255, 0.9); + --grad-a: #101216; + --grad-b: #171a1f; + --accent-a: #3AA0FF; + --accent-b: #4ECDC4; + --accent-coral: #FF6B6B; + --accent-lavender: #7B7AE6; +} + body { - font-family: 'Inter', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + font-family: 'Inter', 'SF Pro Text', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; line-height: 1.6; - color: #2c3e50; - background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 50%, #dee2e6 100%); + color: var(--text-soft); + background: radial-gradient(1200px 600px at 20% 20%, rgba(60, 60, 80, 0.35), transparent 60%), + radial-gradient(800px 800px at 80% 0%, rgba(90, 70, 120, 0.18), transparent 70%), + linear-gradient(135deg, var(--grad-a) 0%, var(--grad-b) 100%); min-height: 100vh; overflow-x: hidden; + background-attachment: fixed; } /* 动态背景 */ @@ -23,10 +44,10 @@ body::before { width: 100%; height: 100%; background: - radial-gradient(circle at 20% 80%, rgba(102, 126, 234, 0.08) 0%, transparent 50%), - radial-gradient(circle at 80% 20%, rgba(118, 75, 162, 0.08) 0%, transparent 50%), - radial-gradient(circle at 40% 40%, rgba(52, 152, 219, 0.06) 0%, transparent 50%), - radial-gradient(circle at 60% 60%, rgba(155, 89, 182, 0.06) 0%, transparent 50%); + radial-gradient(circle at 20% 80%, rgba(255, 255, 255, 0.1) 0%, transparent 50%), + radial-gradient(circle at 80% 20%, rgba(255, 255, 255, 0.1) 0%, transparent 50%), + radial-gradient(circle at 40% 40%, rgba(255, 255, 255, 0.05) 0%, transparent 50%), + radial-gradient(circle at 60% 60%, rgba(255, 255, 255, 0.05) 0%, transparent 50%); z-index: -1; animation: backgroundShift 25s ease-in-out infinite; } @@ -73,18 +94,21 @@ a:hover { .intro-quote { margin: 1.5rem 0; padding: 1.5rem; - background: rgba(255, 255, 255, 0.9); + background: rgba(255, 255, 255, var(--glass-alpha)); border-radius: 15px; border-left: 4px solid #667eea; - box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1); - backdrop-filter: blur(10px); + box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); + backdrop-filter: blur(var(--glass-blur)); + -webkit-backdrop-filter: blur(var(--glass-blur)); position: relative; transition: all 0.3s ease; + border: 1px solid var(--glass-border); } .intro-quote:hover { transform: translateY(-2px); box-shadow: 0 12px 35px rgba(0, 0, 0, 0.15); + background: rgba(255, 255, 255, 0.15); } .intro-quote::before { @@ -101,7 +125,7 @@ a:hover { .intro-quote p { margin: 0; font-style: italic; - color: #2c3e50; + color: #fff; line-height: 1.7; font-size: 1.1rem; } @@ -188,18 +212,19 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info top: 0; left: 0; right: 0; - background: rgba(255, 255, 255, 0.98); - backdrop-filter: blur(20px); + background: rgba(255, 255, 255, var(--glass-alpha)); + backdrop-filter: blur(var(--glass-blur)); + -webkit-backdrop-filter: blur(var(--glass-blur)); z-index: 1000; padding: 1rem 0; transition: all 0.3s ease; - border-bottom: 1px solid rgba(102, 126, 234, 0.1); - box-shadow: 0 2px 20px rgba(0, 0, 0, 0.08); + border-bottom: 1px solid var(--glass-border); + box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); } .navbar.scrolled { - background: rgba(255, 255, 255, 0.98); - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15); + background: rgba(255, 255, 255, 0.2); + box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); } .nav-container { @@ -214,9 +239,9 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info .nav-logo { font-size: 1.8rem; font-weight: 800; - color: #2c3e50; + color: #fff; text-decoration: none; - background: linear-gradient(45deg, #667eea, #764ba2, #9b59b6); + background: linear-gradient(45deg, #fff, #e0e0e0); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; @@ -231,16 +256,17 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info display: flex; list-style: none; gap: 2.5rem; - background: rgba(255, 255, 255, 0.1); + background: rgba(255, 255, 255, var(--glass-alpha)); padding: 0.8rem 1.5rem; border-radius: 50px; - backdrop-filter: blur(10px); - border: 1px solid rgba(255, 255, 255, 0.2); + backdrop-filter: blur(var(--glass-blur)); + -webkit-backdrop-filter: blur(var(--glass-blur)); + border: 1px solid var(--glass-border); } .nav-links a { text-decoration: none; - color: #2c3e50; + color: #fff; font-weight: 600; transition: all 0.3s ease; position: relative; @@ -263,7 +289,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info .nav-links a:hover, .nav-links a.active { - color: #ff6b6b; + color: var(--accent-coral); background: rgba(255, 255, 255, 0.2); transform: translateY(-2px); } @@ -289,7 +315,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info /* 英雄区域 */ .hero-section { padding: 4rem 2rem; - background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 25%, #dee2e6 50%, #ced4da 75%, #adb5bd 100%); + background: rgba(255, 255, 255, 0.06); background-size: 400% 400%; animation: heroGradientShift 15s ease infinite; min-height: 80vh; @@ -299,6 +325,10 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info overflow: hidden; border-radius: 0 0 50px 50px; margin-bottom: 2rem; + backdrop-filter: blur(var(--glass-blur)); + -webkit-backdrop-filter: blur(var(--glass-blur)); + border: 1px solid var(--glass-border); + box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); } .hero-section::before { @@ -308,9 +338,9 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info left: 0; right: 0; bottom: 0; - background: radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.3) 0%, transparent 50%), - radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.3) 0%, transparent 50%), - radial-gradient(circle at 40% 40%, rgba(120, 219, 255, 0.2) 0%, transparent 50%); + background: radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.1) 0%, transparent 50%), + radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.1) 0%, transparent 50%), + radial-gradient(circle at 40% 40%, rgba(120, 219, 255, 0.1) 0%, transparent 50%); pointer-events: none; } @@ -338,6 +368,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info transition: all 0.3s ease; animation: gentleFloat 4s ease-in-out infinite; filter: brightness(1.1) contrast(1.1); + backdrop-filter: blur(5px); } .infj-image:hover { @@ -372,15 +403,16 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info } .profile-card { - background: rgba(255, 255, 255, 0.95); + background: rgba(255, 255, 255, var(--glass-alpha)); border-radius: 20px; padding: 2rem; - box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08); + box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); text-align: center; position: relative; overflow: hidden; - border: 2px solid rgba(102, 126, 234, 0.2); - backdrop-filter: blur(10px); + border: 1px solid var(--glass-border); + backdrop-filter: blur(var(--glass-blur)); + -webkit-backdrop-filter: blur(var(--glass-blur)); } .profile-card::before { @@ -443,12 +475,12 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info margin: 0 0 0.5rem 0; font-size: 2rem; font-weight: 700; - color: #333; + color: #fff; } .profile-info p { margin: 0 0 1rem 0; - color: #666; + color: rgba(255, 255, 255, 0.9); font-size: 1.1rem; } @@ -457,7 +489,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info justify-content: center; align-items: center; gap: 0.5rem; - color: #888; + color: rgba(255, 255, 255, 0.8); font-size: 0.9rem; } @@ -468,9 +500,9 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info .intro-content h2 { font-size: 2.5rem; font-weight: 800; - color: #333; + color: #fff; margin-bottom: 1.5rem; - background: linear-gradient(45deg, #667eea, #764ba2); + background: linear-gradient(45deg, #fff, #e0e0e0); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; @@ -479,7 +511,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info .intro-text p { font-size: 1.1rem; line-height: 1.8; - color: #555; + color: rgba(255, 255, 255, 0.9); margin-bottom: 1.5rem; } @@ -488,11 +520,15 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info } .mbti-card { - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + background: linear-gradient(135deg, rgba(102, 126, 234, 0.2) 0%, rgba(118, 75, 162, 0.2) 100%); border-radius: 15px; padding: 1.5rem; color: #fff; margin-bottom: 2rem; + backdrop-filter: blur(var(--glass-blur)); + -webkit-backdrop-filter: blur(var(--glass-blur)); + border: 1px solid var(--glass-border); + box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); } .mbti-header { @@ -539,17 +575,17 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info font-size: 4rem; font-weight: 800; margin-bottom: 1rem; - background: linear-gradient(45deg, #ff6b6b, #4ecdc4, #45b7d1, #f9ca24); + background: linear-gradient(45deg, #fff, #e0e0e0); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; animation: titleGlow 3s ease-in-out infinite; - text-shadow: 0 0 30px rgba(255, 107, 107, 0.3); + text-shadow: 0 0 30px rgba(255, 255, 255, 0.3); } .hero-subtitle { font-size: 1.4rem; - color: #333; + color: rgba(255, 255, 255, 0.9); margin-bottom: 1.5rem; font-weight: 500; opacity: 0.9; @@ -561,13 +597,13 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info .hero-description p { font-size: 1.2rem; - color: #555; + color: rgba(255, 255, 255, 0.8); font-weight: 400; margin: 0; padding: 1rem 2rem; - background: rgba(255, 255, 255, 0.2); + background: rgba(255, 255, 255, 0.1); border-radius: 25px; - border: 1px solid rgba(255, 255, 255, 0.3); + border: 1px solid rgba(255, 255, 255, 0.18); display: inline-block; } @@ -598,7 +634,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info font-weight: 800; color: #2c3e50; margin-bottom: 1rem; - background: linear-gradient(45deg, #667eea, #764ba2, #9b59b6); + background: linear-gradient(45deg, #fff, #e0e0e0); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; @@ -606,13 +642,13 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info } @keyframes titleGlow { - from { filter: drop-shadow(0 0 20px rgba(102, 126, 234, 0.5)); } - to { filter: drop-shadow(0 0 30px rgba(118, 75, 162, 0.8)); } + from { filter: drop-shadow(0 0 20px rgba(255, 255, 255, 0.5)); } + to { filter: drop-shadow(0 0 30px rgba(255, 255, 255, 0.8)); } } .hero-subtitle { font-size: 1.5rem; - color: #2c3e50; + color: rgba(255, 255, 255, 0.9); margin-bottom: 2rem; font-weight: 300; opacity: 0.8; @@ -627,7 +663,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info } .mbti-tag { - background: linear-gradient(45deg, #ff6b6b, #4ecdc4); + background: linear-gradient(45deg, rgba(255, 107, 107, 0.3), rgba(78, 205, 196, 0.3)); color: #fff; padding: 0.8rem 1.5rem; border-radius: 30px; @@ -635,11 +671,11 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info font-weight: 700; box-shadow: 0 8px 25px rgba(255, 107, 107, 0.4); animation: pulse 2s infinite; - border: 2px solid rgba(255, 255, 255, 0.3); + border: 1px solid rgba(255, 255, 255, 0.18); } .badge-desc { - color: #2c3e50; + color: rgba(255, 255, 255, 0.9); font-size: 0.9rem; font-style: italic; font-weight: 500; @@ -659,7 +695,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info .hero-stats .stat-number { font-size: 2.5rem; font-weight: 800; - background: linear-gradient(45deg, #ff6b6b, #4ecdc4); + background: linear-gradient(45deg, #fff, #e0e0e0); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; @@ -668,7 +704,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info } .hero-stats .stat-label { - color: #2c3e50; + color: rgba(255, 255, 255, 0.9); font-size: 0.9rem; text-transform: uppercase; letter-spacing: 1px; @@ -685,7 +721,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info .section-title { font-size: 3rem; font-weight: 800; - background: linear-gradient(45deg, #667eea, #764ba2, #9b59b6); + background: linear-gradient(45deg, #fff, #e0e0e0); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; @@ -702,14 +738,14 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info transform: translateX(-50%); width: 80px; height: 4px; - background: linear-gradient(45deg, #ff6b6b, #4ecdc4); + background: linear-gradient(45deg, var(--accent-coral), var(--accent-b)); border-radius: 2px; - box-shadow: 0 2px 10px rgba(255, 107, 107, 0.3); + box-shadow: 0 2px 10px rgba(255, 107, 107, 0.25); } .section-subtitle { font-size: 1.2rem; - color: #2c3e50; + color: rgba(255, 255, 255, 0.9); font-weight: 500; opacity: 0.8; } @@ -717,12 +753,13 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info /* 技术栈云图 - INFJ风格设计 */ .tech-cloud-section { padding: 8rem 2rem; - background: rgba(255, 255, 255, 0.9); + background: rgba(255, 255, 255, 0.05); backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); border-radius: 50px; margin: 2rem; - border: 2px solid rgba(102, 126, 234, 0.1); - box-shadow: 0 15px 35px rgba(0, 0, 0, 0.08); + border: 1px solid rgba(255, 255, 255, 0.18); + box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); position: relative; overflow: hidden; } @@ -734,9 +771,9 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info left: 0; right: 0; bottom: 0; - background: radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.3) 0%, transparent 50%), - radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.3) 0%, transparent 50%), - radial-gradient(circle at 40% 40%, rgba(120, 219, 255, 0.2) 0%, transparent 50%); + background: radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.1) 0%, transparent 50%), + radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.1) 0%, transparent 50%), + radial-gradient(circle at 40% 40%, rgba(120, 219, 255, 0.1) 0%, transparent 50%); pointer-events: none; } @@ -791,10 +828,11 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info padding: 0.8rem 1.5rem; margin: 0.5rem; border-radius: 25px; - background: rgba(255, 255, 255, 0.95); + background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); - border: 2px solid rgba(102, 126, 234, 0.2); - color: #2c3e50; + -webkit-backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.18); + color: #fff; font-size: 0.95rem; font-weight: 600; cursor: pointer; @@ -802,7 +840,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info animation: cloudFloat 8s ease-in-out infinite; position: relative; overflow: hidden; - box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08); + box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); } /* 标签浮动动画 */ @@ -839,7 +877,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info .cloud-tag:hover { transform: translateY(-8px) scale(1.1) rotate(5deg); - background: rgba(255, 255, 255, 1); + background: rgba(255, 255, 255, 0.2); box-shadow: 0 15px 35px rgba(0, 0, 0, 0.15), 0 0 25px var(--tag-color, #667eea); border-color: var(--tag-color, #667eea); color: var(--tag-color, #667eea); @@ -890,7 +928,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info } .cloud-tag[data-category="core"]:hover { - background: linear-gradient(135deg, rgba(231, 76, 60, 0.1), rgba(231, 76, 60, 0.05)); + background: linear-gradient(135deg, rgba(231, 76, 60, 0.2), rgba(231, 76, 60, 0.1)); } .cloud-tag[data-category="backend"] { @@ -899,7 +937,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info } .cloud-tag[data-category="backend"]:hover { - background: linear-gradient(135deg, rgba(39, 174, 96, 0.1), rgba(39, 174, 96, 0.05)); + background: linear-gradient(135deg, rgba(39, 174, 96, 0.2), rgba(39, 174, 96, 0.1)); } .cloud-tag[data-category="data"] { @@ -908,7 +946,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info } .cloud-tag[data-category="data"]:hover { - background: linear-gradient(135deg, rgba(52, 152, 219, 0.1), rgba(52, 152, 219, 0.05)); + background: linear-gradient(135deg, rgba(52, 152, 219, 0.2), rgba(52, 152, 219, 0.1)); } .cloud-tag[data-category="ops"] { @@ -917,7 +955,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info } .cloud-tag[data-category="ops"]:hover { - background: linear-gradient(135deg, rgba(243, 156, 18, 0.1), rgba(243, 156, 18, 0.05)); + background: linear-gradient(135deg, rgba(243, 156, 18, 0.2), rgba(243, 156, 18, 0.1)); } .cloud-tag[data-category="ai"] { @@ -926,7 +964,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info } .cloud-tag[data-category="ai"]:hover { - background: linear-gradient(135deg, rgba(155, 89, 182, 0.1), rgba(155, 89, 182, 0.05)); + background: linear-gradient(135deg, rgba(155, 89, 182, 0.2), rgba(155, 89, 182, 0.1)); } /* 分类特定动画延迟 */ @@ -941,17 +979,16 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info .cloud-tag[data-category="ops"]:nth-child(odd) { animation-delay: 3.5s; } .cloud-tag[data-category="ops"]:nth-child(even) { animation-delay: 4.5s; } - - /* 个性时间线 */ .personality-timeline-section { padding: 8rem 2rem; - background: rgba(255, 255, 255, 0.9); + background: rgba(255, 255, 255, 0.05); backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); border-radius: 50px; margin: 2rem; - border: 2px solid rgba(102, 126, 234, 0.1); - box-shadow: 0 15px 35px rgba(0, 0, 0, 0.08); + border: 1px solid rgba(255, 255, 255, 0.18); + box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); } .personality-timeline { @@ -1006,25 +1043,33 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info .timeline-content { flex: 1; - background: rgba(255, 255, 255, 0.9); - backdrop-filter: blur(10px); + background: rgba(255, 255, 255, var(--glass-alpha)); + backdrop-filter: blur(var(--glass-blur)); + -webkit-backdrop-filter: blur(var(--glass-blur)); padding: 2rem; border-radius: 25px; margin: 0 2rem; - border: 2px solid rgba(255, 255, 255, 0.5); - transition: all 0.3s ease; - box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); + border: 1px solid var(--glass-border); + transition: all 0.3s ease, opacity 0.6s ease, transform 0.6s ease; + box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); + opacity: 0; + transform: translateY(30px); +} + +.timeline-item.is-entered .timeline-content { + opacity: 1; + transform: none; } .timeline-content:hover { - background: rgba(255, 255, 255, 1); + background: rgba(255, 255, 255, 0.2); transform: translateY(-8px) scale(1.02); box-shadow: 0 25px 50px rgba(0, 0, 0, 0.15); border-color: #ff6b6b; } .timeline-content h3 { - background: linear-gradient(45deg, #667eea, #764ba2); + background: linear-gradient(45deg, #fff, #e0e0e0); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; @@ -1034,7 +1079,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info } .timeline-content p { - color: #2c3e50; + color: rgba(255, 255, 255, 0.9); line-height: 1.6; font-weight: 500; } @@ -1042,12 +1087,13 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info /* GitHub项目展示 */ .github-showcase-section { padding: 8rem 2rem; - background: rgba(255, 255, 255, 0.9); + background: rgba(255, 255, 255, 0.05); backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); border-radius: 50px; margin: 2rem; - border: 2px solid rgba(102, 126, 234, 0.1); - box-shadow: 0 15px 35px rgba(0, 0, 0, 0.08); + border: 1px solid rgba(255, 255, 255, 0.18); + box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); } .projects-masonry { @@ -1060,15 +1106,16 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info } .project-card { - background: rgba(255, 255, 255, 0.9); - backdrop-filter: blur(10px); + background: rgba(255, 255, 255, var(--glass-alpha)); + backdrop-filter: blur(var(--glass-blur)); + -webkit-backdrop-filter: blur(var(--glass-blur)); border-radius: 25px; padding: 2rem; - border: 2px solid rgba(255, 255, 255, 0.5); + border: 1px solid var(--glass-border); transition: all 0.3s ease; position: relative; overflow: hidden; - box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); + box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); } .project-card::before { @@ -1090,11 +1137,11 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info transform: translateY(-15px) scale(1.02); box-shadow: 0 30px 60px rgba(0, 0, 0, 0.15); border-color: #ff6b6b; - background: rgba(255, 255, 255, 1); + background: rgba(255, 255, 255, 0.2); } .project-title { - background: linear-gradient(45deg, #667eea, #764ba2); + background: linear-gradient(45deg, #fff, #e0e0e0); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; @@ -1104,7 +1151,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info } .project-description { - color: #555; + color: rgba(255, 255, 255, 0.9); margin-bottom: 1.5rem; line-height: 1.6; font-weight: 500; @@ -1120,14 +1167,14 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info display: flex; align-items: center; gap: 0.3rem; - color: #666; + color: rgba(255, 255, 255, 0.8); font-size: 0.9rem; font-weight: 600; } .project-link { display: inline-block; - background: linear-gradient(45deg, #ff6b6b, #4ecdc4); + background: linear-gradient(45deg, var(--accent-coral), var(--accent-b)); color: #fff; padding: 0.8rem 1.8rem; border-radius: 30px; @@ -1135,6 +1182,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info font-weight: 600; transition: all 0.3s ease; box-shadow: 0 5px 15px rgba(255, 107, 107, 0.3); + border: 1px solid rgba(255, 255, 255, 0.18); } .project-link:hover { @@ -1145,16 +1193,17 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info /* 博客瀑布流 */ .blog-waterfall-section { padding: 8rem 2rem; - background: rgba(255, 255, 255, 0.9); + background: rgba(255, 255, 255, 0.05); backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); border-radius: 50px; margin: 2rem; - border: 2px solid rgba(102, 126, 234, 0.1); - box-shadow: 0 15px 35px rgba(0, 0, 0, 0.08); + border: 1px solid rgba(255, 255, 255, 0.18); + box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); } .view-all-link { - background: linear-gradient(45deg, #ff6b6b, #4ecdc4); + background: linear-gradient(45deg, #fff, #e0e0e0); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; @@ -1186,26 +1235,27 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info } .article-card { - background: rgba(255, 255, 255, 0.9); - backdrop-filter: blur(10px); + background: rgba(255, 255, 255, var(--glass-alpha)); + backdrop-filter: blur(var(--glass-blur)); + -webkit-backdrop-filter: blur(var(--glass-blur)); border-radius: 20px; padding: 1.8rem; - border: 2px solid rgba(255, 255, 255, 0.5); + border: 1px solid var(--glass-border); transition: all 0.3s ease; text-decoration: none; display: block; - box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1); + box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); } .article-card:hover { transform: translateY(-8px) scale(1.02); box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15); - background: rgba(255, 255, 255, 1); + background: rgba(255, 255, 255, 0.2); border-color: #ff6b6b; } .article-title { - background: linear-gradient(45deg, #667eea, #764ba2); + background: linear-gradient(45deg, #fff, #e0e0e0); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; @@ -1216,7 +1266,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info } .article-excerpt { - color: #555; + color: rgba(255, 255, 255, 0.9); font-size: 0.95rem; line-height: 1.6; margin-bottom: 1rem; @@ -1228,7 +1278,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info justify-content: space-between; align-items: center; font-size: 0.85rem; - color: #666; + color: rgba(255, 255, 255, 0.8); font-weight: 600; } @@ -1248,12 +1298,13 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info position: relative; min-height: 600px; overflow: hidden; - background: rgba(255, 255, 255, 0.9); - backdrop-filter: blur(10px); + background: rgba(255, 255, 255, 0.06); + backdrop-filter: blur(var(--glass-blur)); + -webkit-backdrop-filter: blur(var(--glass-blur)); border-radius: 50px; margin: 2rem; - border: 2px solid rgba(102, 126, 234, 0.1); - box-shadow: 0 15px 35px rgba(0, 0, 0, 0.08); + border: 1px solid var(--glass-border); + box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); } .contact-floating-section::before { @@ -1264,9 +1315,9 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info right: 0; bottom: 0; background: - radial-gradient(circle at 20% 30%, rgba(102, 126, 234, 0.08) 0%, transparent 50%), - radial-gradient(circle at 80% 70%, rgba(118, 75, 162, 0.08) 0%, transparent 50%), - radial-gradient(circle at 40% 80%, rgba(155, 89, 182, 0.06) 0%, transparent 50%); + radial-gradient(circle at 20% 30%, rgba(102, 126, 234, 0.1) 0%, transparent 50%), + radial-gradient(circle at 80% 70%, rgba(118, 75, 162, 0.1) 0%, transparent 50%), + radial-gradient(circle at 40% 80%, rgba(155, 89, 182, 0.1) 0%, transparent 50%); pointer-events: none; z-index: 1; border-radius: 50px; @@ -1281,7 +1332,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info .contact-title h2 { font-size: 2.8rem; - background: linear-gradient(45deg, #667eea, #764ba2, #9b59b6); + background: linear-gradient(45deg, #fff, #e0e0e0); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; @@ -1292,7 +1343,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info } .contact-title p { - color: #2c3e50; + color: rgba(255, 255, 255, 0.9); font-size: 1.2rem; margin-bottom: 4rem; font-weight: 500; @@ -1310,15 +1361,16 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info } .social-card { - background: rgba(255, 255, 255, 0.9); - backdrop-filter: blur(15px); - border: 2px solid rgba(102, 126, 234, 0.2); + background: rgba(255, 255, 255, var(--glass-alpha)); + backdrop-filter: blur(var(--glass-blur)); + -webkit-backdrop-filter: blur(var(--glass-blur)); + border: 1px solid var(--glass-border); border-radius: 25px; padding: 1rem; text-decoration: none; - color: #2c3e50; + color: #fff; transition: all 0.3s ease; - box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1); + box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); display: flex; flex-direction: column; align-items: center; @@ -1334,6 +1386,11 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info transform-origin: center; } +@keyframes orbit { + 0% { transform: translate(-50%, -50%) rotate(var(--phase)) translateX(var(--radius)) rotate(calc(-1 * var(--phase))); } + 100% { transform: translate(-50%, -50%) rotate(calc(var(--phase) + 360deg)) translateX(var(--radius)) rotate(calc(-1 * var(--phase) - 360deg)); } +} + .social-card::before { content: ''; position: absolute; @@ -1350,7 +1407,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info transform: scale(1.1); box-shadow: 0 15px 35px rgba(0, 0, 0, 0.15), 0 0 25px var(--social-color, #667eea); border-color: var(--social-color, #667eea); - background: rgba(255, 255, 255, 1); + background: rgba(255, 255, 255, 0.2); animation-play-state: paused; } @@ -1376,13 +1433,13 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info margin: 0; font-size: 0.9rem; font-weight: 600; - color: #2c3e50; + color: #fff; } .social-info p { margin: 0; font-size: 0.7rem; - color: #666; + color: rgba(255, 255, 255, 0.8); } /* 轨道围绕动画 - 每个卡片不同的轨道路径,优化避免碰撞 */ @@ -1465,8 +1522,6 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info } } - - .social-card.github { --social-color: #333; --social-color-end: #555; @@ -1506,11 +1561,14 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); - backdrop-filter: blur(5px); + backdrop-filter: blur(calc(var(--glass-blur) * 0.5)); + -webkit-backdrop-filter: blur(calc(var(--glass-blur) * 0.5)); } .modal-content { - background-color: #fff; + background-color: rgba(255, 255, 255, var(--glass-alpha)); + backdrop-filter: blur(var(--glass-blur)); + -webkit-backdrop-filter: blur(var(--glass-blur)); margin: 10% auto; padding: 2rem; border-radius: 15px; @@ -1519,6 +1577,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info text-align: center; position: relative; box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2); + border: 1px solid var(--glass-border); } .close { @@ -1533,7 +1592,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info } .close:hover { - color: #333; + color: #fff; } .qr-code { @@ -1545,17 +1604,19 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info height: 200px; border-radius: 10px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); + border: 1px solid rgba(255, 255, 255, 0.18); } /* 评论系统 */ .comments-section { padding: 8rem 2rem; - background: rgba(255, 255, 255, 0.9); + background: rgba(255, 255, 255, 0.05); backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); border-radius: 50px; margin: 2rem; - border: 2px solid rgba(102, 126, 234, 0.1); - box-shadow: 0 15px 35px rgba(0, 0, 0, 0.08); + border: 1px solid rgba(255, 255, 255, 0.18); + box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); } .comments-container { @@ -1573,20 +1634,21 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info } #artalk-container { - background: rgba(255, 255, 255, 0.9); - backdrop-filter: blur(10px); + background: rgba(255, 255, 255, var(--glass-alpha)); + backdrop-filter: blur(var(--glass-blur)); + -webkit-backdrop-filter: blur(var(--glass-blur)); border-radius: 25px; padding: 2.5rem; - border: 2px solid rgba(255, 255, 255, 0.5); + border: 1px solid var(--glass-border); text-align: left; - box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1); + box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); } /* 加载动画 */ .loading-placeholder { text-align: center; padding: 4rem 2rem; - color: #333; + color: rgba(255, 255, 255, 0.9); font-weight: 600; } @@ -1617,7 +1679,7 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); } - .hero-content { + .hero-container { grid-template-columns: 1fr; text-align: center; gap: 2rem; @@ -1687,6 +1749,73 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info .articles-waterfall { grid-template-columns: 1fr; } + + .social-grid { + width: auto; + height: auto; + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 1rem; + } + + .social-card { + position: static; + width: 100%; + height: auto; + padding: 0.8rem; + transform: none !important; + animation: none !important; + } + + .social-icon { + width: 30px; + height: 30px; + font-size: 1rem; + } + + .social-info h3 { + font-size: 0.7rem; + } + + .social-info p { + font-size: 0.5rem; + } + + .social-card:nth-child(1) { + animation: none; + } + + .social-card:nth-child(2) { + animation: none; + } + + .social-card:nth-child(3) { + animation: none; + } + + .social-card:nth-child(4) { + animation: none; + } + + .social-card:nth-child(5) { + animation: none; + } + + .social-card:nth-child(6) { + animation: none; + } + + @keyframes orbit1 { } + + @keyframes orbit2 { } + + @keyframes orbit3 { } + + @keyframes orbit4 { } + + @keyframes orbit5 { } + + @keyframes orbit6 { } } @media (max-width: 480px) { @@ -1743,15 +1872,101 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info .footer-section { text-align: center; } + + .nav-links { + padding: 0.5rem 1rem; + } + + .nav-links a { + padding: 0.3rem 0.6rem; + font-size: 0.9rem; + } + + .hero-section { + padding: 2rem 1rem; + } + + .profile-card { + padding: 1rem; + } + + .avatar-image { + width: 80px; + height: 80px; + } + + .hero-title { + font-size: 2rem; + } + + .hero-subtitle { + font-size: 1rem; + } + + .mbti-card { + padding: 1rem; + } + + .mbti-tag { + padding: 0.4rem 0.8rem; + font-size: 0.9rem; + } + + .section-title { + font-size: 1.8rem; + } + + .section-subtitle { + font-size: 1rem; + } + + .tech-cloud-section, + .personality-timeline-section, + .github-showcase-section, + .blog-waterfall-section, + .contact-floating-section, + .comments-section { + padding: 4rem 1rem; + margin: 1rem; + border-radius: 25px; + } + + .cloud-tag { + padding: 0.5rem 1rem; + margin: 0.3rem; + font-size: 0.8rem; + } + + .timeline-content { + padding: 1rem; + } + + .project-card, + .article-card { + padding: 1rem; + } + + .modal-content { + padding: 1rem; + margin: 20% auto; + } + + .qr-code img { + width: 150px; + height: 150px; + } } /* 页脚样式 - 首页风格 */ .footer { - background: #2c3e50; + background: rgba(0, 0, 0, 0.2); color: rgba(255, 255, 255, 0.8); padding: 30px 0; margin-top: 80px; text-align: center; + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + border-top: 1px solid rgba(255, 255, 255, 0.18); } .footer-container { @@ -1796,4 +2011,54 @@ a:not(.nav-logo):not(.nav-links a):not(.social-link):not(.btn):not(.footer-info .tech-philosophy { text-align: center; + margin-top: 2rem; +} + +.philosophy-text { + color: rgba(255, 255, 255, 0.9); + font-style: italic; + font-size: 1.1rem; + max-width: 800px; + margin: 0 auto; + padding: 1.5rem; + background: rgba(255, 255, 255, 0.05); + border-radius: 15px; + backdrop-filter: blur(5px); + -webkit-backdrop-filter: blur(5px); + border: 1px solid rgba(255, 255, 255, 0.1); +} + +.motion-reduced * { + animation: none !important; + transition: none !important; +} + +.motion-mobile .hero-section { + animation-duration: 10s; +} + +.motion-mobile .social-card { + width: 90px; + height: 90px; +} + +.motion-mobile .hero-title { + text-shadow: none; +} + +@media (prefers-color-scheme: dark) { + :root { + --glass-alpha: 0.18; + } +} + +@media (prefers-reduced-motion: reduce) { + .hero-section, + .cloud-wrapper::before, + .social-card, + .hero-title, + .mbti-tag, + .avatar-ring { + animation: none !important; + } } \ No newline at end of file diff --git a/data/articles.json b/data/articles.json new file mode 100644 index 0000000..9220e11 --- /dev/null +++ b/data/articles.json @@ -0,0 +1,44 @@ +[ + { + "title": "向量数据库全攻略:从算法公式到选型指南,一篇吃透高维数据存储术", + "excerpt": "深入探讨向量数据库的核心算法、应用场景和选型策略,帮助开发者掌握高维数据存储的关键技术...", + "link": "https://blog.hehouhui.cn/posts/vector-database-guide", + "pubDate": "2025-01-02", + "category": "技术分享" + }, + { + "title": "CompletableFuture 从源码到实战:让异步编程像喝奶茶一样丝滑", + "excerpt": "全面解析CompletableFuture的源码实现和实战应用,让Java异步编程变得简单优雅...", + "link": "https://blog.hehouhui.cn/posts/completablefuture-guide", + "pubDate": "2025-01-02", + "category": "Java开发" + }, + { + "title": "从规范到架构:一篇读懂 Java 工程建模、分层、命名与演进之路", + "excerpt": "深入讲解Java工程的规范化建设,包括项目结构、分层架构、命名规范等最佳实践...", + "link": "https://blog.hehouhui.cn/posts/java-project-architecture", + "pubDate": "2025-01-01", + "category": "架构设计" + }, + { + "title": "Spring Boot 3.0 新特性详解与实战应用", + "excerpt": "全面介绍Spring Boot 3.0的新特性,包括原生镜像支持、可观测性增强等...", + "link": "https://blog.hehouhui.cn/posts/spring-boot-3-features", + "pubDate": "2024-12-30", + "category": "Spring框架" + }, + { + "title": "微服务架构设计模式与最佳实践", + "excerpt": "深入分析微服务架构的设计模式,包括服务拆分、数据一致性、分布式事务等核心问题...", + "link": "https://blog.hehouhui.cn/posts/microservices-patterns", + "pubDate": "2024-12-28", + "category": "微服务" + }, + { + "title": "Redis 高可用集群搭建与性能优化实战", + "excerpt": "详细介绍Redis集群的搭建过程、高可用配置以及性能调优技巧...", + "link": "https://blog.hehouhui.cn/posts/redis-cluster-optimization", + "pubDate": "2024-12-25", + "category": "数据库" + } +] \ No newline at end of file diff --git a/data/github_repos.json b/data/github_repos.json new file mode 100644 index 0000000..c18e976 --- /dev/null +++ b/data/github_repos.json @@ -0,0 +1,32 @@ +[ + { + "id": 1011713435, + "name": "yunxiao-LLM-reviewer", + "html_url": "https://github.com/listener-He/yunxiao-LLM-reviewer", + "description": "一款专为阿里云云效 Flow 平台设计的自动化代码审查工具。通过集成 Qwen、DeepSeek 等先进大模型,该工具能够实时分析 Git 合并请求(MR)中的代码变更,智能识别潜在问题并自动生成结构化评审意见。", + "stargazers_count": 9, + "forks_count": 3, + "language": "TypeScript", + "updated_at": "2025-10-10T11:06:34Z" + }, + { + "id": 1064414600, + "name": "hexo-theme-stellar", + "html_url": "https://github.com/listener-He/hexo-theme-stellar", + "description": "综合型hexo主题:博客+知识库+专栏+笔记,内置海量的标签组件和动态数据组件。", + "stargazers_count": 0, + "forks_count": 0, + "language": null, + "updated_at": "2025-09-26T02:12:18Z" + }, + { + "id": 1060085476, + "name": "Universal-IoT-Java", + "html_url": "https://github.com/listener-He/Universal-IoT-Java", + "description": "通用 IoT Java 平台(示例)", + "stargazers_count": 0, + "forks_count": 0, + "language": null, + "updated_at": "2025-10-13T02:30:28Z" + } +] \ No newline at end of file diff --git a/data/github_user.json b/data/github_user.json new file mode 100644 index 0000000..0c8ccda --- /dev/null +++ b/data/github_user.json @@ -0,0 +1,19 @@ +{ + "login": "listener-He", + "id": 39252579, + "node_id": "MDQ6VXNlcjM5MjUyNTc5", + "avatar_url": "https://avatars.githubusercontent.com/u/39252579?v=4", + "url": "https://api.github.com/users/listener-He", + "html_url": "https://github.com/listener-He", + "type": "User", + "name": "Honesty", + "blog": "https://www.hehouhui.cn", + "hireable": true, + "bio": "Honesty Shanghai Student", + "public_repos": 165, + "public_gists": 0, + "followers": 6, + "following": 12, + "created_at": "2018-05-14T02:57:55Z", + "updated_at": "2025-11-09T05:45:15Z" +} \ No newline at end of file diff --git a/js/about.js b/js/about.js index 7df2bd2..1751f2d 100644 --- a/js/about.js +++ b/js/about.js @@ -1,7 +1,7 @@ // 关于页面JavaScript功能 - 现代动态版本 $(document).ready(function() { - // 初始化所有功能 + initMotionController(); initGitHubStats(); initProjects(); initBlogArticles(); @@ -15,15 +15,21 @@ $(document).ready(function() { // 初始化随机位置 function initRandomPositions() { - // 为联系方式卡片设置随机初始位置 - $('.social-card').each(function(index) { - var randomDelay = Math.random() * 5; // 0-5秒随机延迟 - var randomRotation = Math.random() * 360; // 0-360度随机旋转 - + var cards = $('.social-card'); + var rings = [130, 180, 230]; + var golden = 137.5; + var speedBase = 16; + cards.each(function(idx) { + var ring = rings[idx % rings.length]; + var angle = (idx * golden) % 360; + var speed = speedBase + (idx % rings.length) * 4; $(this).css({ - 'animation-delay': randomDelay + 's', - 'transform': 'translate(-50%, -50%) rotate(' + randomRotation + 'deg)' + '--radius': ring + 'px', + '--phase': angle + 'deg', + '--speed': speed + 's' }); + this.style.setProperty('animation', 'orbit var(--speed) linear infinite'); + this.style.setProperty('transform', 'translate(-50%, -50%) rotate(var(--phase)) translateX(var(--radius)) rotate(calc(-1 * var(--phase)))'); }); // 为技术标签设置随机动画延迟 @@ -32,19 +38,32 @@ function initRandomPositions() { $(this).css('animation-delay', randomDelay + 's'); }); - // 为时间线项目设置随机出现延迟 $('.timeline-item').each(function(index) { var randomDelay = index * 0.2 + Math.random() * 0.5; - $(this).css({ - 'animation-delay': randomDelay + 's', - 'opacity': '0' - }).animate({opacity: 1}, 800); + $(this).css('transition-delay', randomDelay + 's'); }); } +function initMotionController() { + var isMobile = window.matchMedia('(pointer: coarse)').matches || window.innerWidth <= 768; + var reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches; + var supportsBackdrop = (window.CSS && (CSS.supports('backdrop-filter: blur(1px)') || CSS.supports('-webkit-backdrop-filter: blur(1px)'))); + + var root = document.documentElement; + root.setAttribute('data-motion', reduced ? 'reduced' : (isMobile ? 'mobile' : 'desktop')); + root.classList.toggle('motion-mobile', isMobile && !reduced); + root.classList.toggle('motion-desktop', !isMobile && !reduced); + root.classList.toggle('motion-reduced', reduced); + + if (!supportsBackdrop) { + root.style.setProperty('--glass-blur', '0px'); + root.style.setProperty('--glass-alpha', '0.18'); + } +} + // GitHub 统计信息 function initGitHubStats() { - var username = 'listener-He'; // 替换为实际的GitHub用户名 + var username = 'listener-He'; var cacheKey = 'github_stats_cache'; var cacheTimeKey = 'github_stats_cache_time'; @@ -76,19 +95,22 @@ function initGitHubStats() { localStorage.setItem(cacheTimeKey, now.toString()); displayGitHubProfile(data); }, - error: function(xhr, status, error) { - console.error('获取GitHub用户信息失败:', error); - // 使用备用数据 - var fallbackData = { - name: 'listener-He', - login: 'listener-He', - bio: '全栈开发工程师,专注于Java后端和前端技术', - avatar_url: 'https://avatars.githubusercontent.com/u/listener-He', - public_repos: 25, - followers: 48, - following: 32 - }; - displayGitHubProfile(fallbackData); + error: function() { + fetch('data/github_user.json') + .then(function(res) { return res.json(); }) + .then(function(json) { displayGitHubProfile(json); }) + .catch(function() { + var fallbackData = { + name: 'Honesty', + login: 'listener-He', + bio: '开发者', + avatar_url: 'https://avatars.githubusercontent.com/u/39252579?v=4', + public_repos: 0, + followers: 0, + following: 0 + }; + displayGitHubProfile(fallbackData); + }); } }); } @@ -118,6 +140,8 @@ function displayGitHubProfile(data) { '
' + ''; $('#github-profile').html(profileHtml); + $('#github-repos').text(data.public_repos); + $('#github-followers').text(data.followers); // 获取提交统计(使用GitHub API的限制,这里模拟数据) var commitsHtml = '
' + @@ -190,30 +214,11 @@ function initProjects() { localStorage.setItem(cacheTimeKey, now.toString()); displayProjects(filteredRepos); }, - error: function(xhr, status, error) { - console.error('获取GitHub项目失败:', error); - // 使用备用数据 - var fallbackRepos = [ - { - name: 'awesome-project', - description: '一个很棒的开源项目', - html_url: 'https://github.com/listener-He/awesome-project', - stargazers_count: 128, - forks_count: 32, - language: 'Java', - updated_at: '2025-01-01T00:00:00Z' - }, - { - name: 'web-framework', - description: '轻量级Web框架', - html_url: 'https://github.com/listener-He/web-framework', - stargazers_count: 89, - forks_count: 21, - language: 'JavaScript', - updated_at: '2024-12-28T00:00:00Z' - } - ]; - displayProjects(fallbackRepos); + error: function() { + fetch('data/github_repos.json') + .then(function(res) { return res.json(); }) + .then(function(json) { displayProjects(json); }) + .catch(function() { displayProjects([]); }); } }); } @@ -233,6 +238,8 @@ function displayProjects(repos) { (updateDate.getMonth() + 1) + '/' + updateDate.getDate(); + var starSvg = ''; + var forkSvg = ''; projectsHtml += '
' + '
' + '
' + @@ -240,8 +247,8 @@ function displayProjects(repos) { '

' + (repo.description || '暂无描述') + '

' + '
' + '
' + - ' ' + repo.stargazers_count + '' + - ' ' + repo.forks_count + '' + + '' + starSvg + ' ' + (repo.stargazers_count || 0) + '' + + '' + forkSvg + ' ' + (repo.forks_count || 0) + '' + '
' + '
' + '
' + languageTags + '
' + @@ -274,57 +281,14 @@ function initBlogArticles() { localStorage.removeItem(cacheKey); localStorage.removeItem(cacheTimeKey); - // 由于RSS跨域问题,直接使用备用数据 - var fallbackArticles = [ - { - title: "向量数据库全攻略:从算法公式到选型指南,一篇吃透高维数据存储术", - excerpt: "深入探讨向量数据库的核心算法、应用场景和选型策略,帮助开发者掌握高维数据存储的关键技术...", - link: "https://blog.hehouhui.cn/posts/vector-database-guide", - pubDate: "2025-01-02", - category: "技术分享" - }, - { - title: "CompletableFuture 从源码到实战:让异步编程像喝奶茶一样丝滑", - excerpt: "全面解析CompletableFuture的源码实现和实战应用,让Java异步编程变得简单优雅...", - link: "https://blog.hehouhui.cn/posts/completablefuture-guide", - pubDate: "2025-01-02", - category: "Java开发" - }, - { - title: "从规范到架构:一篇读懂 Java 工程建模、分层、命名与演进之路", - excerpt: "深入讲解Java工程的规范化建设,包括项目结构、分层架构、命名规范等最佳实践...", - link: "https://blog.hehouhui.cn/posts/java-project-architecture", - pubDate: "2025-01-01", - category: "架构设计" - }, - { - title: "Spring Boot 3.0 新特性详解与实战应用", - excerpt: "全面介绍Spring Boot 3.0的新特性,包括原生镜像支持、可观测性增强等...", - link: "https://blog.hehouhui.cn/posts/spring-boot-3-features", - pubDate: "2024-12-30", - category: "Spring框架" - }, - { - title: "微服务架构设计模式与最佳实践", - excerpt: "深入分析微服务架构的设计模式,包括服务拆分、数据一致性、分布式事务等核心问题...", - link: "https://blog.hehouhui.cn/posts/microservices-patterns", - pubDate: "2024-12-28", - category: "微服务" - }, - { - title: "Redis 高可用集群搭建与性能优化实战", - excerpt: "详细介绍Redis集群的搭建过程、高可用配置以及性能调优技巧...", - link: "https://blog.hehouhui.cn/posts/redis-cluster-optimization", - pubDate: "2024-12-25", - category: "数据库" - } - ]; - - // 缓存备用数据 - localStorage.setItem(cacheKey, JSON.stringify(fallbackArticles)); - localStorage.setItem(cacheTimeKey, now.toString()); - - displayBlogArticles(fallbackArticles); + fetch('data/articles.json') + .then(function(res) { return res.json(); }) + .then(function(json) { + localStorage.setItem(cacheKey, JSON.stringify(json)); + localStorage.setItem(cacheTimeKey, now.toString()); + displayBlogArticles(json); + }) + .catch(function() { displayBlogArticles([]); }); } function displayBlogArticles(articles) { @@ -345,8 +309,6 @@ function displayBlogArticles(articles) { $('#blog-container').html(articlesHtml); } - - // 数字动画效果 function animateNumber(selector, targetNumber) { var element = $(selector); @@ -367,46 +329,55 @@ function animateNumber(selector, targetNumber) { // 评论系统初始化 function initArtalkComments() { - // 初始化 Artalk 评论系统 - if (typeof Artalk !== 'undefined') { - var artalk = Artalk.init({ - el: '#artalk-container', - pageKey: window.location.pathname, - pageTitle: document.title, - server: 'https://artalk.hehouhui.cn', // 替换为实际的Artalk服务器地址 - site: 'Honesty的主页', - placeholder: '来说点什么吧...', - noComment: '暂无评论', - sendBtn: '发送', - darkMode: false, - gravatar: { - mirror: 'https://cravatar.cn/avatar/' - }, - pagination: { - pageSize: 20, - readMore: true, - autoLoad: true - }, - heightLimit: { - content: 300, - children: 400 - }, - imgUpload: false, - preview: true, - versionCheck: true - }); - - // 自定义样式 - setTimeout(() => { - var atkMain = document.querySelector('.atk-main'); - if (atkMain) { - atkMain.style.borderRadius = '15px'; - atkMain.style.overflow = 'hidden'; - } - }, 1000); + try { + var isLocal = location.hostname === 'localhost' || location.hostname === '127.0.0.1'; + if (isLocal) { + renderCommentsFallback('评论系统暂不可用'); + return; + } + if (typeof Artalk === 'undefined') { + renderCommentsFallback('评论系统加载失败'); + return; + } + var controller = new AbortController(); + var timer = setTimeout(function() { controller.abort(); }, 5000); + fetch('https://artalk.hehouhui.cn/api/v2/conf', { signal: controller.signal }) + .then(function(res) { + clearTimeout(timer); + if (!res.ok) throw new Error('conf fetch failed'); + return res.json(); + }) + .then(function() { + Artalk.init({ + el: '#artalk-container', + pageKey: window.location.pathname, + pageTitle: document.title, + server: 'https://artalk.hehouhui.cn', + site: 'Honesty的主页', + placeholder: '来说点什么吧...', + noComment: '暂无评论', + sendBtn: '发送', + darkMode: false, + gravatar: { mirror: 'https://cravatar.cn/avatar/' }, + pagination: { pageSize: 20, readMore: true, autoLoad: true }, + heightLimit: { content: 300, children: 400 }, + imgUpload: false, + preview: true, + versionCheck: true + }); + }) + .catch(function() { renderCommentsFallback('评论系统暂不可用'); }); + } catch (e) { + renderCommentsFallback('评论系统异常'); } } +function renderCommentsFallback(msg) { + var container = document.getElementById('artalk-container'); + if (!container) return; + container.innerHTML = '
' + (msg || '评论系统不可用') + '
'; +} + // 技术云图初始化 function initTechCloud() { var techItems = [ @@ -501,23 +472,44 @@ function initPageAnimations() { observer.observe(section); }); + var itemObserver = new IntersectionObserver(function(entries) { + entries.forEach(function(entry) { + if (entry.isIntersecting) { + entry.target.classList.add('is-entered'); + itemObserver.unobserve(entry.target); + } + }); + }, { threshold: 0.15, rootMargin: '0px 0px -20px 0px' }); + + document.querySelectorAll('.timeline-item').forEach(function(el) { + itemObserver.observe(el); + }); + // 数字动画 function animateNumbers() { + var root = document.documentElement; + var reduced = root.classList.contains('motion-reduced'); + var isMobile = root.classList.contains('motion-mobile'); $('.stat-number').each(function() { var $this = $(this); var target = parseInt($this.text().replace(/[^0-9]/g, '')); - var duration = 2000; - var step = target / (duration / 16); - var current = 0; - - var timer = setInterval(function() { - current += step; - if (current >= target) { - current = target; - clearInterval(timer); + if (!target || reduced || isMobile) { + if (!isNaN(target)) { + $this.text(target.toLocaleString()); } - $this.text(Math.floor(current).toLocaleString()); - }, 16); + return; + } + var start = 0; + var startTs; + var duration = 1200; + function step(ts) { + if (!startTs) startTs = ts; + var p = Math.min(1, (ts - startTs) / duration); + var val = Math.floor(start + (target - start) * p); + $this.text(val.toLocaleString()); + if (p < 1) requestAnimationFrame(step); + } + requestAnimationFrame(step); }); } @@ -552,10 +544,10 @@ var githubStyles = '