feat(about): 增强个人介绍页面功能与样式
- 添加简介文本折叠/展开功能 - 实现导航栏滚动时的视觉变化效果 - 为姓名和角色标题添加动画渐变效果 - 更新技能标签云的动画和布局 - 优化GitHub数据获取逻辑,支持分页加载更多仓库 - 移除旧的缓存配置,简化代码结构 - 调整响应式设计中的评论框内边距 - 统一文本对齐方式并增强可读性 - 修复技能展示区域的marquee动画实现 - 添加新的CSS工具类以支持动态交互效果
This commit is contained in:
@@ -94,13 +94,14 @@
|
|||||||
<!-- [2] 简介与格言 (Bio) -->
|
<!-- [2] 简介与格言 (Bio) -->
|
||||||
<div class="bento-card area-bio">
|
<div class="bento-card area-bio">
|
||||||
<div class="card-label" data-i18n="bio.label">About Me</div>
|
<div class="card-label" data-i18n="bio.label">About Me</div>
|
||||||
<p class="bio-text" data-i18n="bio.text">
|
<p class="bio-text collapsed" data-i18n="bio.text">
|
||||||
"我是一名充满热情的Java后端开发工程师,专注于AI技术的探索与应用。来自湖南,现在上海工作,享受在这座充满活力的城市中追求技术梦想。"
|
"我是一名充满热情的Java后端开发工程师,专注于AI技术的探索与应用。来自湖南,现在上海工作,享受在这座充满活力的城市中追求技术梦想。"
|
||||||
</p>
|
</p>
|
||||||
<div class="quote-box">
|
<div class="quote-box">
|
||||||
<i class="ri-double-quotes-l"></i>
|
<i class="ri-double-quotes-l"></i>
|
||||||
<p data-i18n="bio.quote">"我追求技术的深度理解而非广度堆砌,每一项技术的学习都源于解决实际问题的内在驱动。作为INFJ人格类型,我善于深度思考,注重细节,喜欢通过代码创造有意义的产品。我相信技术的力量能够改变世界,也热衷于在开源社区中分享知识与经验。 "</p>
|
<p data-i18n="bio.quote">"我追求技术的深度理解而非广度堆砌,每一项技术的学习都源于解决实际问题的内在驱动。作为INFJ人格类型,我善于深度思考,注重细节,喜欢通过代码创造有意义的产品。我相信技术的力量能够改变世界,也热衷于在开源社区中分享知识与经验。 "</p>
|
||||||
</div>
|
</div>
|
||||||
|
<button id="bio-toggle" class="link-btn" aria-label="Toggle Bio">展开/收起</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- [3] 数据统计 (Stats) -->
|
<!-- [3] 数据统计 (Stats) -->
|
||||||
|
|||||||
@@ -409,6 +409,9 @@ body {
|
|||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.animated-gradient { background-image: linear-gradient(90deg, var(--text-primary), var(--accent), var(--text-primary)); -webkit-background-clip: text; background-clip: text; color: transparent; animation: gradientShift 6s linear infinite; text-shadow: 0 0 8px rgba(108,92,231,0.2); }
|
||||||
|
@keyframes gradientShift { 0% { background-position: 0% 50%; } 100% { background-position: 200% 50%; } }
|
||||||
|
|
||||||
.location-tag {
|
.location-tag {
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
color: var(--text-tertiary);
|
color: var(--text-tertiary);
|
||||||
@@ -464,6 +467,16 @@ body {
|
|||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
text-align: justify;
|
||||||
|
}
|
||||||
|
.bio-text.collapsed {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.link-btn {
|
||||||
|
background: none; border: none; color: var(--accent); cursor: pointer; font-size: 0.85rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.quote-box {
|
.quote-box {
|
||||||
@@ -1032,6 +1045,7 @@ body {
|
|||||||
background-clip: text;
|
background-clip: text;
|
||||||
color: transparent;
|
color: transparent;
|
||||||
}
|
}
|
||||||
|
.comment-box { padding: 24px; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* =========================================
|
/* =========================================
|
||||||
@@ -1217,6 +1231,12 @@ body {
|
|||||||
black 90%,
|
black 90%,
|
||||||
transparent 100%
|
transparent 100%
|
||||||
);
|
);
|
||||||
|
animation: techMarquee 18s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes techMarquee {
|
||||||
|
0% { transform: translateX(0); }
|
||||||
|
100% { transform: translateX(-33.333%); }
|
||||||
}
|
}
|
||||||
|
|
||||||
.tech-tag-mobile {
|
.tech-tag-mobile {
|
||||||
@@ -1319,6 +1339,7 @@ body {
|
|||||||
background-clip: text;
|
background-clip: text;
|
||||||
color: transparent;
|
color: transparent;
|
||||||
}
|
}
|
||||||
|
.comment-box { padding: 16px; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* =========================================
|
/* =========================================
|
||||||
|
|||||||
55
js/about.js
55
js/about.js
@@ -141,13 +141,21 @@ class DataManager {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// Parallel Fetch
|
// Parallel Fetch
|
||||||
const [uRes, rRes] = await Promise.allSettled([
|
const uRes = await fetch(`https://api.github.com/users/${user}`);
|
||||||
fetch(`https://api.github.com/users/${user}`),
|
const userData = uRes.ok ? await uRes.json() : (window.SiteConfig?.defaults?.user);
|
||||||
fetch(`https://api.github.com/users/${user}/repos?sort=stars&per_page=100`)
|
let allRepos = [];
|
||||||
]);
|
let page = 1;
|
||||||
|
const perPage = 100;
|
||||||
const userData = uRes.status === 'fulfilled' ? await uRes.value.json() : (window.SiteConfig?.defaults?.user);
|
while (page <= 5) { // 最多抓取500条,直到满足条件或为空
|
||||||
let repoData = rRes.status === 'fulfilled' ? await rRes.value.json() : (window.SiteConfig?.defaults?.repos);
|
const rRes = await fetch(`https://api.github.com/users/${user}/repos?sort=stars&per_page=${perPage}&page=${page}`);
|
||||||
|
if (!rRes.ok) break;
|
||||||
|
const repos = await rRes.json();
|
||||||
|
if (!Array.isArray(repos) || repos.length === 0) break;
|
||||||
|
allRepos = allRepos.concat(repos);
|
||||||
|
if (allRepos.length >= 200) break; // 足量
|
||||||
|
page++;
|
||||||
|
}
|
||||||
|
let repoData = allRepos.length ? allRepos : (window.SiteConfig?.defaults?.repos);
|
||||||
|
|
||||||
// 过滤掉fork项目并按星数排序
|
// 过滤掉fork项目并按星数排序
|
||||||
if (Array.isArray(repoData)) {
|
if (Array.isArray(repoData)) {
|
||||||
@@ -319,6 +327,9 @@ class UIManager {
|
|||||||
this.initTechCloud();
|
this.initTechCloud();
|
||||||
this.initModal();
|
this.initModal();
|
||||||
this.initArtalk();
|
this.initArtalk();
|
||||||
|
this.initBioToggle();
|
||||||
|
this.initNavInteraction();
|
||||||
|
this.initProfileGradient();
|
||||||
let resizeTimer = null;
|
let resizeTimer = null;
|
||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
clearTimeout(resizeTimer);
|
clearTimeout(resizeTimer);
|
||||||
@@ -354,6 +365,33 @@ class UIManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initBioToggle() {
|
||||||
|
const el = document.querySelector('.bio-text');
|
||||||
|
const btn = document.getElementById('bio-toggle');
|
||||||
|
if(!el || !btn) return;
|
||||||
|
btn.addEventListener('click', () => {
|
||||||
|
el.classList.toggle('collapsed');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
initNavInteraction() {
|
||||||
|
const nav = document.querySelector('.glass-nav');
|
||||||
|
if(!nav) return;
|
||||||
|
const onScroll = () => {
|
||||||
|
const y = window.scrollY || document.documentElement.scrollTop;
|
||||||
|
nav.classList.toggle('nav-scrolled', y > 30);
|
||||||
|
};
|
||||||
|
onScroll();
|
||||||
|
window.addEventListener('scroll', onScroll, { passive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
initProfileGradient() {
|
||||||
|
const name = document.querySelector('.hero-name');
|
||||||
|
const role = document.querySelector('.hero-role');
|
||||||
|
if(name) name.classList.add('animated-gradient');
|
||||||
|
if(role) role.classList.add('animated-gradient');
|
||||||
|
}
|
||||||
|
|
||||||
initTechCloud() {
|
initTechCloud() {
|
||||||
const container = document.getElementById('tech-container');
|
const container = document.getElementById('tech-container');
|
||||||
if(!container) return;
|
if(!container) return;
|
||||||
@@ -388,8 +426,7 @@ class UIManager {
|
|||||||
} else {
|
} else {
|
||||||
// PC: 3D Sphere
|
// PC: 3D Sphere
|
||||||
container.classList.remove('mobile-scroll');
|
container.classList.remove('mobile-scroll');
|
||||||
const token = Date.now();
|
container.__animToken = Date.now();
|
||||||
container.__animToken = token;
|
|
||||||
const tags = [];
|
const tags = [];
|
||||||
|
|
||||||
techStack.forEach((item, index) => {
|
techStack.forEach((item, index) => {
|
||||||
|
|||||||
26
js/config.js
26
js/config.js
@@ -34,33 +34,11 @@ const SiteConfig = {
|
|||||||
|
|
||||||
// about.js 配置
|
// about.js 配置
|
||||||
github: {
|
github: {
|
||||||
username: 'listener-He',
|
username: 'listener-He'
|
||||||
cache: {
|
|
||||||
cacheKey: "gh_data_v2",
|
|
||||||
stats: {
|
|
||||||
key: 'github_stats_cache',
|
|
||||||
timeKey: 'github_stats_cache_time',
|
|
||||||
expirationDays: 3
|
|
||||||
},
|
|
||||||
projects: {
|
|
||||||
key: 'github_projects_cache',
|
|
||||||
timeKey: 'github_projects_cache_time',
|
|
||||||
expirationDays: 3
|
|
||||||
},
|
|
||||||
commits: {
|
|
||||||
key: 'github_commits_cache',
|
|
||||||
timeKey: 'github_commits_cache_time',
|
|
||||||
expirationHours: 24
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
blog: {
|
blog: {
|
||||||
rssUrl: 'https://blog.hehouhui.cn/api/rss',
|
rssUrl: 'https://blog.hehouhui.cn/api/rss'
|
||||||
cache: {
|
|
||||||
key: 'blog_articles_cache',
|
|
||||||
expirationDays: 1
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 通用缓存键与TTL(毫秒)
|
// 通用缓存键与TTL(毫秒)
|
||||||
|
|||||||
Reference in New Issue
Block a user