Skip to content

Commit 86a85c1

Browse files
committed
完善第3天新手引导交互与教程输入锁
- 对齐 Day3 ghost cursor 模拟点击、Galgame 轮盘拖拽与输入框持续高亮流程 - 增加新手教程期间胶囊输入框只读锁,支持跳过、自然结束和生气退出后恢复 - 同步 PC 外置聊天窗口的教程输入锁与工具轮盘控制桥接 - 更新 2-7 天新手教程文档与回归测试覆盖
1 parent 497d95b commit 86a85c1

28 files changed

Lines changed: 1972 additions & 316 deletions

docs/design/avatar-floating-7day-complete-guide-dev.md

Lines changed: 16 additions & 15 deletions
Large diffs are not rendered by default.

docs/design/avatar-floating-day2-screen-voice-guide-dev.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,5 +74,5 @@ UniversalTutorialManager.startAvatarFloatingGuideRound(2)
7474
2. `day2_intro_context` 文案、text key 和 voice key 保持原样。
7575
3. 设置按钮、设置侧边栏、主动搭话入口都有明确高光目标、Ghost Cursor 路径和禁止点击/保存约束。
7676
4. Day 2 主线不触发屏幕分享、主动搭话或用户配置保存。
77-
5. Day 2 主线不发送 `cursorAction: 'wobble'`;普通指认统一使用平滑移动和停留
77+
5. Day 2 主线普通指认统一使用平滑移动和停留
7878
6. Day 2 完成、skip、destroy 和 angry exit 的结束态语义不变。

docs/design/avatar-floating-day3-agent-guide-dev.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@
66

77
## 主线流程
88

