|
1 | 1 | --- |
2 | | -import IconChevronLeft from "@/assets/icons/IconChevronLeft.svg"; |
3 | 2 | import IconArrowNarrowUp from "@/assets/icons/IconArrowNarrowUp.svg"; |
4 | 3 | --- |
5 | 4 |
|
6 | 5 | <div |
7 | 6 | id="btt-btn-container" |
8 | | - class:list={[ |
9 | | - "fixed end-4 bottom-8 z-50", |
10 | | - "md:sticky md:end-auto md:float-end md:me-1", |
11 | | - "translate-y-14 opacity-0 transition duration-500", |
12 | | - ]} |
| 7 | + class="mt-4 translate-y-4 opacity-0 transition duration-500" |
13 | 8 | > |
14 | 9 | <button |
15 | 10 | data-button="back-to-top" |
16 | | - class:list={[ |
17 | | - "group relative bg-background px-2 py-1", |
18 | | - "size-14 rounded-full shadow-xl", |
19 | | - "md:h-8 md:w-fit md:rounded-md md:shadow-none md:focus-visible:rounded-none", |
20 | | - "md:bg-background/35 md:bg-clip-padding md:backdrop-blur-lg", |
21 | | - ]} |
| 11 | + class="flex items-center gap-1 rounded-md border border-foreground/10 bg-background/50 px-3 py-1.5 text-sm text-foreground/70 backdrop-blur-sm transition-colors hover:border-accent hover:text-accent" |
22 | 12 | > |
23 | | - <span |
24 | | - id="progress-indicator" |
25 | | - class="absolute inset-0 -z-10 block size-14 scale-110 rounded-full bg-transparent md:hidden md:h-8 md:rounded-md" |
26 | | - ></span> |
27 | | - <IconChevronLeft class="inline-block rotate-90 md:hidden" /> |
28 | | - <span class="sr-only text-sm group-hover:text-accent md:not-sr-only"> |
29 | | - <IconArrowNarrowUp class="inline-block size-4" /> |
30 | | - 返回顶部 |
31 | | - </span> |
| 13 | + <IconArrowNarrowUp class="inline-block size-4" /> |
| 14 | + 返回顶部 |
32 | 15 | </button> |
33 | 16 | </div> |
34 | 17 |
|
35 | 18 | <script is:inline data-astro-rerun> |
36 | | - /** Scrolls the document to the top when |
37 | | - * the "Back to Top" button is clicked. */ |
38 | 19 | function backToTop() { |
39 | 20 | const rootElement = document.documentElement; |
40 | 21 | const btnContainer = document.querySelector("#btt-btn-container"); |
41 | 22 | const backToTopBtn = document.querySelector("[data-button='back-to-top']"); |
42 | | - const progressIndicator = document.querySelector("#progress-indicator"); |
43 | 23 |
|
44 | | - if (!rootElement || !btnContainer || !backToTopBtn || !progressIndicator) |
45 | | - return; |
| 24 | + if (!rootElement || !btnContainer || !backToTopBtn) return; |
46 | 25 |
|
47 | | - // Attach click event handler for back-to-top button |
48 | 26 | backToTopBtn.addEventListener("click", () => { |
49 | | - document.body.scrollTop = 0; // For Safari |
50 | | - document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera |
| 27 | + document.body.scrollTop = 0; |
| 28 | + document.documentElement.scrollTop = 0; |
51 | 29 | }); |
52 | 30 |
|
53 | | - // Handle button visibility according to scroll position |
54 | 31 | let lastVisible = null; |
55 | 32 | function handleScroll() { |
56 | 33 | const scrollTotal = rootElement.scrollHeight - rootElement.clientHeight; |
57 | 34 | const scrollTop = rootElement.scrollTop; |
58 | | - const scrollPercent = Math.floor((scrollTop / scrollTotal) * 100); |
59 | | - |
60 | | - progressIndicator.style.setProperty( |
61 | | - "background-image", |
62 | | - `conic-gradient(var(--accent), var(--accent) ${scrollPercent}%, transparent ${scrollPercent}%)` |
63 | | - ); |
64 | | - |
65 | 35 | const isVisible = scrollTop / scrollTotal > 0.3; |
66 | 36 |
|
67 | 37 | if (isVisible !== lastVisible) { |
68 | 38 | btnContainer.classList.toggle("opacity-100", isVisible); |
69 | 39 | btnContainer.classList.toggle("translate-y-0", isVisible); |
70 | 40 | btnContainer.classList.toggle("opacity-0", !isVisible); |
71 | | - btnContainer.classList.toggle("translate-y-14", !isVisible); |
| 41 | + btnContainer.classList.toggle("translate-y-4", !isVisible); |
72 | 42 | lastVisible = isVisible; |
73 | 43 | } |
74 | 44 | } |
|
0 commit comments