This commit is contained in:
tangly1024
2023-07-15 12:30:53 +08:00
parent a5892cb467
commit dbba49b767
5 changed files with 139 additions and 121 deletions

View File

@@ -1,73 +0,0 @@
import { useCallback, useEffect, useState } from 'react'
import Logo from './Logo'
import { MenuListTop } from './MenuListTop'
import throttle from 'lodash.throttle'
/**
* 顶部导航
* @param {*} param0
* @returns
*/
const Header = props => {
const [isOpen, changeShow] = useState(false)
const [fixedNav, setHeaderBgShow] = useState(false)
const [whiteTitle, setWhiteTitle] = useState(false)
const toggleMenuOpen = () => {
changeShow(!isOpen)
}
// 监听滚动
useEffect(() => {
scrollTrigger()
window.addEventListener('scroll', scrollTrigger)
return () => {
window.removeEventListener('scroll', scrollTrigger)
}
}, [])
const throttleMs = 200
/**
* 根据滚动条,切换导航栏样式
*/
const scrollTrigger = useCallback(throttle(() => {
const scrollS = window.scrollY
const header = document.querySelector('#header')
const postHeader = document.querySelector('#post-bg')
// 导航栏设置 白色背景
if (header && scrollS > 0) {
setHeaderBgShow(true)
setWhiteTitle(false)
} else {
if (postHeader) {
setWhiteTitle(true)
}
setHeaderBgShow(false)
}
}, throttleMs))
return (<>
{/* 头条 */}
<header id='header' className={' h-16 w-full z-20 '}>
<nav className={`${fixedNav ? 'fixed bg-white' : 'relative bg-none'} ${whiteTitle ? 'text-white' : 'text-black'} h-16 top-0 w-full`}>
<div className='flex h-full mx-auto justify-between items-center max-w-[86rem] px-8'>
<div className='flex'>
<Logo {...props} />
</div>
{/* 右侧功能 */}
<div className='mr-1 justify-end items-center '>
<div className='hidden lg:flex'> <MenuListTop {...props} /></div>
<div onClick={toggleMenuOpen} className='w-8 justify-center items-center h-8 cursor-pointer flex lg:hidden'>
{isOpen ? <i className='fas fa-times' /> : <i className='fas fa-bars' />}
</div>
</div>
</div>
</nav>
</header>
</>)
}
export default Header

View File