9+
进入 Day 3 round 时必须先重置弧形工具栏轮盘:调用 `setCompactToolWheelIndex(0, 'avatar-floating-guide-day3-entry-reset')`,使导入图片按钮 `.compact-input-tool-item-import``data-compact-tool-wheel-slot``0`
10+
911
| 顺序 | scene | 台词 | 高光与 Ghost Cursor |
1012
| --- | --- | --- | --- |
1113
| 1 | `day3_tool_toggle_intro` | 嘻嘻,可别以为这个聊天框只能用来打字哦~ 里面其实偷偷藏了超~多好玩的小惊喜呢!快跟着我一起点开看看,瞧瞧今天能挖出什么有趣的宝贝吧! | 圆角矩形高亮胶囊输入框 `chat-input`;Ghost Cursor 直接显示在胶囊聊天框中间并停留,不从默认点移动进入,不点击、不打开弧形工具菜单。 |
12-
| 2 | `day3_avatar_tools` | 在这个小按钮里,有许多可以和人家互动的小道具呢。 | 持续圆形高亮 `button.send-button-circle.compact-input-tool-toggle`;Ghost Cursor 从胶囊输入框位置以约 1480ms 慢慢平滑移动到工具总按钮 `button.send-button-circle.compact-input-tool-toggle` 并模拟点击;点击动画开始时并行调用 API 打开弧形工具菜单,不打开 Avatar 工具菜单。 |
14+
| 2 | `day3_avatar_tools` | 在这个小按钮里,有许多可以和人家互动的小道具呢。 | 持续圆形高亮 `button.send-button-circle.compact-input-tool-toggle`;Ghost Cursor 从胶囊输入框位置平滑移动到工具总按钮 `button.send-button-circle.compact-input-tool-toggle` 并模拟点击;点击动画开始时并行调用 API 打开弧形工具菜单,不打开 Avatar 工具菜单。 |
1315
| 3 | `day3_avatar_tools_props` | 你可以随时来摸摸我的头,或者给我吃一根甜甜的棒棒糖。如果有时候我不小心做错事了,你也可以用小锤子敲敲我,不过……一定要轻轻的,不能太用力哦。 | 持续圆形高亮 `button.send-button-circle.compact-input-tool-toggle`;Ghost Cursor 平滑移动到 Avatar 互动工具按钮,然后在 Avatar 互动工具按钮处模拟点击并触发 Avatar 互动工具按钮点击事件,显示三个小道具。台词播放完后再次触发 Avatar 互动工具按钮点击事件并隐藏三个小道具。 |
14-
| 4 | `day3_galgame_entry` | 快点开这个【Galgame模式】!进去之后就像我们在进行一场专属的互动大冒险呢。 | 持续圆形高亮 `button.send-button-circle.compact-input-tool-toggle`;Ghost Cursor 先移动到当前 `.compact-input-tool-item-galgame`,切换为点击状态后从轮盘上向下拖约 48px。轮盘按 22px/步累计阈值正向转 2 步,把 Galgame 从 slot 2 转到 slot 0;旋转完成后 Ghost Cursor 平滑移动并停在新的 `.compact-input-tool-item-galgame` 中心。教程期间不强制开启 Galgame。 |
16+
| 4 | `day3_galgame_entry` | 快点开这个【Galgame模式】!进去之后就像我们在进行一场专属的互动大冒险呢。 | 持续圆形高亮 `button.send-button-circle.compact-input-tool-toggle`;Ghost Cursor 先平滑移动到初始 Galgame 按钮位置,然后切换为点击状态并保持,向下移动约 100px。轮盘按 22px/步累计阈值正向转 1 步,把 Galgame 从 slot 2 转到 slot 1;旋转完成后 Ghost Cursor 平滑移动并停在新的 `.compact-input-tool-item-galgame` 中心。教程期间不强制开启 Galgame。 |
1517
| 5 | `day3_galgame_choices` | 你选的每一个对话,都会带我们走向完全未知的惊喜故事,我都等不及啦,快来选一个你最心动的回答吧! | 继续指认 Galgame 入口或真实选项区域;不伪造选择局。 |
16-
| 6 | `day3_wrap` | 今天带你认识的这些功能,其实都是为了让我们在一起的时光变得更有趣呢。 | 收尾前关闭弧形菜单和 Avatar 工具菜单,重新高亮聊天窗|
17-
| 7 | `day3_wrap_ready` | 不管是想摸摸我的头,还是想开启属于我们的故事,我都已经做好准备了。 | 约 70% cue 同步隐藏 Ghost Cursor、清理高光和菜单并播放花瓣。 |
18+
| 6 | `day3_wrap` | 今天带你认识的这些功能,其实都是为了让我们在一起的时光变得更有趣呢。 | 收尾前关闭弧形菜单和 Avatar 工具菜单;圆角矩形高亮胶囊输入框 `chat-input`,Ghost Cursor 平滑移动到胶囊输入框中间并停留|
19+
| 7 | `day3_wrap_ready` | 不管是想摸摸我的头,还是想开启属于我们的故事,我都已经做好准备了。 | 继续保持胶囊输入框圆角高亮和 Ghost Cursor 停留;约 70% cue 同步隐藏 Ghost Cursor、清理高光和菜单并播放花瓣。 |
1820

1921
## 新版 UI 目标
2022

@@ -30,7 +32,8 @@ Avatar 工具按钮和 Galgame 按钮只使用圆形高光;总按钮持续高
3032
Day 3 主线仅使用 `move``click`:需要指认的位置使用 `move`,需要真实触发的位置使用 `click`,不使用左右晃动停留动作。
3133
所有 Day 3 的 `click` scene 都必须在 Ghost Cursor 点击动画开始的同一刻触发真实目标按钮的 `click()`;弧形工具菜单打开继续以工具总按钮点击为准。Avatar 道具菜单的显示/隐藏必须同时调用 `setAvatarToolMenuOpen()` 主机 API 同步 React 状态,因为教程锁定期间 Avatar 按钮可能处于 disabled,浏览器会吞掉 DOM click。React 内三个道具的渲染条件是 `toolMenuOpen && compactInputToolFanOpen`,所以 Avatar 道具菜单 open request 必须同时保证弧形工具菜单仍为 open;教程锁定 `composerDisabled=true` 时不得因为禁用输入而把承载道具菜单的弧形菜单关掉。
3234

