Add logo.png to public. Add vertical and horizontal scroll prevent. Fix scroll index out-of-bounds bug. #21

Merged
FatttSnake merged 5 commits from FatttSnake into dev 2023-09-22 16:33:13 +08:00
5 changed files with 144 additions and 55 deletions

BIN
public/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View File

@@ -7,7 +7,7 @@
z-index: 1; z-index: 1;
width: 100%; width: 100%;
height: 70px; height: 70px;
min-width: 900px; min-width: 500px;
background-color: white; background-color: white;
border: { border: {
bottom: { bottom: {

View File

@@ -4,16 +4,20 @@ import '@/assets/css/components/common/hide-scrollbar.scss'
interface HideScrollbarProps interface HideScrollbarProps
extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> { extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
isPreventScroll?: boolean isPreventScroll?: boolean
isPreventVerticalScroll?: boolean
isPreventHorizontalScroll?: boolean
isShowVerticalScrollbar?: boolean
isShowHorizontalScrollbar?: boolean
} }
export interface HideScrollbarElement { export interface HideScrollbarElement {
scrollTo(x: number, y: number): void scrollTo(x: number, y: number, smooth?: boolean): void
scrollX(x: number): void scrollX(x: number, smooth?: boolean): void
scrollY(y: number): void scrollY(y: number, smooth?: boolean): void
scrollLeft(length: number): void scrollLeft(length: number, smooth?: boolean): void
scrollRight(length: number): void scrollRight(length: number, smooth?: boolean): void
scrollUp(length: number): void scrollUp(length: number, smooth?: boolean): void
scrollDown(length: number): void scrollDown(length: number, smooth?: boolean): void
getX(): number getX(): number
getY(): number getY(): number
addEventListenerWithType<K extends keyof HTMLElementEventMap>( addEventListenerWithType<K extends keyof HTMLElementEventMap>(
@@ -40,19 +44,79 @@ export interface HideScrollbarElement {
const HideScrollbar = forwardRef<HideScrollbarElement, HideScrollbarProps>((props, ref) => { const HideScrollbar = forwardRef<HideScrollbarElement, HideScrollbarProps>((props, ref) => {
const rootRef = useRef<HTMLDivElement>(null) const rootRef = useRef<HTMLDivElement>(null)
const lastTouchPosition = useRef<{ x: number; y: number }>({ x: -1, y: -1 })
const [verticalScrollbarWidth, setVerticalScrollbarWidth] = useState(0) const [verticalScrollbarWidth, setVerticalScrollbarWidth] = useState(0)
const [horizontalScrollbarWidth, setHorizontalScrollbarWidth] = useState(0) const [horizontalScrollbarWidth, setHorizontalScrollbarWidth] = useState(0)
const { isPreventScroll, ..._props } = props const {
const handleDefaultWheel = useCallback((event: WheelEvent) => { isPreventScroll,
if (!event.altKey && !event.ctrlKey) { isPreventVerticalScroll,
event.preventDefault() isPreventHorizontalScroll,
} isShowVerticalScrollbar,
}, []) isShowHorizontalScrollbar,
..._props
} = props
const handleDefaultTouchmove = useCallback((event: TouchEvent) => { const handleDefaultWheel = useCallback(
event.preventDefault() (event: WheelEvent) => {
}, []) if (!event.altKey && !event.ctrlKey) {
if (isPreventScroll) {
event.preventDefault()
return
}
if (isPreventVerticalScroll && !event.shiftKey && !event.deltaX) {
event.preventDefault()
return
}
if (isPreventHorizontalScroll && (event.shiftKey || !event.deltaY)) {
event.preventDefault()
return
}
}
},
[isPreventScroll, isPreventHorizontalScroll, isPreventVerticalScroll]
)
const handleDefaultTouchStart = useCallback(
(event: TouchEvent) => {
if (event.touches.length !== 1 || isPreventScroll) {
lastTouchPosition.current = { x: -1, y: -1 }
return
}
const { clientX, clientY } = event.touches[0]
lastTouchPosition.current = { x: clientX, y: clientY }
},
[isPreventScroll]
)
const handleDefaultTouchmove = useCallback(
(event: TouchEvent) => {
event.preventDefault()
if (event.touches.length !== 1 || isPreventScroll) {
lastTouchPosition.current = { x: -1, y: -1 }
return
}
const { clientX, clientY } = event.touches[0]
if (!isPreventVerticalScroll) {
rootRef.current?.scrollTo({
top: rootRef.current?.scrollTop + (lastTouchPosition.current.y - clientY),
behavior: 'instant'
})
}
if (!isPreventHorizontalScroll) {
rootRef.current?.scrollTo({
left: rootRef.current?.scrollLeft + (lastTouchPosition.current.x - clientX),
behavior: 'instant'
})
}
lastTouchPosition.current = { x: clientX, y: clientY }
},
[isPreventScroll, isPreventHorizontalScroll, isPreventVerticalScroll]
)
const handleDefaultClickMiddleMouseButton = useCallback((event: MouseEvent) => { const handleDefaultClickMiddleMouseButton = useCallback((event: MouseEvent) => {
if (event.button === 1) { if (event.button === 1) {
@@ -60,70 +124,88 @@ const HideScrollbar = forwardRef<HideScrollbarElement, HideScrollbarProps>((prop
} }
}, []) }, [])
const handleDefaultKeyDown = (event: KeyboardEvent) => { const handleDefaultKeyDown = useCallback(
if ( (event: KeyboardEvent) => {
[ if (
'ArrowUp', isPreventScroll &&
'ArrowDown', [
'ArrowLeft', 'ArrowUp',
'ArrowRight', 'ArrowDown',
' ', 'ArrowLeft',
'', 'ArrowRight',
'PageUp', ' ',
'PageDown', '',
'Home', 'PageUp',
'End' 'PageDown',
].find((value) => value === event.key) 'Home',
) { 'End'
event.preventDefault() ].find((value) => value === event.key)
} ) {
} event.preventDefault()
}
if (
isPreventVerticalScroll &&
['ArrowUp', 'ArrowDown', ' ', '', 'PageUp', 'PageDown', 'Home', 'End'].find(
(value) => value === event.key
)
) {
event.preventDefault()
}
if (
isPreventHorizontalScroll &&
['ArrowLeft', 'ArrowRight'].find((value) => value === event.key)
) {
event.preventDefault()
}
},
[isPreventScroll, isPreventHorizontalScroll, isPreventVerticalScroll]
)
useImperativeHandle<HideScrollbarElement, HideScrollbarElement>( useImperativeHandle<HideScrollbarElement, HideScrollbarElement>(
ref, ref,
() => { () => {
return { return {
scrollTo(x, y) { scrollTo(x, y, smooth?: boolean) {
rootRef.current?.scrollTo({ rootRef.current?.scrollTo({
left: x, left: x,
top: y, top: y,
behavior: 'smooth' behavior: smooth === false ? 'instant' : 'smooth'
}) })
}, },
scrollX(x) { scrollX(x, smooth?: boolean) {
rootRef.current?.scrollTo({ rootRef.current?.scrollTo({
left: x, left: x,
behavior: 'smooth' behavior: smooth === false ? 'instant' : 'smooth'
}) })
}, },
scrollY(y) { scrollY(y, smooth?: boolean) {
rootRef.current?.scrollTo({ rootRef.current?.scrollTo({
top: y, top: y,
behavior: 'smooth' behavior: smooth === false ? 'instant' : 'smooth'
}) })
}, },
scrollLeft(length) { scrollLeft(length, smooth?: boolean) {
rootRef.current?.scrollTo({ rootRef.current?.scrollTo({
left: rootRef.current?.scrollLeft - length, left: rootRef.current?.scrollLeft - length,
behavior: 'smooth' behavior: smooth === false ? 'instant' : 'smooth'
}) })
}, },
scrollRight(length) { scrollRight(length, smooth?: boolean) {
rootRef.current?.scrollTo({ rootRef.current?.scrollTo({
left: rootRef.current?.scrollLeft + length, left: rootRef.current?.scrollLeft + length,
behavior: 'smooth' behavior: smooth === false ? 'instant' : 'smooth'
}) })
}, },
scrollUp(length) { scrollUp(length, smooth?: boolean) {
rootRef.current?.scrollTo({ rootRef.current?.scrollTo({
top: rootRef.current?.scrollTop - length, top: rootRef.current?.scrollTop - length,
behavior: 'smooth' behavior: smooth === false ? 'instant' : 'smooth'
}) })
}, },
scrollDown(length) { scrollDown(length, smooth?: boolean) {
rootRef.current?.scrollTo({ rootRef.current?.scrollTo({
top: rootRef.current?.scrollTop + length, top: rootRef.current?.scrollTop + length,
behavior: 'smooth' behavior: smooth === false ? 'instant' : 'smooth'
}) })
}, },
getX() { getX() {
@@ -185,8 +267,11 @@ const HideScrollbar = forwardRef<HideScrollbarElement, HideScrollbarProps>((prop
}, 1000) }, 1000)
window.addEventListener('resize', windowResizeListener()) window.addEventListener('resize', windowResizeListener())
if (isPreventScroll) { if (isPreventScroll || isPreventVerticalScroll || isPreventHorizontalScroll) {
rootRef.current?.addEventListener('wheel', handleDefaultWheel, { passive: false }) rootRef.current?.addEventListener('wheel', handleDefaultWheel, { passive: false })
rootRef.current?.addEventListener('touchstart', handleDefaultTouchStart, {
passive: false
})
rootRef.current?.addEventListener('touchmove', handleDefaultTouchmove, { rootRef.current?.addEventListener('touchmove', handleDefaultTouchmove, {
passive: false passive: false
}) })
@@ -194,6 +279,7 @@ const HideScrollbar = forwardRef<HideScrollbarElement, HideScrollbarProps>((prop
rootRef.current?.addEventListener('keydown', handleDefaultKeyDown) rootRef.current?.addEventListener('keydown', handleDefaultKeyDown)
} else { } else {
rootRef.current?.removeEventListener('wheel', handleDefaultWheel) rootRef.current?.removeEventListener('wheel', handleDefaultWheel)
rootRef.current?.removeEventListener('touchstart', handleDefaultTouchStart)
rootRef.current?.removeEventListener('touchmove', handleDefaultTouchmove) rootRef.current?.removeEventListener('touchmove', handleDefaultTouchmove)
rootRef.current?.removeEventListener('mousedown', handleDefaultClickMiddleMouseButton) rootRef.current?.removeEventListener('mousedown', handleDefaultClickMiddleMouseButton)
rootRef.current?.removeEventListener('keydown', handleDefaultKeyDown) rootRef.current?.removeEventListener('keydown', handleDefaultKeyDown)
@@ -204,9 +290,13 @@ const HideScrollbar = forwardRef<HideScrollbarElement, HideScrollbarProps>((prop
} }
}, [ }, [
handleDefaultClickMiddleMouseButton, handleDefaultClickMiddleMouseButton,
handleDefaultKeyDown,
handleDefaultTouchStart,
handleDefaultTouchmove, handleDefaultTouchmove,
handleDefaultWheel, handleDefaultWheel,
isPreventScroll isPreventHorizontalScroll,
isPreventScroll,
isPreventVerticalScroll
]) ])
return ( return (

View File

@@ -61,7 +61,7 @@ const Home: React.FC = () => {
} }
const handleScrollDown = () => { const handleScrollDown = () => {
if (currentContent >= content.length) { if (currentContent >= content.length - 1) {
return return
} }
handleScrollToContent(currentContent + 1)() handleScrollToContent(currentContent + 1)()
@@ -72,7 +72,7 @@ const Home: React.FC = () => {
} }
const handleWheel = (event: React.WheelEvent) => { const handleWheel = (event: React.WheelEvent) => {
if (event.altKey || event.ctrlKey) { if (event.altKey || event.ctrlKey || event.shiftKey) {
return return
} }
@@ -124,7 +124,6 @@ const Home: React.FC = () => {
if (event.key === 'ArrowDown') { if (event.key === 'ArrowDown') {
handleScrollDown() handleScrollDown()
} }
console.log(content.length)
} }
const content = [ const content = [

View File

@@ -43,7 +43,7 @@ const MainFramework: React.FC = () => {
return ( return (
<> <>
<HideScrollbar ref={hideScrollbarRef} isPreventScroll={preventScroll}> <HideScrollbar ref={hideScrollbarRef} isPreventVerticalScroll={preventScroll}>
<div className={'body'}> <div className={'body'}>
<header className={'nav' + (navbarHidden ? ' hide' : '')}> <header className={'nav' + (navbarHidden ? ' hide' : '')}>
<a className={'logo'} href={'https://fatweb.top'}> <a className={'logo'} href={'https://fatweb.top'}>