3.0 KiB
3.0 KiB
拼图运行时拖动跟手延迟修复
日期:2026-04-27
1. 背景
拼图玩法运行时已经支持单块拖动、合并块整体拖动与拆分,但实测拖动时拼块会明显慢于手指或鼠标,表现为“拖着走但始终落后半拍”,尤其在移动端更明显。
本次目标只修复前端拖动跟手延迟,不改变拼图交换、合并、拆分、通关等玩法规则。
2. 根因
本轮定位到拖动延迟主要来自两个前端渲染问题:
pointermove每一帧都调用setDragState,导致整个PuzzleRuntimeShell和整盘拼图格子持续重渲染。- 拼块节点默认挂了
transition,拖动过程中的transform会被浏览器当成缓动动画处理,视觉上进一步放大“慢半拍”。
这两个问题叠加后,即使后端或本地运行态裁决没有延迟,前端拖动视觉仍然会滞后。
3. 修复口径
3.1 拖动视觉更新改为直写 DOM
拖动中的位移不再依赖 React state 持续驱动,而是改成:
pointerdown只记录起点和 pointer 信息。- 超过拖动阈值后,只做一次
setDraggingPieceId用于切换拖动态样式。 - 后续
pointermove通过requestAnimationFrame合帧,把位移直接写入目标拼块或合并块容器的style.transform。
这样可以避免每一帧都触发整盘 React 重渲染。
3.2 收紧过渡属性
拼块节点不再使用包含 transform 的通用 transition,只保留颜色、边框、阴影、透明度等非位移动画属性,避免拖动中的 transform 被浏览器插值缓动。
3.3 裁决边界保持不变
本次只优化拖动阶段的视觉反馈:
pointerup后仍然走现有onDragPiece。- 单块交换、拖到合并块后拆分、合并块整体重排,继续沿用当前本地运行态规则。
- 不新增前端本地裁决,不把玩法真相从既有运行态实现中分叉出去。
3.4 点击触觉反馈
移动端用户每次按下可交互拼图片时,需要触发一次短促手机震动:
- 震动触发点放在
pointerdown,让点击选中、按住准备拖动与拖起都有一致手感。 - 同一次按下会话只触发一次震动,后续连续移动不重复震动。
- 使用浏览器标准
navigator.vibrate([12]),不支持震动能力的设备静默跳过。 - 该反馈只属于前端表现层,不影响拖拽落点、交换、合并、拆分与通关判定。
4. 验收标准
- 单块拖动时拼块视觉位置应紧跟手指或鼠标,不再出现明显缓动拖尾。
- 合并块整体拖动时,组容器应同步跟手移动。
- 点击选中与拖动阈值判定仍保持原语义,不因为优化误触发交换。
- 运行时现有结算弹窗、排行榜和下一关入口不受影响。
- 定向测试覆盖拖动提交坐标的行为,并运行编码检查确保中文文档未被写坏。
- 移动端点击拼图片时立即触发一次短震,同一次按下后的连续移动不重复触发。