33-
PC 外置聊天窗 / 全局 overlay 模式下,`day3_avatar_tools``day3_avatar_tools_props` 的模拟点击只允许由外置聊天窗解析目标后发送一次 `cursor:*:click` patch(`effectDurationMs=420`)到 PC 全局 overlay;首页 Director 不再额外播放第二套 `clickCursorAndWait()` 点击图切换。外置聊天窗回传 `yui_guide_chat_cursor_anchor` 时只回传坐标和 kind,`effect` 必须为空,避免首页收到锚点后再次点击。
35+
PC 外置聊天窗 / 全局 overlay 模式下,`day3_avatar_tools``day3_avatar_tools_props` 的外置聊天窗只负责解析目标并回传 `yui_guide_chat_cursor_anchor`,不得再发送 `cursor:*:click` patch。首页 Director 必须像 Day 2 本地 click 场景一样,在锚点移动完成后调用统一的 `clickCursorAndWait(DEFAULT_CURSOR_CLICK_VISIBLE_MS)` 播放点击图切换;真实 operation 只能通过该 helper 的 `onClickStart` 在点击动画开始时并行触发。外置聊天窗回传 anchor 时只回传坐标和 kind,`effect` 必须为空,避免锚点同步触发第二次点击。PC overlay 移动结束后回传的 anchor 必须带 `settled: true`;首页收到 settled anchor 时只同步内部 cursor 坐标,不再向 PC overlay 发送第二次可见 move。
36+
Day 3 外置 click 场景必须和 Day 2 本地 click 场景使用同一类时序架构:cursor movement helper 负责等待目标位置到达并启动首页 Director 拥有的模拟点击,真实 operation 只能通过该 helper 的 `onClickStart` 在点击动画开始时并行触发;主流程不得绕过 cursor movement 单独定义点击定时器。
3437

3538
PC 端教程 overlay 会把同一条聊天窗指令同时通过 `neko:tutorial-overlay-relay``postMessage.__nekoTutorialOverlayRelay` 中继,并可能携带相同 `timestamp``yui_guide_set_avatar_tool_menu_open` 是幂等状态同步,不是一次性点击事件,必须和 `yui_guide_set_compact_tool_fan_open` 一样跳过消息去重;否则某个较早通道先占用去重 key 后,后续能真正同步 React host 的通道会被挡掉,表现为 Avatar 按钮 click 动画播放了但 `lollipop` / `fist` / `hammer` 三个道具始终不渲染。`yui_guide_click_avatar_tool_button` 仍然要保留去重,避免同一时间戳下双击按钮导致菜单刚打开又被反向收起。
3639

@@ -40,6 +43,7 @@ PC 端教程 overlay 会把同一条聊天窗指令同时通过 `neko:tutorial-o
4043
2. Day 3 不再使用旧 `.composer-emoji-btn` / `.composer-galgame-btn` 作为未打开弧形菜单时的主目标。
4144
3. 弧形菜单通过教程 host request 打开/收起,不依赖放开用户鼠标禁用。
4245
4. Avatar 工具菜单通过既有 `setAvatarToolMenuOpen()` API 打开/关闭,不自动消耗道具。
43-
5. `day3_galgame_entry` 必须用 Ghost Cursor 点击态下拖轮盘,触发 `compactToolWheelRotateRequest(direction=1, stepCount=2)`,让 Galgame 从 slot 2 转到 slot 0;教程期间不强制开启 Galgame,不伪造小游戏或选项。
44-
6. 收尾清理弧形菜单、Avatar 工具菜单、Ghost Cursor 和所有高光。
45-
7. PC 端重启第三天教程时,播放 `day3_avatar_tools_props` 后能在真实聊天窗 DOM 中看到 `#composer-tool-popover-compact`,并且可见 `data-avatar-tool-id` 依次包含 `lollipop``fist``hammer`;同一时刻 Ghost Cursor 只停在 Avatar 互动工具按钮,不移动到三个道具项。
46+
5. `day3_galgame_entry` 必须先让 Ghost Cursor 平滑移动到初始 Galgame 按钮位置,再切换并保持点击态向下拖约 100px;触发 `compactToolWheelRotateRequest(direction=1, stepCount=1)`,让 Galgame 从 slot 2 转到 slot 1;旋转完成后 cursor 再平滑移动并停在新的 Galgame 中心。教程期间不强制开启 Galgame,不伪造小游戏或选项。
47+
6. Day 3 click 场景必须以 Ghost Cursor 到达外置聊天窗回报的目标 anchor 为点击启动条件;Day 3 配置和外置 cursor 指令不得携带显式 `durationMs` / `cursorMoveDurationMs`。若首页开始等待时 anchor 尚未回传,必须等待未来 anchor 或超时,不能因当前没有 move promise 就立即启动模拟点击。
48+
7. 收尾清理弧形菜单、Avatar 工具菜单、Ghost Cursor 和所有高光。
49+
8. PC 端重启第三天教程时,播放 `day3_avatar_tools_props` 后能在真实聊天窗 DOM 中看到 `#composer-tool-popover-compact`,并且可见 `data-avatar-tool-id` 依次包含 `lollipop``fist``hammer`;同一时刻 Ghost Cursor 只停在 Avatar 互动工具按钮,不移动到三个道具项。

