mirror of
https://github.com/LiuYuYang01/ThriveX-Blog.git
synced 2026-06-08 08:12:30 +08:00
完成顶部导航组件
This commit is contained in:
10
package-lock.json
generated
10
package-lock.json
generated
@@ -11,6 +11,7 @@
|
||||
"next": "14.2.5",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"react-icons": "^5.3.0",
|
||||
"sass": "^1.77.8",
|
||||
"typed.js": "^2.1.0"
|
||||
},
|
||||
@@ -1294,6 +1295,15 @@
|
||||
"react": "^18.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/react-icons": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/react-icons/-/react-icons-5.3.0.tgz",
|
||||
"integrity": "sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/read-cache": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/read-cache/-/read-cache-1.0.0.tgz",
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"next": "14.2.5",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"react-icons": "^5.3.0",
|
||||
"sass": "^1.77.8",
|
||||
"typed.js": "^2.1.0"
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Metadata } from "next";
|
||||
import Header from '@/components/Header'
|
||||
|
||||
// 加载样式文件
|
||||
import "@/styles/index.scss";
|
||||
@@ -11,6 +11,7 @@ const LXGWWenKai = localFont({
|
||||
display: 'swap',
|
||||
})
|
||||
|
||||
import type { Metadata } from "next";
|
||||
export const metadata: Metadata = {
|
||||
title: "宇阳 - 花有重开日,人无再少年!",
|
||||
description: "Generated by create next app",
|
||||
@@ -19,7 +20,10 @@ export const metadata: Metadata = {
|
||||
export default function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={LXGWWenKai.className}>{children}</body>
|
||||
<body className={LXGWWenKai.className}>
|
||||
<Header />
|
||||
{children}
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,9 @@ export default function Home() {
|
||||
return (
|
||||
<>
|
||||
<Swiper>
|
||||
{/* 星空背景组件 */}
|
||||
<Starry />
|
||||
{/* 打字机组件 */}
|
||||
<Typed className="absolute top-[40%] left-[50%] transform -translate-x-1/2 w-[80%] text-center text-white text-[30px] custom_text_shadow"></Typed>
|
||||
</Swiper>
|
||||
</>
|
||||
|
||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
BIN
src/assets/image/light_logo.png
Normal file
BIN
src/assets/image/light_logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
89
src/components/Header/index.scss
Normal file
89
src/components/Header/index.scss
Normal file
@@ -0,0 +1,89 @@
|
||||
@import "@/styles/var.scss";
|
||||
|
||||
.HeaderComponent {
|
||||
.header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
backdrop-filter: blur(5px);
|
||||
transition: background-color $move;
|
||||
z-index: 999;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
background: linear-gradient(#fff, transparent 70%);
|
||||
transition: background $move;
|
||||
}
|
||||
|
||||
// 二级导航
|
||||
.two {
|
||||
display: none;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 50px;
|
||||
width: 100%;
|
||||
border-radius: $round;
|
||||
background-color: #f9f9f9;
|
||||
box-shadow: 0 12px 32px rgba(0, 0, 0, .1), 0 2px 6px rgba(0, 0, 0, .08);
|
||||
|
||||
.two_item {
|
||||
.two_item_nav {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
padding-left: 10px;
|
||||
font-size: 15px;
|
||||
box-sizing: border-box;
|
||||
color: #666;
|
||||
transition: all $move;
|
||||
|
||||
// 鼠标经过的小横线
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 0;
|
||||
height: 3px;
|
||||
background-color: $color;
|
||||
transition: width $move;
|
||||
}
|
||||
}
|
||||
|
||||
// 鼠标经过二级导航的效果
|
||||
&:hover .two_item_nav {
|
||||
color: $color !important;
|
||||
background-color: #f2f2f2;
|
||||
padding-left: 30px;
|
||||
|
||||
&:hover::after {
|
||||
width: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 鼠标经过哪个,就让哪个二级导航显示
|
||||
&:hover .two {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.bg {
|
||||
border-bottom: 1px solid #eee;
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
transition: all $move;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
height: 30px;
|
||||
transition: height $move;
|
||||
}
|
||||
}
|
||||
}
|
||||
134
src/components/Header/index.tsx
Normal file
134
src/components/Header/index.tsx
Normal file
@@ -0,0 +1,134 @@
|
||||
"use client"
|
||||
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import Link from 'next/link';
|
||||
|
||||
import lightLogo from '@/assets/image/light_logo.png';
|
||||
import darkLogo from '@/assets/image/dark_logo.png';
|
||||
|
||||
import { IoIosArrowDown } from "react-icons/io";
|
||||
import "./index.scss"
|
||||
|
||||
const Header = () => {
|
||||
const cateList = [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "开发笔记",
|
||||
"url": "/",
|
||||
"mark": "kfbj",
|
||||
"icon": "🎉",
|
||||
"level": 0,
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "生活随笔",
|
||||
"url": "/",
|
||||
"mark": "shsb",
|
||||
"icon": "✍️",
|
||||
"level": 0,
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "大前端",
|
||||
"url": "http://127.0.0.1:5000",
|
||||
"mark": "dqd",
|
||||
"icon": "🎉",
|
||||
"level": 0,
|
||||
"children": [
|
||||
{
|
||||
"id": 5,
|
||||
"name": "前端",
|
||||
"url": "/",
|
||||
"mark": "qd",
|
||||
"icon": "?",
|
||||
"level": 4,
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "Java",
|
||||
"url": "/",
|
||||
"mark": "java",
|
||||
"icon": "?",
|
||||
"level": 4,
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "Python",
|
||||
"url": "/",
|
||||
"mark": "python",
|
||||
"icon": "?",
|
||||
"level": 4,
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
const [isScrolled, setIsScrolled] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
setIsScrolled(window.scrollY > 100);
|
||||
};
|
||||
|
||||
window.addEventListener('scroll', handleScroll);
|
||||
|
||||
return () => window.removeEventListener('scroll', handleScroll);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className='HeaderComponent'>
|
||||
<div className={`header ${isScrolled ? 'bg' : ''}`}>
|
||||
<div className="w-[1500px] mx-auto flex items-center h-full">
|
||||
<ul className="flex items-center h-full">
|
||||
<li className="relative">
|
||||
<Link href="/" className="flex items-center">
|
||||
<img
|
||||
src={!isScrolled ? darkLogo.src : lightLogo.src}
|
||||
alt="Logo"
|
||||
className="h-10 pr-5 transition-transform hover:scale-90"
|
||||
/>
|
||||
</Link>
|
||||
</li>
|
||||
|
||||
<li className="relative group">
|
||||
<Link href="/" className={`text-[15px] px-5 py-4 ${isScrolled ? 'text-[#333]' : 'text-white'} transition-colors group-hover:text-primary`}>
|
||||
💎 首页
|
||||
</Link>
|
||||
</li>
|
||||
|
||||
{cateList.map(one => (
|
||||
<li key={one.id} className="relative group">
|
||||
<Link href={one.url} className={`text-[15px] px-5 py-4 ${isScrolled ? 'text-[#333]' : 'text-white'} transition-colors flex items-center group-hover:text-primary`}>
|
||||
{one.icon} {one.name}
|
||||
{one.children.length > 0 && (
|
||||
<IoIosArrowDown className="ml-2" />
|
||||
)}
|
||||
</Link>
|
||||
|
||||
{one.children.length > 0 && (
|
||||
// <ul className="absolute left-0 w-full bg-white shadow-lg rounded-md hidden group-hover:block">
|
||||
<ul className="two">
|
||||
{one.children.map(two => (
|
||||
<li key={two.id} className="two_item">
|
||||
<Link href={two.url} className="two_item_nav">
|
||||
{two.name}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Header;
|
||||
@@ -3,7 +3,7 @@
|
||||
import { useEffect } from 'react';
|
||||
import './index.scss';
|
||||
|
||||
const StarrySky = () => {
|
||||
const StarrySky: React.FC = () => {
|
||||
useEffect(() => {
|
||||
/*星星的密集程度,数字越大越多*/
|
||||
const stars = 800;
|
||||
@@ -14,10 +14,10 @@ const StarrySky = () => {
|
||||
for (let i = 0; i < stars; i++) {
|
||||
const star = document.createElement('div');
|
||||
star.classList.add('star_starrySky');
|
||||
starsContainer.appendChild(star);
|
||||
starsContainer?.appendChild(star);
|
||||
}
|
||||
|
||||
const starElements = document.querySelectorAll('.star_starrySky');
|
||||
const starElements = document.querySelectorAll<HTMLElement>('.star_starrySky');
|
||||
starElements.forEach((starElement) => {
|
||||
const s = 0.2 + Math.random() * 1;
|
||||
const curR = r + Math.random() * 300;
|
||||
@@ -36,4 +36,4 @@ const StarrySky = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default StarrySky;
|
||||
export default StarrySky;
|
||||
@@ -1,3 +1,8 @@
|
||||
body {
|
||||
height: 2000px;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.custom_text_shadow {
|
||||
text-shadow: 0 0.1875rem 0.3125rem #1c1f21;
|
||||
}
|
||||
15
src/styles/var.scss
Normal file
15
src/styles/var.scss
Normal file
@@ -0,0 +1,15 @@
|
||||
// 版心
|
||||
$w: 1200px;
|
||||
|
||||
// 色彩
|
||||
$color: var(--color, #539dfd); // 主色调
|
||||
$assistColor: var(--assistColor, #539dfd60); // 辅助色调
|
||||
|
||||
// 过渡效果
|
||||
$move: 0.3s;
|
||||
|
||||
// 圆角效果
|
||||
$round: 5px;
|
||||
|
||||
// 阴影效果
|
||||
$boxShadow: 0 2px 8px rgba(186, 186, 186, 0.15);
|
||||
@@ -8,10 +8,11 @@ const config: Config = {
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
backgroundImage: {
|
||||
"gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
|
||||
"gradient-conic":
|
||||
"conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
|
||||
colors: {
|
||||
primary: '#539dfd', // 添加自定义颜色
|
||||
},
|
||||
transitionDuration: {
|
||||
'DEFAULT': '300ms', // 添加默认过渡时间为0.3秒
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user