Skip to content

Commit 5071e32

Browse files
committed
feat: 优化 link list 样式
1 parent 5e1bba6 commit 5071e32

File tree

3 files changed

+159
-11
lines changed

3 files changed

+159
-11
lines changed

src/css/utilities/animations.css

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,37 @@
163163
animation: spin 1s linear infinite;
164164
}
165165

166+
/* ======================================
167+
页面切换动画
168+
====================================== */
169+
@keyframes pageEnter {
170+
from {
171+
opacity: 0;
172+
transform: translateY(20px);
173+
}
174+
to {
175+
opacity: 1;
176+
transform: translateY(0);
177+
}
178+
}
179+
180+
@keyframes pageExit {
181+
from {
182+
opacity: 1;
183+
transform: translateY(0) scale(1);
184+
}
185+
to {
186+
opacity: 0;
187+
transform: translateY(-20px) scale(0.98);
188+
}
189+
}
190+
191+
/* 全局页面进入动画 */
192+
main[class*="page"],
193+
.main-wrapper {
194+
animation: pageEnter 0.4s cubic-bezier(0.4, 0, 0.2, 1) forwards;
195+
}
196+
166197
/* ======================================
167198
移动端侧边栏动画
168199
====================================== */

src/pages/index.module.scss

Lines changed: 94 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,35 @@
1717
padding-top: var(--ifm-navbar-height, 60px);
1818
position: relative;
1919
overflow: hidden;
20+
animation: pageEnter 0.4s cubic-bezier(0.4, 0, 0.2, 1) forwards;
21+
}
22+
23+
// 页面进入动画
24+
@keyframes pageEnter {
25+
from {
26+
opacity: 0;
27+
transform: translateY(20px);
28+
}
29+
to {
30+
opacity: 1;
31+
transform: translateY(0);
32+
}
33+
}
34+
35+
// 页面退出动画
36+
.pageExit {
37+
animation: pageExit 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards !important;
38+
}
39+
40+
@keyframes pageExit {
41+
from {
42+
opacity: 1;
43+
transform: translateY(0) scale(1);
44+
}
45+
to {
46+
opacity: 0;
47+
transform: translateY(-20px) scale(0.98);
48+
}
2049
}
2150

2251
[data-theme="light"] .page {
@@ -443,6 +472,12 @@
443472
}
444473
}
445474

475+
// 列表项入场动画
476+
.linkItem {
477+
opacity: 0;
478+
animation: slideInFromRight 0.5s cubic-bezier(0.4, 0, 0.2, 1) forwards;
479+
}
480+
446481
a {
447482
position: relative;
448483
display: flex;
@@ -454,9 +489,10 @@
454489
text-decoration: none;
455490
color: inherit;
456491
width: 100%;
457-
transition: all 0.2s ease;
492+
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
458493
// 确保触摸目标足够大
459494
min-height: 72px;
495+
overflow: hidden;
460496

461497
// 左侧指示条
462498
&::before {
@@ -469,19 +505,39 @@
469505
height: 0;
470506
background: linear-gradient(180deg, var(--primary) 0%, var(--primary-light) 100%);
471507
border-radius: 0 2px 2px 0;
472-
transition: height 0.2s cubic-bezier(0.4, 0, 0.2, 1);
508+
transition: height 0.3s cubic-bezier(0.4, 0, 0.2, 1);
509+
}
510+
511+
// 点击波纹效果
512+
&::after {
513+
content: "";
514+
position: absolute;
515+
top: 50%;
516+
left: 50%;
517+
width: 0;
518+
height: 0;
519+
border-radius: 50%;
520+
background: rgba(0, 220, 130, 0.2);
521+
transform: translate(-50%, -50%);
522+
transition:
523+
width 0.4s ease,
524+
height 0.4s ease,
525+
opacity 0.4s ease;
526+
opacity: 0;
527+
pointer-events: none;
473528
}
474529

475530
&:hover {
476531
background: var(--primary-alpha-5);
477532
text-decoration: none;
533+
transform: translateX(4px);
478534

479535
&::before {
480536
height: 60%;
481537
}
482538

483539
span:last-child {
484-
transform: translateX(4px);
540+
transform: translateX(6px);
485541
color: var(--primary);
486542
}
487543

@@ -490,16 +546,35 @@
490546
}
491547
}
492548

