From 2749843b0b0eaa15f4ace0f273d863d5621854d2 Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Mon, 13 Mar 2023 11:50:04 +0800 Subject: [PATCH 1/2] animation and style --- lib/utils.js | 27 ++++++ pages/_app.js | 5 +- themes/example/components/BlogListScroll.js | 2 +- themes/hexo/LayoutBase.js | 33 ++++--- themes/hexo/components/Announcement.js | 2 +- themes/hexo/components/BlogPostCard.js | 90 ++++--------------- themes/hexo/components/BlogPostCardInfo.js | 79 ++++++++++++++++ themes/hexo/components/BlogPostListPage.js | 2 +- themes/hexo/components/Header.js | 64 +++++++------ themes/hexo/components/LatestPostsGroup.js | 8 +- themes/hexo/components/TopNav.js | 66 +++++++------- themes/matery/LayoutBase.js | 21 ++--- themes/matery/LayoutSlug.js | 20 ++--- themes/matery/components/BlogPostCard.js | 11 ++- themes/matery/components/BlogPostListPage.js | 2 +- .../matery/components/BlogPostListScroll.js | 20 ++--- themes/matery/components/Header.js | 44 ++++----- themes/matery/components/TopNav.js | 9 +- themes/simple/components/ArticleInfo.js | 4 +- 19 files changed, 281 insertions(+), 228 deletions(-) create mode 100644 themes/hexo/components/BlogPostCardInfo.js diff --git a/lib/utils.js b/lib/utils.js index 0b997696..3e3831e5 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -124,3 +124,30 @@ export const getListByPage = function (list, pageIndex, pageSize) { pageIndex * pageSize ) } + +/** + * 判断是否移动设备 + */ +export const isMobile = () => { + let isMobile = false + if (!isBrowser()) { + return isMobile + } + if (!isMobile && navigator.userAgentData.mobile) { + isMobile = true + } + + if (!isMobile && (/Mobi|Android|iPhone/i.test(navigator.userAgent))) { + isMobile = true + } + + if (/Android|iPhone|iPad|iPod/i.test(navigator.platform)) { + isMobile = true + } + + if (typeof window.orientation !== 'undefined') { + isMobile = true + } + + return isMobile +} diff --git a/pages/_app.js b/pages/_app.js index 41feba71..e6749281 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -24,6 +24,7 @@ import smoothscroll from 'smoothscroll-polyfill' import AOS from 'aos' import 'aos/dist/aos.css' // You can also use for styles +import { isMobile } from '@/lib/utils' const Ackee = dynamic(() => import('@/components/Ackee'), { ssr: false }) const Gtag = dynamic(() => import('@/components/Gtag'), { ssr: false }) @@ -57,7 +58,9 @@ const MyApp = ({ Component, pageProps }) => { useEffect(() => { AOS.init() - smoothscroll.polyfill() + if (isMobile()) { + smoothscroll.polyfill() + } }, []) return ( diff --git a/themes/example/components/BlogListScroll.js b/themes/example/components/BlogListScroll.js index d70e4bc5..b3d7f3f0 100644 --- a/themes/example/components/BlogListScroll.js +++ b/themes/example/components/BlogListScroll.js @@ -78,5 +78,5 @@ export const BlogListScroll = props => { - ); + ) } diff --git a/themes/hexo/LayoutBase.js b/themes/hexo/LayoutBase.js index 701daa71..066c4404 100644 --- a/themes/hexo/LayoutBase.js +++ b/themes/hexo/LayoutBase.js @@ -1,6 +1,6 @@ import CommonHead from '@/components/CommonHead' -import { useEffect, useState } from 'react' - +import { useCallback, useEffect, useState } from 'react' +import throttle from 'lodash.throttle' import Footer from './components/Footer' import JumpToTopButton from './components/JumpToTopButton' import SideRight from './components/SideRight' @@ -42,23 +42,20 @@ const LayoutBase = props => { ) const { onLoading } = useGlobal() + const throttleMs = 200 + const scrollListener = useCallback(throttle(() => { + const targetRef = document.getElementById('wrapper') + const clientHeight = targetRef?.clientHeight + const scrollY = window.pageYOffset + const fullHeight = clientHeight - window.outerHeight + let per = parseFloat(((scrollY / fullHeight) * 100).toFixed(0)) + if (per > 100) per = 100 + const shouldShow = scrollY > 100 && per > 0 - const scrollListener = () => { - requestAnimationFrame(() => { - const targetRef = document.getElementById('wrapper') - const clientHeight = targetRef?.clientHeight - const scrollY = window.pageYOffset - const fullHeight = clientHeight - window.outerHeight - let per = parseFloat(((scrollY / fullHeight) * 100).toFixed(0)) - if (per > 100) per = 100 - const shouldShow = scrollY > 100 && per > 0 - - if (shouldShow !== showFloatButton) { - switchShow(shouldShow) - } - // changePercent(per) - }) - } + if (shouldShow !== showFloatButton) { + switchShow(shouldShow) + } + }, throttleMs)) useEffect(() => { document.addEventListener('scroll', scrollListener) return () => document.removeEventListener('scroll', scrollListener) diff --git a/themes/hexo/components/Announcement.js b/themes/hexo/components/Announcement.js index 391fd3a8..677cb467 100644 --- a/themes/hexo/components/Announcement.js +++ b/themes/hexo/components/Announcement.js @@ -7,7 +7,7 @@ const Announcement = ({ post, className }) => { const { locale } = useGlobal() if (post?.blockMap) { return
-
+
{locale.COMMON.ANNOUNCEMENT}
{post && (
diff --git a/themes/hexo/components/BlogPostCard.js b/themes/hexo/components/BlogPostCard.js index e3e3d7ff..eeb6e0b2 100644 --- a/themes/hexo/components/BlogPostCard.js +++ b/themes/hexo/components/BlogPostCard.js @@ -1,98 +1,39 @@ import BLOG from '@/blog.config' import Link from 'next/link' import React from 'react' -import TagItemMini from './TagItemMini' import CONFIG_HEXO from '../config_hexo' -import NotionPage from '@/components/NotionPage' +import { BlogPostCardInfo } from './BlogPostCardInfo' // import Image from 'next/image' -const BlogPostCard = ({ post, showSummary, siteInfo }) => { +const BlogPostCard = ({ index, post, showSummary, siteInfo }) => { const showPreview = CONFIG_HEXO.POST_LIST_PREVIEW && post.blockMap if (post && !post.page_cover && CONFIG_HEXO.POST_LIST_COVER_DEFAULT) { post.page_cover = siteInfo?.pageCover } const showPageCover = CONFIG_HEXO.POST_LIST_COVER && post?.page_cover + const delay = (index % 2) * 200 + return (
-
- + {/* 文字内容 */} +
- {post.title} + - - -
- - - - {post.date?.start_date || post.lastEditedTime} - - -
- - {(!showPreview || showSummary) && !post.results && ( -

- {post.summary} -

- )} - - {/* 搜索结果 */} - {post.results && ( -

- {post.results.map(r => ( - {r} - ))} -

- )} - - {showPreview && ( -
- -
- )} - -
- - - - {post.category} - - -
-
- {' '} - {post.tagItems.map(tag => ( - - ))} -
-
-
+ {/* 图片封面 */} {showPageCover && !showPreview && post?.page_cover && (
@@ -100,6 +41,7 @@ const BlogPostCard = ({ post, showSummary, siteInfo }) => { {post.title} {/*
diff --git a/themes/hexo/components/BlogPostCardInfo.js b/themes/hexo/components/BlogPostCardInfo.js new file mode 100644 index 00000000..65e8c246 --- /dev/null +++ b/themes/hexo/components/BlogPostCardInfo.js @@ -0,0 +1,79 @@ +import BLOG from '@/blog.config' +import NotionPage from '@/components/NotionPage' +import Link from 'next/link' +import TagItemMini from './TagItemMini' + +export const BlogPostCardInfo = ({ post, showPreview, showSummary }) => { + return <> + {/* 标题 */} + + + {post.title} + + + + {/* 日期 */} +
+ + + + {post.date?.start_date || post.lastEditedTime} + + +
+ + {/* 摘要 */} + {(!showPreview || showSummary) && !post.results && ( +

+ {post.summary} +

+ )} + + {/* 搜索结果 */} + {post.results && ( +

+ {post.results.map(r => ( + {r} + ))} +

+ )} + {/* 预览 */} + {showPreview && ( +
+ +
+ )} + + {/* 分类标签 */} +
+ + + + {post.category} + + +
+
+ {' '} + {post.tagItems.map(tag => ( + + ))} +
+
+
+ +} diff --git a/themes/hexo/components/BlogPostListPage.js b/themes/hexo/components/BlogPostListPage.js index ff4249d7..9a2c68f7 100644 --- a/themes/hexo/components/BlogPostListPage.js +++ b/themes/hexo/components/BlogPostListPage.js @@ -22,7 +22,7 @@ const BlogPostListPage = ({ page = 1, posts = [], postCount, siteInfo }) => { {/* 文章列表 */}
{posts.map(post => ( - + ))}
{showPagination && } diff --git a/themes/hexo/components/Header.js b/themes/hexo/components/Header.js index 81b2fe2e..c15153f3 100644 --- a/themes/hexo/components/Header.js +++ b/themes/hexo/components/Header.js @@ -1,8 +1,9 @@ // import Image from 'next/image' -import { useEffect, useState } from 'react' +import { useCallback, useEffect, useState } from 'react' import Typed from 'typed.js' import CONFIG_HEXO from '../config_hexo' import NavButtonGroup from './NavButtonGroup' +import throttle from 'lodash.throttle' let wrapperTop = 0 let windowTop = 0 @@ -53,6 +54,34 @@ const Header = props => { }) } + const autoScrollEnd = () => { + if (autoScroll) { + windowTop = window.scrollY + autoScroll = false + } + } + const throttleMs = 200 + const scrollTrigger = useCallback(throttle(() => { + if (screen.width <= 768) { + return + } + + const scrollS = window.scrollY + // 自动滚动 + if ((scrollS > windowTop) & (scrollS < window.innerHeight) && !autoScroll + ) { + autoScroll = true + window.scrollTo({ top: wrapperTop, behavior: 'smooth' }) + autoScrollEnd() + } + if ((scrollS < windowTop) && (scrollS < window.innerHeight) && !autoScroll) { + autoScroll = true + window.scrollTo({ top: 0, behavior: 'smooth' }) + autoScrollEnd() + } + windowTop = scrollS + }, throttleMs)) + return (