diff --git a/app/src/layout/dock/Outline.ts b/app/src/layout/dock/Outline.ts index 9169a0949..508d64fed 100644 --- a/app/src/layout/dock/Outline.ts +++ b/app/src/layout/dock/Outline.ts @@ -36,9 +36,6 @@ export class Outline extends Model { public blockId: string; public isPreview: boolean; private preFilterExpandIds: string[] | null = null; - private scrollAnimationId: number | null = null; - private scrollLastFrameTime: number = 0; - private scrollCurrentFPS: number = 60; constructor(options: { app: App, @@ -377,68 +374,11 @@ export class Outline extends Model { }); return; } - // 检查是否在滚动边界区域 if (moveEvent.clientY < contentRect.top + Constants.SIZE_SCROLL_TB || moveEvent.clientY > contentRect.bottom - Constants.SIZE_SCROLL_TB) { - // 如果还没有开始滚动,则开始持续滚动 - if (!this.scrollAnimationId) { - const scrollDirection = moveEvent.clientY < contentRect.top + Constants.SIZE_SCROLL_TB ? -1 : 1; - this.scrollLastFrameTime = performance.now(); - let scrollFrameCount = 0; - - const scrollAnimation = (currentTime: number) => { - if (!this.scrollAnimationId) { - return; - } - - // 每隔 20 帧重新计算一次帧率 - if (scrollFrameCount % 20 === 0) { - const deltaTime = currentTime - this.scrollLastFrameTime; - this.scrollLastFrameTime = currentTime; - // 计算过去 20 帧的平均帧率 - this.scrollCurrentFPS = deltaTime > 0 ? (20 * 1000) / deltaTime : 60; - } - scrollFrameCount++; - - // 基于当前帧率计算滚动步长,确保等效于 60fps 时的 16px/帧 - const baseScrollStep = 16; - const targetFPS = 60; - const scrollStep = baseScrollStep * (targetFPS / this.scrollCurrentFPS); - - this.element.scroll({ - top: this.element.scrollTop + scrollStep * scrollDirection - }); - - // 使用 requestAnimationFrame 继续动画 - this.scrollAnimationId = requestAnimationFrame(scrollAnimation); - }; - - // 检查浏览器是否支持 requestAnimationFrame - if (typeof requestAnimationFrame !== "undefined") { - this.scrollAnimationId = requestAnimationFrame(scrollAnimation); - } else { - // 回退到 setTimeout 方法 - const scrollInterval = 16; // 约 60fps - const scrollStep = 16; // 每次滚动的距离 - - const scrollAnimationFallback = () => { - this.element.scroll({ - top: this.element.scrollTop + scrollStep * scrollDirection - }); - this.scrollAnimationId = window.setTimeout(scrollAnimationFallback, scrollInterval); - }; - this.scrollAnimationId = window.setTimeout(scrollAnimationFallback, scrollInterval); - } - } - } else { - // 离开滚动区域时停止滚动 - if (this.scrollAnimationId) { - if (typeof cancelAnimationFrame !== "undefined") { - cancelAnimationFrame(this.scrollAnimationId); - } else { - clearTimeout(this.scrollAnimationId); - } - this.scrollAnimationId = null; - } + this.element.scroll({ + top: this.element.scrollTop + (moveEvent.clientY < contentRect.top + Constants.SIZE_SCROLL_TB ? -Constants.SIZE_SCROLL_STEP : Constants.SIZE_SCROLL_STEP), + behavior: "smooth" + }); } selectItem = hasClosestByClassName(moveEvent.target as HTMLElement, "b3-list-item") as HTMLElement; if (!selectItem || selectItem.tagName !== "LI" || selectItem.style.position === "fixed") { @@ -470,15 +410,6 @@ export class Outline extends Model { documentSelf.onselect = null; ghostElement?.remove(); item.style.opacity = ""; - // 清理滚动动画 - if (this.scrollAnimationId) { - if (typeof cancelAnimationFrame !== "undefined") { - cancelAnimationFrame(this.scrollAnimationId); - } else { - clearTimeout(this.scrollAnimationId); - } - this.scrollAnimationId = null; - } if (!selectItem) { selectItem = this.element.querySelector(".dragover__top, .dragover__bottom, .dragover"); }