From dd5fbd0fc607aa19e2c466dcfa96e13313fc4931 Mon Sep 17 00:00:00 2001 From: lijinke666 Date: Thu, 22 Feb 2024 14:35:26 +0800 Subject: [PATCH] =?UTF-8?q?fix(scroll):=20=E4=BF=AE=E5=A4=8D=E7=A7=BB?= =?UTF-8?q?=E5=8A=A8=E7=AB=AF=E6=BB=9A=E5=8A=A8=E8=87=B3=E8=BE=B9=E7=BC=98?= =?UTF-8?q?=E6=97=B6=E6=8A=96=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/s2-core/src/facet/base-facet.ts | 48 +++++++++++++++++++++--- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/packages/s2-core/src/facet/base-facet.ts b/packages/s2-core/src/facet/base-facet.ts index ccbda879de..fd14be4e2f 100644 --- a/packages/s2-core/src/facet/base-facet.ts +++ b/packages/s2-core/src/facet/base-facet.ts @@ -1,4 +1,4 @@ -import type { IElement, IGroup, Event as GraphEvent } from '@antv/g-canvas'; +import type { Event as GraphEvent, IElement, IGroup } from '@antv/g-canvas'; import { Group } from '@antv/g-canvas'; import { Wheel, type GestureEvent } from '@antv/g-gesture'; import { interpolateArray } from 'd3-interpolate'; @@ -24,6 +24,7 @@ import { KEY_GROUP_ROW_RESIZE_AREA, OriginEventType, S2Event, + ScrollDirection, ScrollbarPositionType, } from '../common/constant'; import { DEFAULT_PAGE_INDEX } from '../common/constant/pagination'; @@ -74,7 +75,6 @@ import { optimizeScrollXY, translateGroup, } from './utils'; -import type { BaseHeader, BaseHeaderConfig } from './header/base'; export abstract class BaseFacet { // spreadsheet instance @@ -133,6 +133,8 @@ export abstract class BaseFacet { layoutResult?: LayoutResult, ): ViewCellHeights; + protected scrollDirection: ScrollDirection; + protected scrollFrameId: ReturnType = null; get scrollBarTheme() { @@ -183,26 +185,57 @@ export abstract class BaseFacet { this.hScrollBar?.show(); }; + onContainerWheelForMobileCompatibility = () => { + const canvas = this.spreadsheet.getCanvasElement(); + let startY: number; + let endY: number; + + canvas.addEventListener('touchstart', (event) => { + startY = event.touches[0].clientY; + }); + + canvas.addEventListener('touchend', (event) => { + endY = event.changedTouches[0].clientY; + if (endY < startY) { + this.scrollDirection = ScrollDirection.SCROLL_UP; + } else if (endY > startY) { + this.scrollDirection = ScrollDirection.SCROLL_DOWN; + } + }); + }; + onContainerWheel = () => { this.onContainerWheelForPc(); this.onContainerWheelForMobile(); }; + // g-gesture@1.0.1 手指快速往上滚动时, deltaY 有时会为负数, 导致向下滚动时然后回弹, 看起来就像表格在抖动, 需要判断滚动方向, 修正一下. + getMobileWheelDeltaY = (deltaY: number) => { + if (this.scrollDirection === ScrollDirection.SCROLL_UP) { + return Math.max(0, deltaY); + } + + if (this.scrollDirection === ScrollDirection.SCROLL_DOWN) { + return Math.min(0, deltaY); + } + + return deltaY; + }; + onContainerWheelForPc = () => { const canvas = this.spreadsheet.getCanvasElement(); canvas?.addEventListener('wheel', this.onWheel); }; onContainerWheelForMobile = () => { - // mock wheel event fo mobile this.mobileWheel = new Wheel(this.spreadsheet.container); this.mobileWheel.on('wheel', (ev: GestureEvent) => { this.spreadsheet.hideTooltip(); const originEvent = ev.event; - const { deltaX, deltaY, x, y } = ev; - // The coordinates of mobile and pc are three times different - // TODO: 手指快速往上滚动时, deltaY 有时会为负数, 导致向下滚动时然后回弹, 看起来就像表格在抖动, 需要判断滚动方向, next 版本未复现 + const { deltaX, deltaY: defaultDeltaY, x, y } = ev; + const deltaY = this.getMobileWheelDeltaY(defaultDeltaY); + this.onWheel({ ...originEvent, deltaX, @@ -211,6 +244,8 @@ export abstract class BaseFacet { offsetY: y, } as unknown as WheelEvent); }); + + this.onContainerWheelForMobileCompatibility(); }; bindEvents = () => { @@ -930,6 +965,7 @@ export abstract class BaseFacet { const { interaction } = this.spreadsheet.options; if (interaction.overscrollBehavior !== 'auto') { + this.cancelScrollFrame(); this.stopScrollChaining(event); } };