theme-heo top-nav

This commit is contained in:
tangly1024.com
2023-07-18 17:56:05 +08:00
parent d98735bc42
commit fc3c631e31
3 changed files with 82 additions and 114 deletions

View File

@@ -17,7 +17,6 @@ export const MenuItemDrop = ({ link }) => {
href={link?.to}
className="font-sans hover:bg-black hover:bg-opacity-10 rounded-2xl flex justify-center items-center px-3 py-1 no-underline tracking-widest">
{link?.icon && <i className={link?.icon} />} {link?.name}
{hasSubMenu && <i className='px-2 fa fa-angle-down'></i>}
</Link>}
{/* 含子菜单的按钮 */}

View File

@@ -5,7 +5,9 @@ import RandomPostButton from './RandomPostButton'
import SearchButton from './SearchButton'
import SlideOver from './SlideOver'
import ReadingProgress from './ReadingProgress'
import NavBarSwipe from './NavBarSwipe'
import { MenuListTop } from './MenuListTop'
import { isBrowser } from '@/lib/utils'
import BLOG from '@/blog.config'
/**
* 顶部导航
* @param {*} param0
@@ -15,6 +17,9 @@ const NavBar = props => {
const [fixedNav, setFixedNav] = useState(false)
const [textWhite, setTextWhite] = useState(false)
const [navBgWhite, setBgWhite] = useState(false)
const [activeIndex, setActiveIndex] = useState(0)
const slideOverRef = useRef()
const toggleMenuOpen = () => {
@@ -33,8 +38,8 @@ const NavBar = props => {
const throttleMs = 200
/**
* 根据滚动条,切换导航栏样式
*/
* 根据滚动条,切换导航栏样式
*/
const scrollTrigger = useCallback(throttle(() => {
const scrollS = window.scrollY
@@ -57,7 +62,74 @@ const NavBar = props => {
}
}, throttleMs))
// 监听导航栏显示文字
useEffect(() => {
let prevScrollY = 0
let ticking = false
const handleScroll = () => {
if (!ticking) {
window.requestAnimationFrame(() => {
const currentScrollY = window.scrollY
if (currentScrollY > prevScrollY) {
setActiveIndex(1) // 向下滚动时设置activeIndex为1
} else {
setActiveIndex(0) // 向上滚动时设置activeIndex为0
}
prevScrollY = currentScrollY
ticking = false
})
ticking = true
}
}
if (isBrowser()) {
window.addEventListener('scroll', handleScroll)
}
return () => {
if (isBrowser()) {
window.removeEventListener('scroll', handleScroll)
}
}
}, [])
return (<>
<style jsx>{`
@keyframes fade-in-down {
0% {
opacity: 0.5;
transform: translateY(-30%);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fade-in-up {
0% {
opacity: 0.5;
transform: translateY(30%);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
.fade-in-down {
animation: fade-in-down 0.3s ease-in-out;
}
.fade-in-up {
animation: fade-in-up 0.3s ease-in-out;
}
`}</style>
{/* 顶部导航菜单栏 */}
<nav id='nav' className={`${fixedNav ? 'fixed' : 'relative bg-none'} ${textWhite ? 'text-white ' : 'text-black dark:text-white'} ${navBgWhite ? 'bg-white dark:bg-[#18171d]' : 'bg-none'} z-20 h-16 top-0 w-full`}>
<div className='flex h-full mx-auto justify-between items-center max-w-[86rem] px-8'>
@@ -67,13 +139,16 @@ const NavBar = props => {
</div>
{/* 中间菜单 */}
<NavBarSwipe {...props}/>
<div id='nav-bar-swipe' className={`hidden lg:flex flex-grow flex-col items-center justify-center h-full relative w-full ${activeIndex === 0 ? 'fade-in-down' : 'fade-in-up'}`}>
{activeIndex === 0 && <MenuListTop {...props} />}
{activeIndex === 1 && <h1 className='font-bold text-center text-light-400 dark:text-gray-400'>{BLOG.AUTHOR || BLOG.TITLE} | {BLOG.BIO}</h1>}
</div>
{/* 右侧固定 */}
<div className='flex justify-center items-center space-x-1'>
<div className='flex flex-shrink-0 justify-center items-center space-x-1'>
<RandomPostButton {...props} />
<SearchButton />
<ReadingProgress/>
<ReadingProgress />
{/* 移动端菜单按钮 */}
<div onClick={toggleMenuOpen} className='flex lg:hidden w-8 justify-center items-center h-8 cursor-pointer'>
@@ -82,7 +157,7 @@ const NavBar = props => {
</div>
{/* 右边侧拉抽屉 */}
<SlideOver cRef={slideOverRef} {...props}/>
<SlideOver cRef={slideOverRef} {...props} />
</div>
</nav>
</>)

View File

@@ -1,106 +0,0 @@
import BLOG from '@/blog.config'
import { isBrowser } from '@/lib/utils'
import { useEffect, useState } from 'react'
import { MenuListTop } from './MenuListTop'
/**
* 一个swipe组件
* 垂直方向g给导航栏用
* @param {*} param0
* @returns
*/
export default function NavSwipe(props) {
const [activeIndex, setActiveIndex] = useState(0)
const item1 = (
<div className='mr-1 justify-end items-center hidden lg:block'>
<div className='hidden lg:flex'>
<MenuListTop {...props} />
</div>
</div>
)
const item2 = <h1 className='font-bold text-light-400 dark:text-gray-400'>{BLOG.AUTHOR || BLOG.TITLE} | {BLOG.BIO}</h1>
const items = [item1, item2]
useEffect(() => {
let prevScrollY = 0
let ticking = false
const handleScroll = () => {
if (!ticking) {
window.requestAnimationFrame(() => {
const currentScrollY = window.scrollY
if (currentScrollY > prevScrollY) {
setActiveIndex(1) // 向下滚动时设置activeIndex为1
} else {
setActiveIndex(0) // 向上滚动时设置activeIndex为0
}
prevScrollY = currentScrollY
ticking = false
})
ticking = true
}
}
if (isBrowser()) {
window.addEventListener('scroll', handleScroll)
}
return () => {
if (isBrowser()) {
window.removeEventListener('scroll', handleScroll)
}
}
}, [])
return (
<div className="hidden lg:block h-full relative w-full overflow-hidden">
{items.map((item, index) => (
<div
key={index}
className={`absolute top-0 bottom-0 w-full h-full flex justify-center items-center line-clamp-1 transform transition-transform duration-500 ${
index === activeIndex ? 'slide-in' : 'slide-out'
}`}
>
{item}
</div>
))}
<style jsx>{`
.slide-in {
animation-name: slide-in;
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
.slide-out {
animation-name: slide-out;
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
@keyframes slide-in {
from {
transform: translateY(${activeIndex === 1 ? '100%' : '-100%'});
}
to {
transform: translateY(0);
}
}
@keyframes slide-out {
from {
transform: translateY(0);
}
to {
transform: translateY(${activeIndex === 1 ? '-100%' : '100%'});
}
}
`}</style>
</div>
)
};