import { Y_BUFFER_INDEX } from '@/lib/constants/dom-buffer'; import { getEndIndex, getStartIndex, getViewCount } from '@/lib/calculate/row'; import { Store } from '@/lib/store'; export class ScrollOperator { private readonly store: Store; private scrollYTicking: boolean; constructor(store: Store) { this.store = store; this.scrollYTicking = false; } public scrollY = (scrollTop: number) => { if (!this.scrollYTicking) { requestAnimationFrame(() => { // 静止右键菜单 this.silentEnvironment(); const { startIndex, endIndex, ignore } = this.calculateYStartAndEnd(scrollTop); if (!ignore) { this.changeScrollY(startIndex, endIndex); } this.scrollYTicking = false; }); this.scrollYTicking = true; } }; public scrollX(scrollLeft: number, offsetWidth: number) { this.silentEnvironment(); const { startXLeft, endXLeft } = this.calculateXStartAndEnd(scrollLeft, offsetWidth); this.changeScrollX(startXLeft, endXLeft); } // private async batchScrollY(times: number, step: number, startIndex: number, endIndex: number) { // let startIndexCount = startIndex; // let endIndexCount = endIndex; // for (let i = 0; i < times; i++) { // startIndexCount = startIndexCount + step; // endIndexCount = endIndexCount + step; // console.log(`[test]${startIndexCount}-${endIndexCount}`); // this.changeScrollY(startIndexCount, endIndexCount); // await nextTick(); // } // } private silentEnvironment() { // 如果右键菜单是激活态,需要关闭 // TODO 抽象 rightMenu 的 Operator if (this.store.state.rightMenu.active) { this.store.mutation.inactiveRightMenu(); } } private calculateYStartAndEnd(scrollTop: number) { const viewCount = getViewCount( this.store.state.config.bodyViewHeight, this.store.state.config.rowHeight, ); const startIndex = getStartIndex(scrollTop, this.store.state.config.rowHeight); const endIndex = getEndIndex(startIndex, viewCount); // 上滑动边界 const startBoundary = this.getLastYStartIndex() + Y_BUFFER_INDEX / 2; const endBoundary = this.getLastYEndIndex() - Y_BUFFER_INDEX / 2; // 已经越过边界 if (startIndex < startBoundary || endIndex > endBoundary) { const resultStart = startIndex - Y_BUFFER_INDEX <= 0 ? 0 : startIndex - Y_BUFFER_INDEX; const resultEnd = endIndex + Y_BUFFER_INDEX; return { startIndex: resultStart, endIndex: resultEnd }; } return { ignore: true }; } private getLastYStartIndex() { return this.store.state.virtualScroll.y.startIndex; } private getLastYEndIndex() { return this.store.state.virtualScroll.y.endIndex; } private calculateXStartAndEnd(scrollLeft: number, offsetWidth: number) { const startXLeft = scrollLeft; const endXLeft = scrollLeft + offsetWidth; return { startXLeft, endXLeft, }; } private changeScrollY(startIndex: number, endIndex: number) { this.store.mutation.changeVirtualScroll(startIndex, endIndex); } private changeScrollX(startXLeft: number, endXLeft: number) { this.store.mutation.changeVirtualScrollX(startXLeft, endXLeft); } }