From 3d2846faf6e5be64c152e81e714096c3d8a1750e Mon Sep 17 00:00:00 2001 From: linyuan Date: Thu, 21 Dec 2023 12:09:34 +0800 Subject: [PATCH] feature: container scroll --- .../v3/components/day/EventWrapper.tsx | 9 ++- src/view/LCalendar/v3/utils/selector.ts | 80 +++++++++++++++---- 2 files changed, 70 insertions(+), 19 deletions(-) diff --git a/src/view/LCalendar/v3/components/day/EventWrapper.tsx b/src/view/LCalendar/v3/components/day/EventWrapper.tsx index e3f461b..c46dee1 100644 --- a/src/view/LCalendar/v3/components/day/EventWrapper.tsx +++ b/src/view/LCalendar/v3/components/day/EventWrapper.tsx @@ -77,7 +77,7 @@ export const EventWrapperComponent = function(props:React.PropsWithChildren { + + // 整个滚动区域的容器 + const scrollRect = scrollContainer?.getBoundingClientRect() + // 日历所有天数的容器 + const daysRect = daysContainer?.getBoundingClientRect() + const timestamp = getTimeFromPoint( scrollRect, daysRect, @@ -119,7 +125,6 @@ export const EventWrapperComponent = function(props:React.PropsWithChildren { // scrollContainer.scrollTop = scrollContainer.scrollTop + 10 diff --git a/src/view/LCalendar/v3/utils/selector.ts b/src/view/LCalendar/v3/utils/selector.ts index 446a193..38910bf 100644 --- a/src/view/LCalendar/v3/utils/selector.ts +++ b/src/view/LCalendar/v3/utils/selector.ts @@ -13,37 +13,80 @@ function addDocEventListener(type:string, fn:(arg:any)=>any) { export class Selector { public listeners: IAny - constructor() { + public scrollContainer:HTMLDivElement + public coordinate:ICoordinates|null + public timerID:NodeJS.Timeout|null + constructor(scrollContainer:HTMLDivElement) { this.handleInitialEvent = this.handleInitialEvent.bind(this) this.handleTerminatingEvent = this.handleTerminatingEvent.bind(this) + this.updateParentScroll = this.updateParentScroll.bind(this) + this.clearUpdateParentScroll = this.clearUpdateParentScroll.bind(this) this.listeners = Object.create(null) - } - updateParentScroll(scrollContainer:HTMLDivElement, coordinate:ICoordinates) { - const scrollRect = scrollContainer.getBoundingClientRect() - const scrollRectTop = scrollRect.top - const scrollRectBottom = scrollRect.bottom - const mousePointY = coordinate.clientY - const distanceTop = mousePointY - scrollRectTop - const distanceBottom = scrollRectBottom - mousePointY - const thresholdDistance = 20 - if (distanceTop < thresholdDistance) { - scrollContainer.scrollTop = scrollContainer.scrollTop - 10 - } else if (distanceBottom < thresholdDistance) { - scrollContainer.scrollTop = scrollContainer.scrollTop + 10 + this.scrollContainer = scrollContainer // 记录滚动的容器元素 + this.coordinate = null // 记录鼠标坐标点 + this.timerID = null + } + updateParentScroll() { + const scrollContainer = this.scrollContainer + const coordinate = this.coordinate + if (!coordinate || !scrollContainer) { + return } + setTimeout(() => { + + const scrollRect = scrollContainer.getBoundingClientRect() + const scrollRectTop = scrollRect.top + const scrollRectBottom = scrollRect.bottom + const mousePointY = coordinate.clientY + + const distanceTop = mousePointY - scrollRectTop + const distanceBottom = scrollRectBottom - mousePointY + + // 距离上下边界的阈值 + const thresholdDistance = 20 + // 设置每一帧的滚动速度 + const scrollSpeed = 2 + + // 之前距离滚动框未滚动的位置 + const beforeScrollTop = scrollContainer.scrollTop + if (distanceTop < thresholdDistance) { + // 向上滚动 + scrollContainer.scrollTop = beforeScrollTop - scrollSpeed + // 新的坐标点 + coordinate.clientY -= beforeScrollTop - scrollContainer.scrollTop + } else if (distanceBottom < thresholdDistance) { + // 向下滚动 + scrollContainer.scrollTop = beforeScrollTop + scrollSpeed + coordinate.clientY += scrollContainer.scrollTop - beforeScrollTop + } + this.emit('selecting', coordinate) + }) - console.log( - distanceTop, distanceBottom, distanceBottom + distanceTop - ) // document.addEventListener('click', (e) => { // console.log('pageY:', e.pageY) // console.log('clientY:', e.clientY) // }) } + addUpdateParentScroll() { + if (this.timerID !== null) { + return + } + this.timerID = setInterval(() => { + requestAnimationFrame(this.updateParentScroll) + }) + } + clearUpdateParentScroll() { + if (this.timerID === null) { + return + } + clearInterval(this.timerID) + this.timerID = null + this.coordinate = null + } removeEndListener() { return } @@ -85,12 +128,15 @@ export class Selector { } handleMoveEvent(e:React.MouseEvent) { const selectingCoordinates = getEventCoordinates(e) + this.coordinate = selectingCoordinates + this.addUpdateParentScroll() this.emit('selecting', selectingCoordinates) } handleTerminatingEvent(e:React.MouseEvent) { this.removeMoveListener() this.removeEndListener() const endCoordinates = getEventCoordinates(e) + this.clearUpdateParentScroll() this.emit('select', endCoordinates) } }