493-
// 移动端添加 active 状态反馈
549+
// 点击动画
494550
&:active {
495551
background: var(--primary-alpha-10);
552+
transform: translateX(2px) scale(0.98);
553+
554+
&::after {
555+
width: 300px;
556+
height: 300px;
557+
opacity: 1;
558+
transition:
559+
width 0.3s ease,
560+
height 0.3s ease,
561+
opacity 0.3s ease 0.1s;
562+
}
563+
564+
&::before {
565+
height: 80%;
566+
}
567+
568+
span:last-child {
569+
transform: translateX(8px) scale(1.1);
570+
}
496571
}
497572

498573
// 箭头图标
499574
span:last-child {
500575
font-size: 18px;
501576
color: var(--text-light);
502-
transition: all 0.2s ease;
577+
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
503578
flex-shrink: 0;
504579
}
505580

@@ -516,7 +591,7 @@
516591
font-size: 16px;
517592
font-weight: 600;
518593
color: var(--text-primary);
519-
transition: color 0.2s ease;
594+
transition: color 0.3s cubic-bezier(0.4, 0, 0.2, 1);
520595

521596
@media (max-width: 540px) {
522597
font-size: 15px;
@@ -529,6 +604,7 @@
529604
font-size: 14px;
530605
color: var(--text-secondary);
531606
line-height: 1.5;
607+
transition: color 0.3s cubic-bezier(0.4, 0, 0.2, 1);
532608

533609
@media (max-width: 540px) {
534610
font-size: 13px;
@@ -537,6 +613,18 @@
537613
}
538614
}
539615

616+
// 列表项入场动画
617+
@keyframes slideInFromRight {
618+
from {
619+
opacity: 0;
620+
transform: translateX(20px);
621+
}
622+
to {
623+
opacity: 1;
624+
transform: translateX(0);
625+
}
626+
}
627+
540628
/* ======================================
541629
入场动画
542630
====================================== */

src/pages/index.tsx

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import Head from "@docusaurus/Head";
22
import Link from "@docusaurus/Link";
33
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
44
import Layout from "@theme/Layout";
5-
import React from "react";
5+
import { useHistory } from "@docusaurus/router";
6+
import React, { useRef } from "react";
67
import styles from "./index.module.scss";
78

89
interface Stat {
@@ -18,6 +19,8 @@ interface NavLink {
1819

1920
const Home: React.FC = () => {
2021
const { siteConfig } = useDocusaurusContext();
22+
const history = useHistory();
23+
const pageRef = useRef<HTMLElement>(null);
2124

2225
const stats: Stat[] = [
2326
{ label: "文档篇章", value: "1200+" },
@@ -30,13 +33,31 @@ const Home: React.FC = () => {
3033
{ title: "基岩版核心", description: "基岩版服务器开服指南", to: "/Bedrock/intro" }
3134
];
3235

36+
const handleLinkClick = (e: React.MouseEvent<HTMLAnchorElement>, to: string) => {
37+
e.preventDefault();
38+
const pageElement = pageRef.current;
39+
40+
if (pageElement) {
41+
// 添加退出动画类
42+
pageElement.classList.add(styles.pageExit);
43+
44+
// 延迟导航,让退出动画完成
45+
setTimeout(() => {
46+
history.push(to);
47+
}, 300);
48+
} else {
49+
// 如果找不到元素,直接导航
50+
history.push(to);
51+
}
52+
};
53+
3354
return (
3455
<Layout>
3556
<Head>
3657
<title>{siteConfig.title}</title>
3758
<meta name="description" content={siteConfig.tagline} />
3859
</Head>
39-
<main className={styles.page}>
60+
<main ref={pageRef} className={styles.page}>
4061
{/* 装饰性模糊圆形 */}
4162
<div className={`${styles.decorCircle} ${styles.decorCircle1}`} />
4263
<div className={`${styles.decorCircle} ${styles.decorCircle2}`} />
@@ -74,14 +95,22 @@ const Home: React.FC = () => {
7495
</div>
7596
<ul className={styles.linkList}>
7697
{quickLinks.map((item, index) => (
77-
<li key={item.title}>
78-
<Link to={item.to}>
98+
<li
99+
key={item.title}
100+
className={styles.linkItem}
101+
style={{ animationDelay: `${0.4 + index * 0.1}s` }}
102+
>
103+
<a
104+
href={item.to}
105+
className={styles.linkItemAnchor}
106+
onClick={(e) => handleLinkClick(e, item.to)}
107+
>
79108
<div>
80109
<h3>{item.title}</h3>
81110
<p>{item.description}</p>
82111
</div>
83112
<span></span>
84-
</Link>
113+
</a>
85114
</li>
86115
))}
87116
</ul>

0 commit comments

Comments
 (0)