mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
feat(board nav): update mobile navbar animation on scroll
This commit is contained in:
@@ -27,25 +27,11 @@
|
|||||||
position: fixed;
|
position: fixed;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
animation-name: stickyMenuAnimation;
|
transition: top 0.3s ease-in-out;
|
||||||
animation-duration: 1s;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
animation-fill-mode: both;
|
|
||||||
animation-play-state: paused;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes stickyMenuAnimation {
|
|
||||||
0% {
|
|
||||||
top: 0px;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
top: -50px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.boardNavMobile .pageJump a {
|
.boardNavMobile .pageJump a {
|
||||||
color: var(--button-text-color-mobile);
|
color: var(--button-text-color-mobile);
|
||||||
text-decoration: var(--button-text-decoration-mobile);
|
text-decoration: var(--button-text-decoration-mobile);
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
|
import { useEffect, useState } from 'react';
|
||||||
import { useAccountComment } from '@plebbit/plebbit-react-hooks';
|
import { useAccountComment } from '@plebbit/plebbit-react-hooks';
|
||||||
import { Link, useLocation, useNavigate, useParams } from 'react-router-dom';
|
import { Link, useLocation, useNavigate, useParams } from 'react-router-dom';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { isAllView, isCatalogView, isSubscriptionsView } from '../../lib/utils/view-utils';
|
import { isAllView, isCatalogView, isSubscriptionsView } from '../../lib/utils/view-utils';
|
||||||
import styles from './board-nav.module.css';
|
import styles from './board-nav.module.css';
|
||||||
import useDefaultSubplebbits, { categorizeSubplebbits, useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits';
|
import useDefaultSubplebbits, { categorizeSubplebbits, useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits';
|
||||||
|
import { debounce } from 'lodash';
|
||||||
|
|
||||||
const BoardNavDesktop = () => {
|
const BoardNavDesktop = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -67,8 +69,23 @@ const BoardNavMobile = ({ subplebbitAddress }: { subplebbitAddress: string }) =>
|
|||||||
</select>
|
</select>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// navbar animation on scroll
|
||||||
|
const [prevScrollPos, setPrevScrollPos] = useState(0);
|
||||||
|
const [visible, setVisible] = useState(true);
|
||||||
|
useEffect(() => {
|
||||||
|
const debouncedHandleScroll = debounce(() => {
|
||||||
|
const currentScrollPos = window.scrollY;
|
||||||
|
setVisible(prevScrollPos > currentScrollPos || currentScrollPos < 10);
|
||||||
|
setPrevScrollPos(currentScrollPos);
|
||||||
|
}, 50);
|
||||||
|
|
||||||
|
window.addEventListener('scroll', debouncedHandleScroll);
|
||||||
|
|
||||||
|
return () => window.removeEventListener('scroll', debouncedHandleScroll);
|
||||||
|
}, [prevScrollPos, visible]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.boardNavMobile} id='sticky-menu'>
|
<div className={styles.boardNavMobile} id='sticky-menu' style={{ top: visible ? 0 : '-23px' }}>
|
||||||
<div className={styles.boardSelect}>
|
<div className={styles.boardSelect}>
|
||||||
<strong>{t('board')}</strong>
|
<strong>{t('board')}</strong>
|
||||||
{boardSelect}
|
{boardSelect}
|
||||||
@@ -81,52 +98,6 @@ const BoardNavMobile = ({ subplebbitAddress }: { subplebbitAddress: string }) =>
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// sticky menu animation
|
|
||||||
// will trigger more than once with hot reloading during development
|
|
||||||
if (!window.STICKY_MENU_SCROLL_LISTENER) {
|
|
||||||
window.STICKY_MENU_SCROLL_LISTENER = true;
|
|
||||||
|
|
||||||
const scrollRange = 50; // the animation css px range in stickyMenuAnimation, must also edit css animation 100%: {top}
|
|
||||||
let currentScrollInRange = 0,
|
|
||||||
previousScroll = 0;
|
|
||||||
|
|
||||||
window.addEventListener('scroll', () => {
|
|
||||||
// find difference between current and last scroll position
|
|
||||||
const currentScroll = window.scrollY;
|
|
||||||
const scrollDifference = currentScroll - previousScroll;
|
|
||||||
previousScroll = currentScroll;
|
|
||||||
|
|
||||||
// find new current scroll in range
|
|
||||||
const previousScrollInRange = currentScrollInRange;
|
|
||||||
currentScrollInRange += scrollDifference;
|
|
||||||
if (currentScrollInRange > scrollRange) {
|
|
||||||
currentScrollInRange = 0;
|
|
||||||
} else if (currentScrollInRange < 0) {
|
|
||||||
currentScrollInRange = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// fix mobile overflow scroll bug
|
|
||||||
if (currentScroll <= 0) {
|
|
||||||
currentScrollInRange = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// no changes
|
|
||||||
if (currentScrollInRange === previousScrollInRange) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the menu element
|
|
||||||
const menuElement = document.getElementById('sticky-menu');
|
|
||||||
if (!menuElement) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// control progress of the animation using negative animation-delay (0 to -1s)
|
|
||||||
const animationPercent = currentScrollInRange / scrollRange;
|
|
||||||
menuElement.style.animationDelay = animationPercent * -1 + 's';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const BoardNav = () => {
|
const BoardNav = () => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any });
|
const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any });
|
||||||
|
|||||||
Reference in New Issue
Block a user