@@ -6,6 +6,8 @@ import Link from 'next/link'
import { useRouter } from 'next/router'
import { useImperativeHandle, useRef, useState } from 'react'
import CONFIG from '../config'
import { useGlobal } from '@/lib/global'
import { Transition } from '@headlessui/react'
/**
* 顶部英雄区
@@ -15,15 +17,28 @@ import CONFIG from '../config'
* @returns
*/
const Hero = props => {
const { onLoading } = useGlobal()
return (
<div id="hero-wrapper" className='recent-top-post-group w-full overflow-hidden select-none px-5 mb-4'>
<hero id="hero" style={{ zIndex: 1 }} className="recent-post-top rounded-[12px] 2xl:px-5 recent-top-post-group max-w-[86rem] overflow-x-scroll w-full mx-auto flex-row flex-nowrap flex relative space-x-3" >
{/* 左侧banner组 */}
<BannerGroup {...props} />
<Transition
show={!onLoading}
appear={true}
enter="transition ease-in-out duration-700 transform order-first"
enterFrom="opacity-0 -translate-y-16"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-16"
unmount={false}
>
<hero id="hero" style={{ zIndex: 1 }} className="recent-post-top rounded-[12px] 2xl:px-5 recent-top-post-group max-w-[86rem] overflow-x-scroll w-full mx-auto flex-row flex-nowrap flex relative space-x-3" >
{/* 左侧banner组 */}
<BannerGroup {...props} />
{/* 右侧置顶文章组 */}
<TopGroup {...props} />
</hero>
{/* 右侧置顶文章组 */}
<TopGroup {...props} />
</hero>
</Transition>
</div>
)
}
@@ -186,8 +201,8 @@ function TodayCard({ cRef }) {
const [isCoverUp, setIsCoverUp] = useState(true)
/**
* 外部可以调用此方法
*/
* 外部可以调用此方法
*/
useImperativeHandle(cRef, () => {
return {
coverUp: () => {
@@ -197,18 +212,18 @@ function TodayCard({ cRef }) {
})
/**
* 点击更多
* @param {*} e
*/
* 点击更多
* @param {*} e
*/
function handleClickMore(e) {
e.stopPropagation()
setIsCoverUp(false)
}
/**
* 点击卡片跳转的链接
* @param {*} e
*/
* 点击卡片跳转的链接
* @param {*} e
*/
function handleCardClick(e) {
router.push('https://tangly1024.com')
}

View File

@@ -0,0 +1,79 @@
import { useCallback, useEffect, useState } from 'react'
import Logo from './Logo'
import { MenuListTop } from './MenuListTop'
import throttle from 'lodash.throttle'
/**
* 顶部导航
* @param {*} param0
* @returns
*/
const NavBar = props => {
const [isOpen, changeShow] = useState(false)
const [fixedNav, setFixedNav] = useState(false)
const [textWhite, setTextWhite] = useState(false)
const [navBgWhite, setBgWhite] = useState(false)
const toggleMenuOpen = () => {
changeShow(!isOpen)
}
// 监听滚动
useEffect(() => {
scrollTrigger()
window.addEventListener('scroll', scrollTrigger)
return () => {
window.removeEventListener('scroll', scrollTrigger)
}
}, [])
const throttleMs = 200
/**
* 根据滚动条,切换导航栏样式
*/
const scrollTrigger = useCallback(throttle(() => {
const scrollS = window.scrollY
// 导航栏设置 白色背景
if (scrollS <= 0) {
setFixedNav(false)
setBgWhite(false)
// 文章详情页特殊处理
const postHeader = document.querySelector('#post-bg')
if (postHeader) {
setFixedNav(true)
setTextWhite(true)
setBgWhite(false)
}
return
}
// 向下滚动后的导航样式
setFixedNav(true)
setTextWhite(false)
setBgWhite(true)
}, throttleMs))
return (<>
{/* 头条 */}
<nav id='nav' className={`${fixedNav ? 'fixed' : 'relative bg-none'} ${textWhite ? 'text-white ' : 'text-black'} ${navBgWhite ? 'bg-white' : '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'>
<div className='flex'>
<Logo {...props} />
</div>
{/* 右侧功能 */}
<div className='mr-1 justify-end items-center '>
<div className='hidden lg:flex'> <MenuListTop {...props} /></div>
<div onClick={toggleMenuOpen} className='w-8 justify-center items-center h-8 cursor-pointer flex lg:hidden'>
{isOpen ? <i className='fas fa-times' /> : <i className='fas fa-bars' />}
</div>
</div>
</div>
</nav>
</>)
}
export default NavBar

View File

@@ -17,15 +17,15 @@ export default function PostHeader({ post, siteInfo }) {
return (
<div id="post-bg" className="w-full h-[30rem] relative md:flex-shrink-0 overflow-hidden bg-cover bg-center bg-no-repeat z-10">
<header id='article-header-cover' style={{ backdropFilter: 'blur(15px)' }} className="bg-[#0060e0] absolute top-0 w-full h-full py-10 flex justify-center items-center ">
<div id='article-header-cover' style={{ backdropFilter: 'blur(15px)' }} className="bg-[#0060e0] absolute top-0 w-full h-full py-10 flex justify-center items-center ">
<div id='post-cover-wrapper' style={{ filter: 'blur(15px)' }} className='opacity-50 rotate-12 translate-x-12 -mr-60'>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img id='post-cover' style={{ boxShadow: 'box-shadow:110px -130px 300px 60px #4d240c inset' }} className='w-full h-full object-cover opacity-80 min-w-[50vw] min-h-[20rem]' src={headerImage}/>
</div>
<div id='post-info' className='absolute z-10 flex flex-col'>
<div className='mb-3 flex justify-center'>
<div id='post-info' className='absolute z-10 flex flex-col w-full max-w-[86rem] px-5'>
<div className='mb-3 flex justify-start'>
{post.category && <>
<Link href={`/category/${post.category}`} passHref legacyBehavior>
<div className="cursor-pointer px-2 py-1 mb-2 border rounded-sm dark:border-white text-sm font-medium hover:underline duration-200 shadow-text-md text-white">
@@ -36,11 +36,11 @@ export default function PostHeader({ post, siteInfo }) {
</div>
{/* 文章Title */}
<div className="leading-snug font-bold xs:text-4xl sm:text-4xl md:text-5xl md:leading-snug text-4xl shadow-text-md flex justify-center text-center text-white">
<NotionIcon icon={post.pageIcon} className='text-4xl mx-1' />{post.title}
<div className="max-w-5xl font-bold xs:text-4xl sm:text-4xl md:text-4xl md:leading-snug shadow-text-md flex justify-start text-white">
<span><NotionIcon icon={post.pageIcon} className='text-4xl mx-1' /></span>{post.title}
</div>
<section className="flex-wrap shadow-text-md flex text-sm justify-center mt-4 text-white dark:text-gray-400 font-light leading-8">
<section className="flex-wrap shadow-text-md flex text-sm justify-start mt-4 text-white dark:text-gray-400 font-light leading-8">
<div className='flex justify-center dark:text-gray-200 text-opacity-70'>
{post?.type !== 'Page' && (
@@ -79,7 +79,7 @@ export default function PostHeader({ post, siteInfo }) {
<WavesArea />
</header>
</div>
</div>
)
}

View File

@@ -4,7 +4,7 @@ import CommonHead from '@/components/CommonHead'
import { useEffect, useRef } from 'react'
import Footer from './components/Footer'
import SideRight from './components/SideRight'
import Header from './components/Header'
import NavBar from './components/NavBar'
import { useGlobal } from '@/lib/global'
import BLOG from '@/blog.config'
import { isBrowser, loadExternalResource } from '@/lib/utils'
@@ -53,23 +53,8 @@ const LayoutBase = props => {
<CommonHead meta={meta} siteInfo={siteInfo} />
<Style />
{/* 顶部导航 */}
<Header {...props} />
{/* 顶部嵌入 首页放hero文章页放大图 */}
<Transition
show={!onLoading}
appear={true}
enter="transition ease-in-out duration-700 transform order-first"
enterFrom="opacity-0 -translate-y-16"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-16"
unmount={false}
>
{headerSlot}
</Transition>
{/* 顶部嵌入 导航栏首页放hero文章页放文章详情 */}
{headerSlot}
{/* 主区块 */}
<main id="wrapper-outer" className={'flex-grow w-full max-w-[86rem] mx-auto relative px-5'}>
@@ -124,12 +109,13 @@ const LayoutBase = props => {
* @returns
*/
const LayoutIndex = (props) => {
// 博客列表上方嵌入一个 通知横幅和英雄块
const headerSlot = <>
{/* 通知横幅 */}
<NoticeBar />
<Hero {...props} />
</>
const headerSlot = <header>
{/* 顶部导航 */}
<div id='nav-bar-wrapper' className='h-16'><NavBar {...props} /></div>
{/* 通知横幅 */}
<NoticeBar />
<Hero {...props} />
</header>
return <LayoutPostList {...props} headerSlot={headerSlot} />
}
@@ -144,7 +130,7 @@ const LayoutPostList = (props) => {
const slotRight = <SideRight {...props} />
return <LayoutBase {...props} slotRight={slotRight}>
{/* 文章分类条 */}
{/* 文章分类条 */}
<CategoryBar {...props} />
{BLOG.POST_LIST_STYLE === 'page'
@@ -224,8 +210,14 @@ const LayoutSlug = props => {
const targetRef = isBrowser() ? document.getElementById('article-wrapper') : null
// 右侧栏
const slotRight = <SideRight {...props} />
const headerSlot = <header>
{/* 顶部导航 */}
<div id='nav-bar-wrapper'><NavBar {...props} /></div>
<PostHeader {...props} />
</header>
return (
<LayoutBase {...props} headerSlot={<PostHeader {...props} />} showCategory={false} showTag={false} slotRight={slotRight}>
<LayoutBase {...props} headerSlot={headerSlot} showCategory={false} showTag={false} slotRight={slotRight}>
<div className="w-full lg:hover:shadow lg:border rounded-t-xl lg:rounded-xl lg:px-2 lg:py-4 bg-white dark:bg-hexo-black-gray dark:border-black article">
{lock && <ArticleLock validPassword={validPassword} />}
@@ -308,8 +300,13 @@ const Layout404 = props => {
const LayoutCategoryIndex = props => {
const { categoryOptions } = props
const { locale } = useGlobal()
const headerSlot = <header>
{/* 顶部导航 */}
<div id='nav-bar-wrapper' className='h-16'><NavBar {...props} /></div>
</header>
return (
<LayoutBase {...props} className='mt-8'>
<LayoutBase {...props} className='mt-8' headerSlot={headerSlot}>
<div className="text-4xl font-extrabold dark:text-gray-200 mb-5">
{locale.COMMON.CATEGORY}
</div>