← ALL NOTES
METHOD·2026.09·6 MIN READ
多功能界面的操作入口与状态分层
3d-designprocess-design
问题

把多个独立功能合并进同一套界面时,最容易被低估的问题,不是"按钮够不够放",而是每个入口到底属于哪一种操作关系。

工具栏、顶栏、选中态操作条,表面上都是"点一下触发功能",但它们对应的用户前提完全不同:有的先进入一种模式,再去场景里操作;有的点击后立即执行;有的只有选中某个对象以后才有意义。

我之前把五个独立的 3D 交互 demo 合并成一个综合原型时,正好遇到这个问题。技术落地上,我和 Claude Code 一起把功能做成可注册的模块结构;但真正决定入口该放哪里的是产品语义,而不是代码长什么样。

这次最值得记下来的,是两次分类判断被纠正的过程。它们都说明了一件事:代码上相似的状态切换,在用户心智里可能属于完全不同的层级。

先按操作关系分层

最终把界面入口分成三类:

区域操作性质典型功能
右侧工具栏互斥工作模式。先选模式,再去画布中继续操作选择、距离测量、体积测量、笔记、立方体
顶栏一次性动作。点击后立即执行,不改变后续点击的含义模型校正、旋转 15°、重置方向、重置视角、修改比例
选中态操作条依赖当前选中对象。没有选中对象时入口本身不存在测量项复制

这个分类的关键不在视觉位置,而在用户操作前提:

  • 模式类:点入口只是开始,真正的操作发生在后续画布交互里;
  • 动作类:点击本身就是完整操作;
  • 对象操作类:先有一个明确的选中对象,入口才成立。

只要这个关系分清楚,功能放到哪里通常会自然很多。

判断错误一:把 Gizmo 当成全局控制器

第一个问题来自 cube-gizmo demo。

这个 demo 最初很容易被理解成一个常驻在屏幕上的移动端控制器。合并进综合原型时,Claude Code 也沿着这个思路,把 Gizmo 当成一个独立、长期存在的控制入口。

但重新走一遍真实使用流程以后,我纠正了这个判断。

Gizmo 并不是用来控制整个相机或场景的全局控制器。它服务的是某一个已经创建并选中的立方体。

正确流程应该是:

  1. 用户先在工具栏进入"立方体"模式;
  2. 在场景中点击,创建一个立方体;
  3. 选中这个立方体;
  4. 只有此时,Gizmo 才作为这个对象的变换控件出现。

这里"立方体工具"和"Gizmo"不是同一层东西。

前者是一个工作模式,决定用户接下来在场景里做什么;后者是选中对象之后出现的子控件,只服务于当前对象。

如果把 Gizmo 做成常驻 overlay,界面仍然可以运行,但它会给用户一个错误暗示:这个控件像是在控制整个场景,而不是控制某个具体立方体。

最终实现上,Gizmo 也没有被硬塞进新的全局 slot,而是作为 feature 自己的选中态内容存在。

判断错误二:把俯视模式放进互斥工具栏

第二个问题来自俯视模式。

一开始合并时,它很自然地被当成工具栏里的另一个按钮,和选择、测量、笔记这些模式并列。

从代码结构看,这种判断很容易成立:它们都是"点一下以后切到某个状态"。

但从使用关系看,俯视并不是一种工作工具,而是场景的观察方式。

"当前使用什么工具"和"当前用什么视角看场景"是两条独立状态轴:

工具模式:选择 / 距离测量 / 体积测量 / 笔记 / 立方体
视角模式:3D / 俯视

它们应该可以任意组合。

例如"俯视 + 距离测量"完全是合法状态。用户可以保持俯视,同时继续画测量线。

如果把俯视模式塞进工具栏的互斥集合,切换到测量以后就必须退出俯视,等于人为制造了一个产品上没有理由存在的限制。

因此最终把视角模式从 feature 工具体系里拆出来,放到场景 viewer 层,并在 UI 上使用独立的 3D / 俯视切换控件。

一个更实用的判断方法

这两次错误看起来不同,但可以用同一组问题判断。

1. 点击以后,用户还需要去场景里做下一步吗? 如果需要,它更像一种工作模式,而不是一次性动作。

2. 这个入口是否依赖一个已经选中的对象? 如果依赖,它应该属于对象上下文,而不是常驻全局区域。

3. 它能不能和当前工具同时存在? 如果可以同时存在,就不应该被塞进同一组互斥状态。

4. 它改变的是"我要做什么",还是"我怎么看当前场景"? 前者通常属于工具,后者更接近 viewer 或场景级状态。

这些问题比"这个按钮看起来应该放左边还是右边"更早,也更重要。

经验总结
  1. 功能入口先按操作前提分类,再决定视觉位置。 不要因为几个入口都长成按钮,就默认它们属于同一个区域。
  2. 工作模式、一次性动作和对象操作是三种不同关系。 它们对应的状态生命周期也不同。
  3. 选中态控件不要误做成全局控件。 一个功能只有在选中具体对象后才成立,就应该依附于那个对象出现。
  4. 可以同时存在的状态不要放进同一个互斥集合。 例如视角和测量工具,本质上是两条独立轴。
  5. 合并功能以后一定要重新走一遍完整用户流程。 单个 demo 内合理的结构,放到综合产品里未必仍然成立。
关于 AI 辅助架构判断

这次具体的注册表结构和代码组织主要由 Claude Code 协助完成,但两次关键纠正都发生在产品语义层。

AI 很容易根据代码形态做出合理分类:都是按钮、都是状态切换、都可以注册到某个区域。从工程角度看,这些方案甚至没有明显错误。

真正需要人工确认的是:用户点击之前发生了什么,点击之后还要做什么,这个状态能不能和其他状态同时存在,以及这个控件到底属于场景、工具还是当前对象。

所以在这类综合原型里,我更倾向把 AI 用在"快速展开技术方案",再自己用真实操作流程去检查分类是否成立。

实现备注

每个 feature 使用统一注册结构,并声明自己属于哪个 UI slot。

壳层分别渲染 toolbar、topbar、selection 三类入口。

Gizmo 不作为独立全局 slot,而作为 feature 的选中态内容存在,例如 SelectionGizmo。

视角模式不进入 feature 注册表,而归到 viewer / camera 层,因为它描述的是场景观察方式,而不是具体工作功能。

CONTINUE READING
从 Figma 组件属性到代码 Props2026.09Figma 设计系统的工程化落地2026.09