docs/design/avatar-floating-day4-companion-guide-dev.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,14 @@ PC 端设置侧边栏、动画设置、锁定按钮、离开/回来按钮和隐
6464

6565
| 顺序 | scene id | 目标 | cursor | operation | 说明 |
6666
| --- | --- | --- | --- | --- | --- |
67-
| 1 | `day4_intro_companion` | `chat-window` | `wobble` || 每日第一句,高亮聊天窗。 |
67+
| 1 | `day4_intro_companion` | `chat-window` | `move` || 每日第一句,高亮聊天窗。 |
6868
| 2 | `day4_chat_settings` | 设置按钮 + `settings-sidepanel:chat-settings` | `click` + `ellipse` | `open-settings` + `show-settings-sidepanel:chat-settings` | 先高亮并点击设置按钮,再转入对话设置侧边栏。 |
6969
| 3 | `day4_model_behavior` | 动画设置按钮 + `settings-sidepanel:animation-settings` | `move` + `ellipse` | `show-settings-sidepanel:animation-settings` | 先收起对话设置侧边栏并高亮动画设置按钮,再转入动画设置侧边栏。 |
7070
| 4 | `day4_gaze_follow` | `#${p}-mouse-tracking-toggle` 外层开关行 | `move` || 高亮并指向跟踪鼠标按钮,不点击。 |
7171
| 5 | `day4_privacy_mode` | 隐私模式按钮 / `#${p}-toggle-proactive-vision` 外层开关行 | `move` || 不展开隐私侧边栏,高亮隐私模式按钮并移动 cursor;本句播完后收起设置弹窗。 |
72-
| 6 | `day4_model_lock` | `#${p}-lock-icon` | `wobble` || 圆形高亮模型锁定按钮,cursor 平滑移动过去并 wobble|
73-
| 7 | `day4_return_home` | `#${p}-btn-goodbye` | `wobble` || 展示回到小猫窝按钮,可 secondary 高亮回来按钮。 |
74-
| 8 | `day4_wrap` | `chat-window` | `wobble` | `cleanup` | 收尾重新高亮聊天窗并播放花瓣转场。 |
72+
| 6 | `day4_model_lock` | `#${p}-lock-icon` | `move` || 圆形高亮模型锁定按钮,cursor 平滑移动过去并 move 并停留|
73+
| 7 | `day4_return_home` | `#${p}-btn-goodbye` | `move` || 展示回到小猫窝按钮,可 secondary 高亮回来按钮。 |
74+
| 8 | `day4_wrap` | `chat-window` | `move` | `cleanup` | 收尾重新高亮聊天窗并播放花瓣转场。 |
7575

7676
Day 4 不保留空台词 scene。8 个 scene 分别对应用户看到的 8 个讲解点:开场、聊天设置、模型行为、视线跟随、主动视觉/隐私模式、模型锁定、回到小猫窝、收尾。
7777

