Appearance
Feature: Quick Look 节点预览
Goal
用户可以在画布中通过空格键快速预览任意节点的内容(图片、视频、富文本),无需进入节点编辑模式,类似 macOS Quick Look 体验。
Behavior Constraints
约束 1:触发预览
Pre: 画布中存在至少一个节点处于 hover 或 selected 状态,焦点不在任何文本输入元素内 Behavior: 用户按下空格键,系统打开全屏预览浮层,展示该节点的媒体内容 Post: 预览浮层可见,画布交互被阻断(不可拖拽/缩放)
约束 2:关闭预览
Pre: 预览浮层已打开 Behavior: 用户按下空格键 或 Esc 键 或 点击遮罩区域 Post: 预览浮层关闭,画布恢复正常交互
约束 3:按节点类型展示内容
Pre: 预览浮层已打开 Behavior: 根据节点类型展示对应内容 — Image 节点展示图片(支持缩放拖拽)、Video 节点播放视频(支持进度条和倍速)、Text 节点渲染富文本 Post: 内容正确展示在预览浮层中
约束 4:空内容节点
Pre: 目标节点没有可预览内容(ImageNode 无 images、VideoNode 无 videos、TextNode 无 text) Behavior: 按空格键不触发预览 Post: 无变化
约束 5:焦点冲突避免
Pre: 焦点在 Prompt 输入框、富文本编辑器或其他文本输入元素内 Behavior: 空格键正常输入空格字符,不触发预览 Post: 无变化
约束 6:多节点切换
Pre: 预览浮层已打开,画布中有多个包含内容的节点 Behavior: 用户按左/右方向键可在有内容的节点间切换预览 Post: 预览内容切换到前/后一个有内容的节点
约束 7:hover 优先级
Pre: 存在一个 selected 节点和一个不同的 hovered 节点 Behavior: 按空格键时预览 hovered 节点(与 macOS Quick Look 行为一致:指针所在优先) Post: 预览浮层展示 hover 节点的内容
State Machine
Acceptance Criteria
- [~] AC-01:hover 节点有内容时按空格键,打开全屏预览浮层
- [~] AC-02:selected 节点有内容时按空格键,打开全屏预览浮层
- [~] AC-03:同时存在 hover 和 selected 节点时,预览 hover 节点
- [x] AC-04:Image 节点预览展示图片(
images[0]) - [x] AC-05:Video 节点预览播放视频(
videos[0]) - [x] AC-06:Text 节点预览渲染富文本(
text) - [x] AC-07:节点无可预览内容时,按空格键不触发预览
- [~] AC-08:焦点在文本输入元素内时,空格键不触发预览
- [x] AC-09:预览状态下按空格键关闭预览
- [~] AC-10:预览状态下按 Esc 关闭预览
- [~] AC-11:预览状态下点击遮罩关闭预览
- [x] AC-12:预览状态下按左右方向键切换到前/后一个有内容的节点
- [x] AC-13:切换到边界时(第一个/最后一个),不循环,方向键无效
- [~] AC-14:图片预览支持缩放和拖拽查看
- [~] AC-15:视频预览支持进度条拖动和倍速控制
BDD Scenarios
gherkin
Feature: Quick Look 节点预览
# Maps to AC-01, AC-04
Scenario: hover 图片节点时按空格预览
Given 画布中有一个 Image 节点,images 包含一张图片
When 用户将鼠标悬浮在该节点上
And 用户按下空格键
Then 全屏预览浮层出现,展示该图片
# Maps to AC-02, AC-05
Scenario: selected 视频节点时按空格预览
Given 画布中有一个 Video 节点已被选中,videos 包含一个视频
When 用户按下空格键
Then 全屏预览浮层出现,播放该视频
# Maps to AC-06
Scenario: 预览文本节点
Given 画布中有一个 Text 节点已被选中,text 包含富文本内容
When 用户按下空格键
Then 全屏预览浮层出现,渲染该富文本
# Maps to AC-03
Scenario: hover 和 selected 同时存在时优先 hover
Given 画布中有一个已选中的 Image 节点 A 和一个正在 hover 的 Video 节点 B
When 用户按下空格键
Then 预览浮层展示节点 B 的视频
# Maps to AC-07
Scenario: 空内容节点不触发预览
Given 画布中有一个 Image 节点未上传图片(images 为空)
When 用户悬浮该节点并按空格键
Then 预览浮层不出现
# Maps to AC-08
Scenario: 输入框内按空格不触发预览
Given 用户焦点在某节点的 Prompt 输入框内
When 用户按下空格键
Then 空格字符正常输入,预览不触发
# Maps to AC-09, AC-10, AC-11
Scenario: 关闭预览的三种方式
Given 预览浮层已打开
When 用户按下空格键
Then 预览浮层关闭
When 用户重新打开预览后按 Esc
Then 预览浮层关闭
When 用户重新打开预览后点击遮罩区域
Then 预览浮层关闭
# Maps to AC-12, AC-13
Scenario: 方向键切换预览节点
Given 画布中有 3 个有内容的节点 A B C,当前预览节点 B
When 用户按右方向键
Then 预览切换到节点 C
When 用户再次按右方向键
Then 预览不变(已到末尾)
When 用户按左方向键
Then 预览切换到节点 B
# Maps to AC-14
Scenario: 图片预览支持缩放和拖拽
Given 预览浮层已打开,展示一张图片
When 用户滚轮缩放或双指捏合
Then 图片放大或缩小
When 用户拖拽图片
Then 图片视口随拖拽移动
# Maps to AC-15
Scenario: 视频预览支持进度条和倍速
Given 预览浮层已打开,播放一个视频
When 用户拖动进度条
Then 视频跳转到对应时间点
When 用户切换倍速
Then 视频以新速率播放TDD Pointers
节点内容检测(纯函数):
- Test:
hasPreviewableContent(nodeData)— Image 有 images 返回 true,空数组返回 false (maps to AC-07) - Test: Video 有 videos 返回 true,Text 有 text 返回 true
预览目标解析(纯函数):
- Test: hover 节点优先于 selected 节点 (maps to AC-03)
- Test: 无 hover 时 fallback 到 selected 节点 (maps to AC-02)
- Test: 两者都无时返回 null
节点排序/切换(纯函数):
- Test: 可预览节点列表按画布位置排序,方向键正确切换索引 (maps to AC-12)
- Test: 边界不循环 (maps to AC-13)
Out of Scope
- Image 节点多 variations 的网格预览(仅预览
images[0]) - 触摸屏/移动端手势触发预览
- 预览浮层的过渡动画细节(由实现决定)
- 节点生成中(status=generating)的特殊预览行为