diff --git a/package-lock.json b/package-lock.json index 8bd42be..7923256 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index 9f4a4fa..a2cba12 100644 --- a/package.json +++ b/package.json @@ -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" }, diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 04f0670..6bd7daf 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -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 ( - {children} + +
+ {children} + ); } diff --git a/src/app/page.tsx b/src/app/page.tsx index 8e142ea..348b408 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -6,7 +6,9 @@ export default function Home() { return ( <> + {/* 星空背景组件 */} + {/* 打字机组件 */} diff --git a/src/assets/image/logo.png b/src/assets/image/dark_logo.png similarity index 100% rename from src/assets/image/logo.png rename to src/assets/image/dark_logo.png diff --git a/src/assets/image/light_logo.png b/src/assets/image/light_logo.png new file mode 100644 index 0000000..3c879cf Binary files /dev/null and b/src/assets/image/light_logo.png differ diff --git a/src/components/Header/index.scss b/src/components/Header/index.scss new file mode 100644 index 0000000..8ed7782 --- /dev/null +++ b/src/components/Header/index.scss @@ -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; + } + } +} \ No newline at end of file diff --git a/src/components/Header/index.tsx b/src/components/Header/index.tsx new file mode 100644 index 0000000..e1bb3d3 --- /dev/null +++ b/src/components/Header/index.tsx @@ -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 ( +
+
+
+
    +
  • + + Logo + +
  • + +
  • + + 💎 首页 + +
  • + + {cateList.map(one => ( +
  • + + {one.icon} {one.name} + {one.children.length > 0 && ( + + )} + + + {one.children.length > 0 && ( + //
      +
        + {one.children.map(two => ( +
      • + + {two.name} + +
      • + ))} +
      + )} + + ))} +
    +
+
+
+ ); +}; + +export default Header; \ No newline at end of file diff --git a/src/components/Starry/index.tsx b/src/components/Starry/index.tsx index 512db85..d02823b 100644 --- a/src/components/Starry/index.tsx +++ b/src/components/Starry/index.tsx @@ -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('.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; \ No newline at end of file diff --git a/src/styles/index.scss b/src/styles/index.scss index ae2a11f..6a11da3 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -1,3 +1,8 @@ +body { + height: 2000px; + background-color: #f9f9f9; +} + .custom_text_shadow { text-shadow: 0 0.1875rem 0.3125rem #1c1f21; } \ No newline at end of file diff --git a/src/styles/var.scss b/src/styles/var.scss new file mode 100644 index 0000000..a47f7df --- /dev/null +++ b/src/styles/var.scss @@ -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); \ No newline at end of file diff --git a/tailwind.config.ts b/tailwind.config.ts index e9a0944..c30dd45 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -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秒 }, }, },