You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
7.6 KiB
7.6 KiB
RFC 137: 角色-对白关联表单交互设计
状态:Draft
创建日期:2026-01-30
参考:ui-ux-pro-max UX 准则、现有 StoryboardDialogue 数据模型
1. 背景与目标
1.1 当前问题
- 分镜表单的「角色」栏仅为 Badge 列表 + ResourcePicker,与对白无关联
- 对白目前存在「拍摄描述」字段(原 dialogue),与角色无一一对应
- 后端
StoryboardDialogue已支持characterName,一个分镜可有多个角色各自的对白
1.2 设计目标
- 关联展示:选择角色后自动展示该角色在此分镜下的对白
- 可编辑:对白以输入框形式,支持手动编辑
- 初始化:AI 解析剧本时自动提取对白并关联角色
- 数据一致:与
StoryboardDialogue模型对齐(characterName + text)
2. 数据结构扩展
2.1 DraftShot 扩展
// client/src/types/storyboard.ts
export interface DraftShot {
// ... 现有字段
characters: string[];
/** 角色-对白映射。key=角色名, value=该角色在此分镜的对白文本 */
characterDialogues: Record<string, string>;
}
- 保留
characters:角色列表(用于 ResourcePicker、智能提取) - 新增
characterDialogues:按角色存储对白 - 原
dialogue已改为拍摄描述,不再用于对白
2.2 AI 解析输出
剧本 AI 解析时需输出分镜维度的角色对白,例如:
{
"storyboards": [
{
"characters": ["唐僧", "孙悟空"],
"characterDialogues": {
"唐僧": "如何才能救你?",
"孙悟空": "山顶有张符咒,撕下来就行!"
}
}
]
}
3. 交互设计(基于 ui-ux-pro-max)
3.1 推荐方案:角色-对白行式布局
布局:左侧角色名,右侧对白输入框,一行一个角色。类似两列表格,结构清晰、一目了然。
┌────────────┬──────────────────────────────────────┐
│ 角色 │ 对白 │
├────────────┼──────────────────────────────────────┤
│ 孙悟空 │ [师父!救救我!______________] │
│ 唐僧 │ [如何才能救你?______________] │
│ 土地公公 │ [(无对白)________________] │ ← 此分镜该角色无对白
└────────────┴──────────────────────────────────────┘
无对白角色:该角色在此分镜无台词时,输入框为空,placeholder 显示「(此分镜无对白)」;用户仍可手动输入,以补充漏提取的对白。
| UX 准则 | 应用 |
|---|---|
| Form Labels | 表头「角色」「对白」;每行角色名作为该行输入框的语义标签 |
| Input Affordance | 输入框有 border/background,明显可编辑 |
| Empty States | 无对白时 placeholder:「(此分镜无对白)」;无角色时显示「添加角色后可编辑对白」 |
| Input Affordance | 输入框保持可编辑,便于用户补充 |
优点:
- 结构简单,无展开/收起,学习成本低
- 所有角色及对白同屏可见,便于对照修改
- 天然支持「有/无对白」:无对白即为空输入框
4. 视觉与交互规格
4.1 角色-对白行式结构
┌─────────────────────────────────────────────────────────────┐
│ [User图标] 角色 [+ 添加角色] │
├──────────────────┬──────────────────────────────────────────┤
│ 孙悟空 [×] │ ┌────────────────────────────────────┐ │
│ │ │ 师父!救救我! │ │
│ │ └────────────────────────────────────┘ │
├──────────────────┼──────────────────────────────────────────┤
│ 唐僧 [×] │ ┌────────────────────────────────────┐ │
│ │ │ 如何才能救你? │ │
│ │ └────────────────────────────────────┘ │
├──────────────────┼──────────────────────────────────────────┤
│ 土地公公 [×] │ ┌────────────────────────────────────┐ │
│ │ │ (此分镜无对白) │ │ ← placeholder
│ │ └────────────────────────────────────┘ │
└──────────────────┴──────────────────────────────────────────┘
- 左列:角色名 + 删除按钮
[×],固定宽度(如 100–120px) - 右列:单行 Input 或可折叠的 Textarea(短对白用 Input,长对白可展开)
- 添加角色:顶部 ResourcePicker,与现有一致
4.2 状态与反馈
| 状态 | 表现 |
|---|---|
| 有对白 | 输入框显示对白内容 |
| 无对白 | 输入框为空,placeholder:「(此分镜无对白)」 |
| 无角色 | 空状态:「添加角色后可编辑对白」 |
| 焦点 | 输入框 focus:ring-2 focus:ring-brand |
4.3 输入框类型建议
- 默认:单行
Input(type="text"),适合大多对白 - 可选:对白较长时使用
Textarea,或支持点击展开为多行
4.4 无障碍
- 每行用
role="row"或aria-labelledby关联角色名与输入框 - 输入框有
aria-label或通过<label>关联角色名
5. 数据流与回调
5.1 新增 Props
// ScreenplayStoryboardForm
onCharacterDialogueChange: (characterName: string, text: string) => void;
5.2 父组件职责
- 维护
characterDialogues - 智能提取时写入 AI 返回的角色对白
- 同步到
contentmarkdown(若需持久化到现有格式)
6. 实现步骤建议
- 扩展
DraftShot类型,增加characterDialogues - 实现
CharacterDialogueRow组件(角色名 + 对白 Input,一行一个) - 在表单中替换原
ResourceSelector(仅角色部分)为角色列表 + 行式对白区 - 连接
onCharacterDialogueChange与父组件 state - 更新 ScreenplayParseDialog 的解析与初始化逻辑,写入
characterDialogues - 添加空状态、加载态(若 AI 提取异步)的 UI
7. 参考资料
client/src/mocks/storyboard-dialogues.ts:StoryboardDialogue 结构client/src/mocks/storyboards.ts:分镜 dialogues 示例(多角色对白)- ui-ux-pro-max:Forms、Feedback、Animation、Accessibility 相关准则