@@ -87,9 +87,9 @@ Day 4 不保留空台词 scene。8 个 scene 分别对应用户看到的 8 个
8787
## 高亮与 Ghost Cursor 时序总则
8888

8989
1. 每段台词进入聊天窗后,先建立本段 spotlight,再播放/继续本段语音;Ghost Cursor 不抢在 spotlight 前出现。
90-
2. 首句 `day4_intro_companion` 是每日通用开场:播放第一句时立即高亮聊天窗,Ghost Cursor 直接出现在聊天窗或输入区中心并 wobble;第一句播放完后清理聊天窗高亮。
90+
2. 首句 `day4_intro_companion` 是每日通用开场:播放第一句时立即高亮聊天窗,Ghost Cursor 直接出现在聊天窗或输入区中心并 move 并停留;第一句播放完后清理聊天窗高亮。
9191
3. 设置类 scene 在台词开始前的准备阶段先打开设置弹窗和对应侧边栏;台词开始时只高亮最终要讲的侧边栏或开关。
92-
4. 非首句 scene 建立 spotlight 后约 220ms 再移动 Ghost Cursor。第一次移动默认约 760ms,tour 后续控件之间约 520ms;移动完成后按本段动作要求 wobble 或停留
92+
4. 非首句 scene 建立 spotlight 后约 220ms 再移动 Ghost Cursor。第一次移动默认约 760ms,tour 后续控件之间约 520ms;移动完成后按本段动作要求 停留
9393
5. 隐私模式台词结束后必须关闭设置弹窗和侧边栏;后续锁定/离开按钮 scene 再把 spotlight 切到对应圆形按钮,随后 Ghost Cursor 平滑移动过去。
9494
6. 收尾花瓣 cue 触发时,Ghost Cursor 和所有高亮必须同步清理,不允许花瓣层上残留指针或 spotlight。
9595

@@ -112,7 +112,7 @@ Day 4 不保留空台词 scene。8 个 scene 分别对应用户看到的 8 个
112112

113113
### 阶段 1:对话节奏设置
114114

115-
- 动作 1:`day4_intro_companion` 播放第一句时立即高亮聊天窗;Ghost Cursor 出现在聊天窗或输入区中心并 wobble。本句全程不移动到任何模型旁按钮,不打开设置。第一句播放完后取消聊天窗高亮,为下一段设置侧边栏高亮让位。
115+
- 动作 1:`day4_intro_companion` 播放第一句时立即高亮聊天窗;Ghost Cursor 出现在聊天窗或输入区中心并 move 并停留。本句全程不移动到任何模型旁按钮,不打开设置。第一句播放完后取消聊天窗高亮,为下一段设置侧边栏高亮让位。
116116
- 台词:“今天,就让我悄悄跟上你的步伐吧。特别希望能在这个温馨的日子里,再多了解你一点点呢。”
117117
- 动作 2:`day4_chat_settings` 台词开始时先用圆形 spotlight 高亮设置按钮;约 220ms 后 Ghost Cursor 平滑移动到设置按钮并播放模拟点击,同时并行调用打开设置 API。设置按钮高光作为 persistent 保持到 `day4_privacy_mode` 台词播放完毕。设置弹窗打开后,spotlight 切到“对话设置”按钮的圆角矩形高亮,Ghost Cursor 平滑移动到该按钮,并调用 `ensureAvatarFloatingSettingsSidePanel('chat-settings')` 展开对话设置侧边栏。随后取消“对话设置”按钮主高亮,把圆角矩形主高亮切到对话设置侧边栏;Ghost Cursor 在侧边栏范围内做椭圆运动直至本句台词播放完毕。全程只指认,不改值。
118118
- 台词:“在这里可以决定我回复你的长短,还能决定要不要让我带上可爱的表情,或者在人家唠叨的时候打断我哦!都可以调到让你最舒服的节奏”
@@ -134,17 +134,17 @@ Day 4 不保留空台词 scene。8 个 scene 分别对应用户看到的 8 个
134134

