diff --git a/src/assets/css/components/common/hide-scrollbar.scss b/src/assets/css/components/common/hide-scrollbar.scss index 3aaa0b8..a7f1b6c 100644 --- a/src/assets/css/components/common/hide-scrollbar.scss +++ b/src/assets/css/components/common/hide-scrollbar.scss @@ -24,6 +24,7 @@ position: absolute; z-index: 1000; opacity: .5; + touch-action: none; .box { position: relative; diff --git a/src/components/common/HideScrollbar.tsx b/src/components/common/HideScrollbar.tsx index 9799a81..ded9e3b 100644 --- a/src/components/common/HideScrollbar.tsx +++ b/src/components/common/HideScrollbar.tsx @@ -133,16 +133,19 @@ const HideScrollbar = forwardRef((prop const rootRef = useRef(null) const contentRef = useRef(null) const wheelListenerRef = useRef<(event: WheelEvent) => void>(() => undefined) - const lastClickPositionRef = useRef({ x: -1, y: -1 }) + const lastScrollbarClickPositionRef = useRef({ x: -1, y: -1 }) + const lastScrollbarTouchPositionRef = useRef({ x: -1, y: -1 }) const lastTouchPositionRef = useRef({ x: -1, y: -1 }) const [verticalScrollbarWidth, setVerticalScrollbarWidth] = useState(0) const [verticalScrollbarLength, setVerticalScrollbarLength] = useState(100) const [verticalScrollbarPosition, setVerticalScrollbarPosition] = useState(0) const [verticalScrollbarOnClick, setVerticalScrollbarOnClick] = useState(false) + const [verticalScrollbarOnTouch, setVerticalScrollbarOnTouch] = useState(false) const [horizontalScrollbarWidth, setHorizontalScrollbarWidth] = useState(0) const [horizontalScrollbarLength, setHorizontalScrollbarLength] = useState(100) const [horizontalScrollbarPosition, setHorizontalScrollbarPosition] = useState(0) const [horizontalScrollbarOnClick, setHorizontalScrollbarOnClick] = useState(false) + const [horizontalScrollbarOnTouch, setHorizontalScrollbarOnTouch] = useState(false) const { isPreventScroll, @@ -244,7 +247,7 @@ const HideScrollbar = forwardRef((prop return (event: React.MouseEvent) => { switch (eventFlag) { case 'down': - lastClickPositionRef.current = { x: event.clientX, y: event.clientY } + lastScrollbarClickPositionRef.current = { x: event.clientX, y: event.clientY } switch (scrollbarFlag) { case 'vertical': setVerticalScrollbarOnClick(true) @@ -264,7 +267,7 @@ const HideScrollbar = forwardRef((prop rootRef.current?.scrollTo({ top: rootRef.current?.scrollTop + - ((event.clientY - lastClickPositionRef.current.y) / + ((event.clientY - lastScrollbarClickPositionRef.current.y) / (rootRef.current?.clientHeight ?? 1)) * (contentRef.current?.clientHeight ?? 0), behavior: 'instant' @@ -274,13 +277,13 @@ const HideScrollbar = forwardRef((prop rootRef.current?.scrollTo({ left: rootRef.current?.scrollLeft + - ((event.clientX - lastClickPositionRef.current.x) / + ((event.clientX - lastScrollbarClickPositionRef.current.x) / (rootRef.current?.clientWidth ?? 1)) * (contentRef.current?.clientWidth ?? 0), behavior: 'instant' }) } - lastClickPositionRef.current = { + lastScrollbarClickPositionRef.current = { x: event.clientX, y: event.clientY } @@ -288,6 +291,65 @@ const HideScrollbar = forwardRef((prop } } + const handleScrollbarTouchEvent = (eventFlag: string, scrollbarFlag: string) => { + return (event: React.TouchEvent) => { + switch (eventFlag) { + case 'start': + if (event.touches.length !== 1) { + return + } + lastScrollbarTouchPositionRef.current = { + x: event.touches[0].clientX, + y: event.touches[0].clientY + } + switch (scrollbarFlag) { + case 'vertical': + setVerticalScrollbarOnTouch(true) + break + case 'horizontal': + setHorizontalScrollbarOnTouch(true) + break + } + break + case 'end': + case 'cancel': + setVerticalScrollbarOnTouch(false) + setHorizontalScrollbarOnTouch(false) + break + case 'move': + if (event.touches.length !== 1) { + return + } + if (verticalScrollbarOnTouch) { + rootRef.current?.scrollTo({ + top: + rootRef.current?.scrollTop + + ((event.touches[0].clientY - + lastScrollbarClickPositionRef.current.y) / + (rootRef.current?.clientHeight ?? 1)) * + (contentRef.current?.clientHeight ?? 0), + behavior: 'instant' + }) + } + if (horizontalScrollbarOnTouch) { + rootRef.current?.scrollTo({ + left: + rootRef.current?.scrollLeft + + ((event.touches[0].clientX - + lastScrollbarClickPositionRef.current.x) / + (rootRef.current?.clientWidth ?? 1)) * + (contentRef.current?.clientWidth ?? 0), + behavior: 'instant' + }) + } + lastScrollbarClickPositionRef.current = { + x: event.touches[0].clientX, + y: event.touches[0].clientY + } + } + } + } + const handleDefaultScroll = () => { setVerticalScrollbarPosition( ((rootRef.current?.scrollTop ?? 0) / (contentRef.current?.clientHeight ?? 1)) * 100 @@ -358,10 +420,17 @@ const HideScrollbar = forwardRef((prop onMouseMove={ !isPreventScroll ? handleScrollbarMouseEvent('move', 'all') : undefined } + onTouchMove={ + !isPreventScroll ? handleScrollbarTouchEvent('move', 'all') : undefined + } onMouseUp={!isPreventScroll ? handleScrollbarMouseEvent('up', 'all') : undefined} + onTouchEnd={!isPreventScroll ? handleScrollbarTouchEvent('end', 'all') : undefined} onMouseLeave={ !isPreventScroll ? handleScrollbarMouseEvent('leave', 'all') : undefined } + onTouchCancel={ + !isPreventScroll ? handleScrollbarTouchEvent('cancel', 'all') : undefined + } >
((prop ? handleScrollbarMouseEvent('down', 'vertical') : undefined } + onTouchStart={ + !isPreventScroll && !isPreventVerticalScroll + ? handleScrollbarTouchEvent('start', 'vertical') + : undefined + } />
@@ -420,6 +494,11 @@ const HideScrollbar = forwardRef((prop ? handleScrollbarMouseEvent('down', 'horizontal') : undefined } + onTouchStart={ + !isPreventScroll && !isPreventHorizontalScroll + ? handleScrollbarTouchEvent('start', 'horizontal') + : undefined + } /> diff --git a/src/pages/MainFramework.tsx b/src/pages/MainFramework.tsx index 51221c0..d2b9da6 100644 --- a/src/pages/MainFramework.tsx +++ b/src/pages/MainFramework.tsx @@ -65,7 +65,6 @@ const MainFramework: React.FC = () => { ref={hideScrollbarRef} isPreventVerticalScroll={preventScroll} isShowHorizontalScrollbar={true} - isShowVerticalScrollbar={true} >