Skip to content

fix(drawguess): 画家落笔时不再重建猜词输入框,修复手机键盘反复弹出 - #10

Open
yiyang2001 wants to merge 4 commits into
absswds:masterfrom
yiyang2001:fix/drawguess-mobile-keyboard
Open

yiyang2001 wants to merge 4 commits into
absswds:masterfrom
yiyang2001:fix/drawguess-mobile-keyboard

Conversation

@yiyang2001

@yiyang2001 yiyang2001 commented Oct 19, 2026 •

Copy link
Copy Markdown

改了什么、为什么 / What and why

修复舞台模式下猜词输入框在每次画布更新时被重建,导致手机键盘反复收起和弹出的问题。

此前,每次落笔、撤销、清空或猜词都会广播完整的 game_state。renderStage 随后清空容器并重建整个界面,导致猜词输入框的 DOM 元素被替换,并在 50ms 后重新聚焦。手机上的已输入文字、光标位置及中文输入法的组字状态因此可能丢失。

主要改动:

  • 局部更新渲染:同一回合、同一身份下,原地更新画布、标题、侧栏比分和计时器,保留猜词输入框与画笔工具栏的 DOM 元素。
  • 按需重建界面:仅在换回合、换画家、自己猜对或容器被清空等需要重建的情况下,重新渲染界面。
  • 优化焦点行为:触屏设备不再自动聚焦猜词输入框,避免每回合开始时键盘遮挡画布;桌面端仍在每回合开始时自动聚焦一次。
  • 新增渲染器测试:新增 tests/drawguess-renderer.test.js,在 VM 沙箱中使用真实服务端 playerView 驱动渲染器,覆盖连续落笔时输入框不被替换、不重复聚焦、猜词与比分更新、换回合及画家端同步。

怎么测试的 / How I tested it

  • npm run check
  • npm test
  • 验证连续落笔、撤销、清空及猜词时,输入框不会被不必要地替换。
  • 验证猜词内容、光标及中文输入法组字状态不会因画布更新而丢失。
  • 验证猜词与比分更新、换回合及画家端状态同步。
  • 验证桌面端每回合自动聚焦一次,触屏设备不会自动弹出键盘。
  • 验证游戏可以从大厅正常开局,并在多端操作后保持状态同步。

检查清单 / Checklist

  • npm run check 通过 / passes
  • npm test 通过 / passes
  • 能从大厅开局,操作几步后各端状态保持同步 / The game starts from the lobby and stays in sync after a few moves
  • 新的界面文字及规则说明在 zh 和 en 中都有 / New UI strings and rules text exist in both zh and en
  • 隐藏信息(手牌、身份)经过 playerView / Hidden information (hands, roles) goes through playerView
  • 如有视觉布局改动,附上桌面端和手机端截图 / Attach desktop and mobile screenshots if the layout changes

yiyang2001 and others added 4 commits October 18, 2026 17:51
舞台模式下每一笔/撤销/清空/猜词都会广播完整 game_state,renderStage 每次都
清空容器重建整屏,猜词输入框被替换并在 50ms 后重新 focus:手机键盘随每一笔
收起再弹出,已输入文字、光标和中文输入法组字全部丢失。

- 同一回合、同一身份内只原地更新画布、标题、侧栏比分和计时器,输入框与画笔
  工具栏保持同一个 DOM 元素;换回合、换画家、自己猜对或容器被清空时才重建
- 触屏设备不再自动 focus 猜词框(避免每回合开局键盘挡住画布),桌面端每回合
  仍自动聚焦一次
- 新增 tests/drawguess-renderer.test.js:在 vm 沙箱里用真实服务端 playerView
  驱动渲染器,覆盖连续落笔不替换/不聚焦输入框、猜词与比分、换回合、画家端同步

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
画画卡顿 / 画的东西消失又出现:
- 每一笔都广播带全部笔画的 game_state,画越多越卡;画家的画布还会被落后的
  服务端回传覆盖,刚画的线先消失再出现。笔画/撤销/清空改为广播小增量
  (moveDelta → game_delta),画家画布不再被回传覆盖
- 落笔时只画新增线段,不再每次移动都重绘全部笔画;用 pointer 事件和
  coalesced events
- 画的过程中每 50ms 发送一段,猜的人实时看到;同一笔的段共享 g,撤销按整笔撤
- 笔画统一存在 280×280 逻辑坐标(与 mcp/draw.js 一致),各种屏幕看到的画一样,
  不再在手机上被裁掉
- 服务端清洗笔画数据并限制点数和笔段数;新增大号画笔;输入法组字时回车不提交;
  猜词框 16px 避免 iOS 自动放大

轮数和题库:
- 新增房间设置「轮数」(每人画几次),自动时一局至少 6 回合,2 人默认每人 3 次
- 题库从约 325 词扩充到 619 词,中英一一对应;同一局不重复出词

繁简体:
- 猜词比对做 NFKC、繁转简、忽略大小写空格和常见标点;繁简对照表由 OpenCC 生成
  (games/lib/zh-variants.js,已记入 NOTICE)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
顶部区块为裁剪背景图设了 overflow:hidden,作为 grid 子项最小高度为 0;
大厅高度一旦略小于内容,grid 就把它压到只剩边框,页面看起来从「按风格找局」开始。
lobby-shell 的行改为 max-content,任何区块都不会被压到小于内容。

同时补回手机布局丢掉的 safe-area 内边距,避免内容被状态栏/灵动岛挡住。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
服务器可能暴露在公网,而每条游戏消息都会转发给整个房间;之前没有任何限制
(ws 默认单条 100MB、不限频率),任何人都能开房间灌大消息或刷消息。

- maxPayload 1MB:最大的正常消息是悄悄话模式一次提交整幅画,约 250KB
- 每个连接令牌桶:可突发 200 条,每秒回补 50 条。正常游戏峰值约 20 条/秒
  (你画我猜每 50ms 一段笔画),超出的消息丢弃;持续刷屏则断开(1008)
- tests/ws-limits.test.js:真实服务器验证超大消息被断开、短突发后恢复、
  持续刷屏被断开,以及 20 条/秒画画 4 秒全部送达

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

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.

1 participant