@@ -49,8 +49,8 @@ const currentReading = bookshelfData.find((item: any) => item.status === 'readin
4949 <div class = ' absolute top-0 right-0 w-32 h-32 bg-purple-500/5 rounded-full blur-3xl opacity-0 group-hover:opacity-100 transition-opacity duration-500' ></div >
5050 <div class = ' relative' >
5151 <div class = ' flex items-start gap-4 mb-4' >
52- <div class = ' size-12 rounded-lg bg-purple-100 dark:bg-purple-900 flex items-center justify-center group-hover:scale-110 group-hover:rotate-3 transition-all duration-300 flex-shrink-0' >
53- <Icon name = ' book ' class = ' size-6 text-purple-600 dark:text-purple-400' />
52+ <div class = ' size-8 rounded-lg bg-purple-100 dark:bg-purple-900 flex items-center justify-center group-hover:scale-110 transition-all duration-300 flex-shrink-0' >
53+ <Icon name = ' shelf ' class = ' size-5 text-purple-600 dark:text-purple-400' />
5454 </div >
5555 <div class = ' flex-1 min-w-0' >
5656 <div class = ' flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 mb-1' >
@@ -101,15 +101,15 @@ const currentReading = bookshelfData.find((item: any) => item.status === 'readin
101101 <div class =' relative' >
102102 <div class =' flex items-center justify-between mb-4' >
103103 <div class =' flex items-center gap-2' >
104- <div class =' size-8 rounded-lg bg-blue-100 dark:bg-blue-900 flex items-center justify-center group-hover:scale-110 group-hover:rotate-3 transition-all duration-300' >
105- <Icon name =' document' class =' size-4 text-blue-600 dark:text-blue-400' />
104+ <div class =' size-8 rounded-lg bg-blue-100 dark:bg-blue-900 flex items-center justify-center group-hover:scale-110 transition-all duration-300' >
105+ <Icon name =' document' class =' size-5 text-blue-600 dark:text-blue-400' />
106106 </div >
107107 <h2 class =' text-lg font-semibold text-foreground' >最新文章</h2 >
108108 </div >
109109 <a href =' /blog' class =' text-sm text-primary hover:underline group-hover:translate-x-1 transition-transform inline-block' >查看更多 →</a >
110110 </div >
111111 <ul class =' space-y-2' >
112- { allPostsByDate .map ((post , index ) => (
112+ { allPostsByDate .map ((post ) => (
113113 <li class = ' post-item' >
114114 <a href = { ` /blog/${post .data .slug } ` } class = ' flex items-center gap-3 p-2 rounded hover:bg-muted/50 transition-all group/item' >
115115 <div class = ' size-6 rounded bg-muted flex items-center justify-center group-hover/item:bg-primary/10 group-hover/item:scale-110 transition-all' >
@@ -137,10 +137,11 @@ const currentReading = bookshelfData.find((item: any) => item.status === 'readin
137137 <div class =' absolute inset-0' >
138138 <Image
139139 src ={ avatarImage }
140- alt =' Avatar '
140+ alt =' CatCodeMe 头像 - 个人博客作者 '
141141 class =' w-full h-full object-cover'
142+ loading =' eager'
143+ fetchpriority =' high'
142144 />
143- <div class =' absolute inset-0 bg-black/0 group-hover:bg-black/50 transition-all duration-500' ></div >
144145 </div >
145146 <div class =' relative p-6 z-10' >
146147 <h3 class =' text-xl font-semibold text-white mb-3' >CatCodeMe</h3 >
@@ -154,13 +155,16 @@ const currentReading = bookshelfData.find((item: any) => item.status === 'readin
154155 </p >
155156 </div >
156157 <div class =' flex items-center gap-3' >
157- <a href =' https://github.com/CatCodeMe' target =' _blank' rel =' noopener noreferrer' class =' text-white hover:text-primary transition-colors' >
158+ <a href =' https://github.com/CatCodeMe' target =' _blank' rel =' noopener noreferrer' class =' text-white hover:text-primary transition-colors' aria-label = ' 访问 GitHub 主页 ' >
158159 <Icon name =' github' class =' size-5' />
159160 </a >
160- <a href =' https://twitter.com' target =' _blank' rel =' noopener noreferrer' class =' text-white hover:text-primary transition-colors' >
161+ <a href =' https://twitter.com/hulj13 ' target =' _blank' rel =' noopener noreferrer' class =' text-white hover:text-primary transition-colors' aria-label = ' 访问 Twitter 主页 ' >
161162 <Icon name =' x' class =' size-5' />
162163 </a >
163- <a href =' mailto:your@email.com' class =' text-white hover:text-primary transition-colors' >
164+ <a href =' /rss.xml' class =' text-white hover:text-primary transition-colors' aria-label =' 订阅 RSS' >
165+ <Icon name =' rss' class =' size-5' />
166+ </a >
167+ <a href =' #' id =' email-link' class =' text-white hover:text-primary transition-colors' aria-label =' 发送邮件' >
164168 <Icon name =' email' class =' size-5' />
165169 </a >
166170 </div >
@@ -173,18 +177,20 @@ const currentReading = bookshelfData.find((item: any) => item.status === 'readin
173177 <div class =' absolute top-0 right-0 w-32 h-32 bg-blue-500/5 rounded-full blur-3xl opacity-0 group-hover:opacity-100 transition-opacity duration-500' ></div >
174178 <div class =' relative' >
175179 <div class =' flex items-center gap-2 mb-4' >
176- <div class =' size-8 rounded-lg bg-blue-100 dark:bg-blue-900 flex items-center justify-center group-hover:scale-110 group-hover:rotate-3 transition-all duration-300' >
177- <Icon name =' document ' class =' size-4 text-blue-600 dark:text-blue-400' />
180+ <div class =' size-8 rounded-lg bg-blue-100 dark:bg-blue-900 flex items-center justify-center group-hover:scale-110 transition-all duration-300' >
181+ <Icon name =' content-statistic ' class =' size-5 text-blue-600 dark:text-blue-400' />
178182 </div >
179- <h2 class =' text-lg font-semibold text-foreground' >博客统计 </h2 >
183+ <h2 class =' text-lg font-semibold text-foreground' >统计 </h2 >
180184 </div >
181185 <div class =' grid grid-cols-2 gap-4' >
182186 <div class =' text-center p-3 rounded-lg bg-muted/50' >
183187 <div class =' text-2xl font-bold text-foreground mb-1' >{ totalPosts } </div >
184188 <div class =' text-xs text-muted-foreground' >文章总数</div >
185189 </div >
186190 <div class =' text-center p-3 rounded-lg bg-muted/50' >
187- <div class =' text-2xl font-bold text-foreground mb-1' >{ totalWords .toLocaleString ()} </div >
191+ <div class =' text-2xl font-bold text-foreground mb-1' >
192+ <span id =' total-words-counter' class =' inline-block' >{ totalWords .toLocaleString ()} </span >
193+ </div >
188194 <div class =' text-xs text-muted-foreground' >总字数</div >
189195 </div >
190196 </div >
@@ -197,23 +203,25 @@ const currentReading = bookshelfData.find((item: any) => item.status === 'readin
197203 <div class =' absolute top-0 right-0 w-32 h-32 bg-orange-500/5 rounded-full blur-3xl opacity-0 group-hover:opacity-100 transition-opacity duration-500' ></div >
198204 <div class =' relative' >
199205 <div class =' flex items-center gap-2 mb-4' >
200- <div class =' size-8 rounded-lg bg-orange-100 dark:bg-orange-900 flex items-center justify-center group-hover:scale-110 group-hover:rotate-3 transition-all duration-300' >
201- <Icon name =' github' class =' size-4 text-orange-600 dark:text-orange-400' />
206+ <div class =' size-8 rounded-lg bg-orange-100 dark:bg-orange-900 flex items-center justify-center group-hover:scale-110 transition-all duration-300' >
207+ <Icon name =' github' class =' size-5 text-orange-600 dark:text-orange-400' />
202208 </div >
203209 <h2 class =' text-lg font-semibold text-foreground' >GitHub</h2 >
204210 </div >
205211 <div class =' rounded overflow-hidden group-hover:scale-105 transition-transform duration-300' >
206212 <img
207213 class =' hidden w-full dark:block'
208214 src =' https://raw.githubusercontent.com/CatCodeMe/catcodeme/output/github-contribution-grid-snake-dark.svg'
209- alt =' github contribution snake dark '
215+ alt =' GitHub 贡献图 - 深色模式 - 显示 CatCodeMe 的代码贡献活动 '
210216 loading =' lazy'
217+ fetchpriority =' low'
211218 />
212219 <img
213220 class =' block w-full dark:hidden'
214221 src =' https://raw.githubusercontent.com/CatCodeMe/catcodeme/output/github-contribution-grid-snake.svg'
215- alt =' github contribution snake light '
222+ alt =' GitHub 贡献图 - 浅色模式 - 显示 CatCodeMe 的代码贡献活动 '
216223 loading =' lazy'
224+ fetchpriority =' low'
217225 />
218226 </div >
219227 </div >
@@ -227,6 +235,59 @@ const currentReading = bookshelfData.find((item: any) => item.status === 'readin
227235 // Force light theme on homepage
228236 localStorage.setItem('theme', 'light');
229237 document.documentElement.dataset.theme = 'light';
238+
239+ // 数字滚动动画
240+ function animateCounter(element, targetValue, duration = 2000) {
241+ const startValue = 0;
242+ const startTime = performance.now();
243+ const targetNumber = parseInt(targetValue.replace(/,/g, ''));
244+
245+ function updateCounter(currentTime) {
246+ const elapsed = currentTime - startTime;
247+ const progress = Math.min(elapsed / duration, 1);
248+
249+ // 使用 easeOutCubic 缓动函数
250+ const easeOutCubic = 1 - Math.pow(1 - progress, 3);
251+ const currentValue = Math.floor(startValue + (targetNumber - startValue) * easeOutCubic);
252+
253+ element.textContent = currentValue.toLocaleString();
254+
255+ if (progress < 1) {
256+ requestAnimationFrame(updateCounter);
257+ } else {
258+ element.textContent = targetValue;
259+ }
260+ }
261+
262+ requestAnimationFrame(updateCounter);
263+ }
264+
265+ // 邮箱混淆 - 防止爬虫抓取
266+ function obfuscateEmail() {
267+ // 将邮箱地址拆分成多个部分,避免明文出现
268+ const parts = ['1020082805', '@', 'qq', '.', 'com'];
269+ const email = parts.join('');
270+
271+ const emailLink = document.getElementById('email-link');
272+ if (emailLink) {
273+ emailLink.href = 'mailto:' + email;
274+ }
275+ }
276+
277+ // 页面加载后启动动画
278+ document.addEventListener('DOMContentLoaded', () => {
279+ const counterElement = document.getElementById('total-words-counter');
280+ if (counterElement) {
281+ const targetValue = counterElement.textContent;
282+ counterElement.textContent = '0';
283+ setTimeout(() => {
284+ animateCounter(counterElement, targetValue, 2000);
285+ }, 500);
286+ }
287+
288+ // 初始化邮箱链接
289+ obfuscateEmail();
290+ });
230291</script >
231292 </main >
232293
@@ -332,5 +393,14 @@ const currentReading = bookshelfData.find((item: any) => item.status === 'readin
332393 }
333394 }
334395
396+ /* 数字滚动动画 */
397+ #total-words-counter {
398+ transition: transform 0.1s ease-out;
399+ }
400+
401+ #total-words-counter:hover {
402+ transform: scale(1.1);
403+ }
404+
335405</style >
336406</PageLayout >
0 commit comments