135135
### 阶段 5:模型锁定
136136

137-
- 动作:`day4_model_lock` 进入准备阶段时先执行 `cleanupBefore`,确保设置弹窗、侧边栏和设置按钮 persistent 高光已经清理;台词开始时圆形高亮锁定按钮 `#${p}-lock-icon`,约 220ms 后 Ghost Cursor 平滑移动到锁定按钮并 wobble。全程不点击、不真的锁定。
137+
- 动作:`day4_model_lock` 进入准备阶段时先执行 `cleanupBefore`,确保设置弹窗、侧边栏和设置按钮 persistent 高光已经清理;台词开始时圆形高亮锁定按钮 `#${p}-lock-icon`,约 220ms 后 Ghost Cursor 平滑移动到锁定按钮并 move 并停留。全程不点击、不真的锁定。
138138
- 台词:“总是小心不触碰到、把我点歪吗?那就快把我牢牢固定在当前的位置吧!开启锁定后,我就哪儿也不去,乖乖在原地陪着你~
139139

140140
### 阶段 6:回到小猫窝
141141

142-
- 动作:`day4_return_home` 台词开始时 primary spotlight 高亮“请她离开”按钮 `#${p}-btn-goodbye`,“回来”按钮 `#${p}-btn-return` 只在真实可见时作为 secondary 高亮。Ghost Cursor 平滑移动到离开按钮并 wobble,再移动到回来按钮并 wobble;全程不点击、不真的让 Yui 离开。
142+
- 动作:`day4_return_home` 台词开始时 primary spotlight 高亮“请她离开”按钮 `#${p}-btn-goodbye`,“回来”按钮 `#${p}-btn-return` 只在真实可见时作为 secondary 高亮。Ghost Cursor 平滑移动到离开按钮并 move 并停留,再移动到回来按钮并 move 并停留;全程不点击、不真的让 Yui 离开。
143143
- 台词:“如果你现在需要专注、担心我打扰的话,可以让我暂时回到小猫窝里收起来哦!等你想我的时候,随时一键就能把我重新唤回身边,喵呜~
144144

145145
### 阶段 7:低打扰收尾
146146

147-
- 动作:`day4_wrap` 准备阶段先执行 `cleanup`,关闭设置弹窗、侧边栏、临时菜单和跨窗口高亮,恢复干净状态。收尾台词开始时重新高亮聊天窗;约 220ms 后 Ghost Cursor 从上一位置平滑移动到聊天窗或输入区附近,默认移动约 760ms,移动完成后 wobble。外置聊天窗模式同步高亮独立聊天窗并使用外置 cursor。台词约 70% 处触发与 Day 1 相同的花瓣转场 cue,触发瞬间同步隐藏 Ghost Cursor、清理内置/外置聊天窗高亮、action/persistent/secondary/extra/virtual spotlight;转场结束后写入 Day 4 完成态。
147+
- 动作:`day4_wrap` 准备阶段先执行 `cleanup`,关闭设置弹窗、侧边栏、临时菜单和跨窗口高亮,恢复干净状态。收尾台词开始时重新高亮聊天窗;约 220ms 后 Ghost Cursor 从上一位置平滑移动到聊天窗或输入区附近,默认移动约 760ms,移动完成后 move 并停留。外置聊天窗模式同步高亮独立聊天窗并使用外置 cursor。台词约 70% 处触发与 Day 1 相同的花瓣转场 cue,触发瞬间同步隐藏 Ghost Cursor、清理内置/外置聊天窗高亮、action/persistent/secondary/extra/virtual spotlight;转场结束后写入 Day 4 完成态。
148148
- 台词:“真正舒服的陪伴才不是一刻不停地粘着主人呢~ 而是懂得什么时候该悄悄靠近抓抓你的衣角撒个娇,什么时候该安安静静地趴在一旁,用目光默默守候着主人喵~
149149

150150
## 剧场后聊天窗支线

0 commit comments

Comments
 (0)