Skip to content

fix: 修复歌词手动滚动边界未正确限制可见范围 - #343

Open
K-Blaaaack wants to merge 1 commit into
SPlayer-Dev:devfrom
K-Blaaaack:fix/333-lyric-scroll-bound
Open

K-Blaaaack wants to merge 1 commit into
SPlayer-Dev:devfrom
K-Blaaaack:fix/333-lyric-scroll-bound

Conversation

@K-Blaaaack

Copy link
Copy Markdown
Contributor

改动类型

  • 缺陷修复(fix)

是否包含破坏性变更

  • 否

改动说明

修复 #333:手动滚动歌词时首尾边界未按实际可见范围限制。

两个引擎的缺陷都在各自包内部(lyric-dom 0.2.0 / @applemusic-like-lyrics/core 0.6.0,均为当前最新版),因此在本仓库接入层修复:

  • physics 引擎(lyric-dom):applyUserScroll 累加 userScrollOffset 时没有任何上限,滚轮可持续把歌词推出首尾范围,出现大面积空白。
  • AMLL 引擎:滚动引擎本身有钳制,但边界按全部歌词行的几何尺寸计算;开启「隐藏已播放行」后被隐藏的行只是透明度置为 1e-4,仍占布局高度,因此仍可滚入这片不可见区域。

新增 useLyricScrollBound,在两个歌词容器的捕获阶段拦截滚轮 / 触摸手势,按屏内实际可见的行推导当前姿态下允许的滚动区间,越界的增量直接吞掉。捕获阶段先于引擎的目标阶段监听器执行,因此能有效拦截且与监听器注册顺序无关。

为避免与引擎渲染循环争抢,测量过程不调用 getBoundingClientRect / getComputedStyle(两者都会强制同步布局),改为解析引擎逐帧写入的内联 translateY,行元素与行高在一次手势内缓存复用,单次滚动事件零布局开销。

关联 Issue

Closes #333

测试情况

自动化检查(全部通过):

  • tsc -p tsconfig.node.json + vue-tsc -p tsconfig.web.json:通过
  • eslint .:0 error(2 个既有 warning 来自未改动的 src/settings/categories/player.spec.ts)
  • prettier --check .:通过
  • vitest run:30 文件 / 212 用例通过
  • tsx --test(node 侧):35 用例通过

新增用例覆盖两个引擎:首行贴顶时向上滚动被拦截、底部有余量时向下滚动被放行、内容不高于容器时锁死、AMLL 开启「隐藏已播放行」后不越界。另有一条回归防护断言持续滚动时 getBoundingClientRect / getComputedStyle 调用为 0,并已反向验证该断言在逐行测量的旧实现下会失败。

手动验证:在 Linux 开发模式下运行应用、播放带歌词歌曲实际滚动确认(该过程中发现并修复了本改动引入的一处滚动掉帧问题)。原 issue 环境为 Windows,未在 Windows / macOS 复测;边界逻辑与平台无关,仍建议在 Windows 上确认一次。

自查清单

  • 本 PR 只包含一个主要功能 / 修复,没有夹带无关改动
  • 已在本地完整测试通过;AI 生成的代码同样自行测试并审阅过,未做未经验证的提交
  • 已运行格式化,并确认 typecheck / lint 通过
  • 未手写 native/*/index.d.ts(本改动不涉及原生模块)
  • 已向 dev 分支提交

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: 歌词手动滚动边界未正确限制可见歌词范围

1 participant