Skip to content

Commit

Permalink
feat: ✨ 减少动画,增加回到顶部
Browse files Browse the repository at this point in the history
  • Loading branch information
zhuba-Ahhh committed Sep 19, 2024
1 parent 218851c commit 47a1b6b
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 78 deletions.
8 changes: 4 additions & 4 deletions src/app/about/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@ export default function About() {

return (
<div
className={`max-w-4xl mx-auto rounded-lg shadow-lg p-8 my-10
className={`max-w-4xl mx-auto rounded-lg shadow-lg p-8 my-10 transition-all duration-300 ease-in-out
${
theme === "dark"
? "bg-gray-800 text-white"
: "bg-gradient-to-br from-blue-50 to-indigo-100 text-gray-800"
}`}
>
<h1
className={`text-4xl font-bold mb-6 ${
className={`text-4xl font-bold mb-6 transition-colors duration-300 ${
theme === "dark" ? "text-indigo-300" : "text-indigo-800"
}`}
>
关于我的博客
</h1>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
<div
className={`md:col-span-2 prose lg:prose-xl ${
className={`md:col-span-2 prose lg:prose-xl transition-all duration-300 ${
theme === "dark" ? "text-gray-300" : "text-gray-700"
}`}
>
Expand All @@ -43,7 +43,7 @@ export default function About() {
如果你有任何问题、建议或合作意向,欢迎随时与我联系。让我们一起在编程的世界里探索和创新!
</p>
</div>
<div className="flex flex-col items-center justify-center">
<div className="flex flex-col items-center justify-center transition-transform duration-300 hover:scale-105">
<Image
src="/img/avatar.png"
alt="博主头像"
Expand Down
30 changes: 8 additions & 22 deletions src/app/blog/[id]/AnimatedBlogPost.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"use client";

import { motion } from "framer-motion";
import BlogHeader from "./BlogHeader";
import BlogContent from "./BlogContent";
import BlogFooter from "./BlogFooter";
import RelatedPosts from "./RelatedPosts";
import ShareButtons from "./ShareButtons";
import TableOfContents from "./TableOfContents";
import ScrollToTop from "@/components/blog/id/ScrollToTop";
import Comments from "@/components/blog/id/Comments";
import { mdxComponents } from "./MdxComponents";
import type { Heading } from "./types";
Expand All @@ -32,29 +32,14 @@ export default function AnimatedBlogPost({
relatedPosts,
}: AnimatedBlogPostProps) {
return (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.5 }}
className="container mx-auto px-4 py-8 text-gray-900 dark:text-gray-100 bg-white dark:bg-gray-800"
>
<div className="container mx-auto px-4 py-8 text-gray-900 dark:text-gray-100 bg-white dark:bg-gray-800">
<div className="flex flex-col md:flex-row gap-8">
<aside className="md:w-1/4">
<motion.div
initial={{ x: -50, opacity: 0 }}
animate={{ x: 0, opacity: 1 }}
transition={{ duration: 0.5, delay: 0.2 }}
className="sticky top-20"
>
<div className="sticky top-20">
<TableOfContents headings={headings} />
</motion.div>
</div>
</aside>
<motion.article
className="md:w-3/4"
initial={{ y: 50, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.5, delay: 0.3 }}
>
<article className="md:w-3/4">
<BlogHeader
post={post}
readingTime={readingTime}
Expand All @@ -74,8 +59,9 @@ export default function AnimatedBlogPost({
<div className="mt-16">
<Comments />
</div>
</motion.article>
</article>
<ScrollToTop />
</div>
</motion.div>
</div>
);
}
4 changes: 2 additions & 2 deletions src/app/blog/[id]/MdxComponents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ export const mdxComponents: MDXComponents = {
h2: (props: any) => (
<h2
id={props.children.toString().toLowerCase().replace(/\s+/g, "-")}
className="relative text-2xl font-semibold mt-6 mb-3 text-gray-800 dark:text-gray-200 scroll-mt-20 cursor-pointer before:content-['#'] before:absolute before:-left-6 before:opacity-0 hover:before:opacity-100 before:text-gray-800 dark:before:text-gray-200" // 设置 # 符号颜色与字体对齐
className="relative text-2xl font-semibold mt-6 mb-3 text-gray-800 dark:text-gray-200 scroll-mt-20 cursor-pointer before:content-['#'] before:absolute before:-left-6 before:opacity-0 hover:before:opacity-100 before:text-blue-500 dark:before:text-blue-400" // 设置 # 符号颜色与字体对齐
{...props}
/>
),
h3: (props: any) => (
<h3
id={props.children.toString().toLowerCase().replace(/\s+/g, "-")}
className="relative text-xl font-medium mt-4 mb-2 text-gray-700 dark:text-gray-300 scroll-mt-20 cursor-pointer before:content-['#'] before:absolute before:-left-6 before:opacity-0 hover:before:opacity-100 before:text-gray-700 dark:before:text-gray-300" // 设置 # 符号颜色与字体对齐
className="relative text-xl font-medium mt-4 mb-2 text-gray-700 dark:text-gray-300 scroll-mt-20 cursor-pointer before:content-['#'] before:absolute before:-left-6 before:opacity-0 hover:before:opacity-100 before:text-blue-500 dark:before:text-blue-400" // 设置 # 符号颜色与字体对齐
{...props}
/>
),
Expand Down
37 changes: 3 additions & 34 deletions src/components/app/AnimatedLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,7 @@
"use client";

import {
LazyMotion,
domAnimation,
motion,
AnimatePresence,
} from "framer-motion";
import { usePathname } from "next/navigation";
import React, { ReactNode } from "react";

const pageVariants = {
initial: { opacity: 0, x: "-100%" },
in: { opacity: 1, x: 0 },
// out: { opacity: 0, x: "100%" },
};

const pageTransition = {
type: "tween",
ease: "anticipate",
duration: 0.5,
};

interface AnimatedLayoutProps {
children: ReactNode;
}
Expand All @@ -29,20 +10,8 @@ export default function AnimatedLayout({ children }: AnimatedLayoutProps) {
const pathname = usePathname();

return (
<LazyMotion features={domAnimation}>
<AnimatePresence mode="wait">
<motion.main
key={pathname}
initial="initial"
animate="in"
exit="out"
variants={pageVariants}
// transition={pageTransition}
className="flex-grow container mx-auto px-4 mt-16"
>
{children}
</motion.main>
</AnimatePresence>
</LazyMotion>
<main key={pathname} className="flex-grow container mx-auto px-4 mt-16">
{children}
</main>
);
}
10 changes: 7 additions & 3 deletions src/components/app/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,24 @@ export default function Footer() {
{ href: "/contact", label: "联系我们" },
];

const buildYear = 2024; // 建站年份
const currentYear = new Date().getFullYear(); // 当前年份
const isNew = currentYear === buildYear; // 判断是否为新建站

return (
<footer className="border-t py-6 md:py-0">
<footer className="border-t py-6 md:py-0 bg-gray-100">
<div className="container flex flex-col items-center justify-between gap-4 md:h-24 md:flex-row">
<div className="flex flex-col items-center gap-4 px-8 md:flex-row md:gap-2 md:px-0">
<p className="text-center text-sm leading-loose text-muted-foreground md:text-left">
&copy; 2024 我的博客. 保留所有权利。
&copy; {currentYear} 我的博客. 保留所有权利。{isNew ? "新建站" : `建站时间: ${buildYear}年`},感谢您的访问!
</p>
</div>
<nav className="flex items-center space-x-4">
{links.map((link) => (
<Link
key={link.href}
href={link.href}
className="text-sm text-muted-foreground"
className="text-sm text-muted-foreground hover:text-blue-500 transition duration-200" // 增加过渡效果
>
<Badge>{link.label}</Badge>
</Link>
Expand Down
26 changes: 13 additions & 13 deletions src/components/app/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@ interface LayoutProps {
}

export default function Layout({ children }: LayoutProps) {
const [showScrollTop, setShowScrollTop] = useState(false);
// const [showScrollTop, setShowScrollTop] = useState(false);

useEffect(() => {
const handleScroll = debounce(() => {
setShowScrollTop(window.pageYOffset > 300);
}, 100);
// useEffect(() => {
// const handleScroll = debounce(() => {
// setShowScrollTop(window.pageYOffset > 300);
// }, 100);

window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
// window.addEventListener("scroll", handleScroll);
// return () => window.removeEventListener("scroll", handleScroll);
// }, []);

const scrollToTop = () => {
window.scrollTo({ top: 0, behavior: "smooth" });
};
// const scrollToTop = () => {
// window.scrollTo({ top: 0, behavior: "smooth" });
// };

return (
<div className="flex flex-col min-h-screen bg-gray-50 dark:bg-gray-900 text-gray-800 dark:text-gray-200">
Expand All @@ -30,15 +30,15 @@ export default function Layout({ children }: LayoutProps) {
{children}
</main>
<Footer />
{showScrollTop && (
{/* {showScrollTop && (
<button
onClick={scrollToTop}
className="fixed bottom-8 right-8 bg-blue-500 hover:bg-blue-600 text-white p-2 rounded-full shadow-lg transition-opacity duration-300 ease-in-out"
aria-label="滚动到顶部"
>
</button>
)}
)} */}
</div>
);
}
36 changes: 36 additions & 0 deletions src/components/blog/id/ScrollToTop.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"use client";
import React, { useState, useCallback, useEffect } from "react";
import { debounce } from "lodash-es";

export default function ScrollToTop() {
const [showScroll, setShowScroll] = useState(false);

const handleScroll = useCallback(
() => setShowScroll(window.scrollY > 500),
[]
);

useEffect(() => {
window.addEventListener("scroll", handleScroll);
setShowScroll(false);
return () => window.removeEventListener("scroll", handleScroll);
}, [handleScroll]);

const scrollToTop = useCallback(() => {
window.scrollTo({ top: 0, behavior: "smooth" });
}, []);

return (
<>
{showScroll && (
<button
onClick={scrollToTop}
className="fixed bottom-4 right-4 p-2 bg-gray-800 text-white rounded-full shadow-lg transition-opacity duration-300" // 添加过渡效果
style={{ visibility: showScroll ? "visible" : "hidden" }} // 使用visibility控制显示
>
回到顶部
</button>
)}
</>
);
}

0 comments on commit 47a1b6b

Please sign in to comment.