画布编辑器内的复杂交互设计
在画布编辑器中设计元素创建、连接与取景交互体系,在同类任务测试中将任务完成时间缩短了 34%
项目背景
在白板内用户使用各种元素在画布内进行特定业务场景作业。创建与元素建联是场景中的高频核心操作。我设计了一套完整的创建元素、元素建联的交互体系应用在白板中。让用户在场景作业的使用体验变得高效、简单。

创建方式
创建方式分为 3 种,满足默认创建、自定义位置创建、键盘输入时连续创建等多种场景。
点击创建
点击创建用于默认方向上的快速补节点。它适合结构方向已经比较明确的时候,用户不需要回到工具栏,也不需要重新做一次完整拖拽,只要围绕当前对象继续点击。
输入文本
拖拽创建
拖拽创建用于用户需要自己决定落点的时候。它保留了“从当前对象继续往下做”的起点,但把最终落点交还给用户。如果拖拽停在空白处,系统会继续走新增逻辑;如果拖拽停在已有对象上,则会进入连接逻辑。
输入文本
Command + Enter
Command + Enter 用于连续输入场景。用户在编辑节点内容时,不需要离开输入状态再回头创建下一个节点,而是可以直接生成下一个节点并继续输入。
输入文本
热区和控制点
热区范围与激活
当指针进入对象周围时,出现创建点 UI,hover 后激活,点击即创建。
当前对象
指针在对象内时,四周也会出现创建点 UI,交互同理。
当前对象
热区跟随尺寸和画布自适应
热区尺寸不是固定值。对象放大或缩小之后,热区会跟着对象尺寸变化;画布缩放变化时,热区也会跟着调整。否则对象一旦变大或变小,触发范围就会很快失真。
当前对象
当前对象
旋转的 Case
一般情况下,热区随着对象旋转而旋转。
当前对象
对象四周的创建点方向跟随物理方位发生变化
当前对象
当前对象
连接对象
当用户希望对象之间建立关系时,会使用连接线将对象之间进行连接。从用户行为出发,一般有两类连接场景。
手动连接
有明确连接意图。用户会手动将连接线拖拽到对象上。
当前对象
已有对象
系统智能判断
还有一种快捷方式是:当对象旁边有同类对象时,hover 创建点后系统会预判你希望连接到附近的对象,此时会出现点击后的预览效果。点击后自动产生连接。
当前对象
已有对象
接下来是方向判断。下面左侧的对象虽然也很近,但它偏离了这次创建的主方向,所以不能连接;右侧的对象处在正确方向上,所以可以直接连接。
当前对象
其他对象
当前对象
已有对象
当同一个方向里同时出现多个候选对象时,先保留同方向、同类型、未建立过连接的候选,再在这些候选里优先选择更贴近主方向、同时距离更近的那个。
当前对象
候选对象 A
候选对象 B
如果两个候选对象和当前创建点的 X 轴距离刚好一样,则优先选择 Y 更小的,作为 tie-break 逻辑。
当前对象
候选对象 A
候选对象 B
只有同类型的对象会进行连接,避免跨类型误连。
当前对象
已有便签
当前对象
已有对象
距离记忆
系统会按预设的默认距离创建下一个新节点。
当前对象
但如果用户通过拖拽创建了新节点,后续在点击创建时新节点会记住上一次对象创建的距离。
当前对象
排序整理
排序整理在连续创建的场景时显得尤为重要。它让创建出来的子节点井然有序,节约了手动调整的时间。
当前对象
子节点 B
子节点 C
子节点 D
子节点 E
当前对象
子节点 B
子节点 C
子节点 D
子节点 E
碰撞逻辑
参与碰撞的 case
在我们的定义中,白板内的便签、图形文本、文本、区块均参与碰撞逻辑。
当前对象
已有便签
不参与碰撞的元素
但属性仅具备标注性质的对象(高亮笔、铅笔)的笔迹,则不参与碰撞。
当前对象
取景策略
在用户创建大的结构图场景中,如果让用户既见森林又见树木,是关键。这里采用三层逻辑满足不同规格大小的场景。
第一层:全貌同屏
原节点 A、已有子节点和新建节点都能完整留在视图里,这是最好的结果,因为用户能同时看清结构全貌和这次新增的关系。
原节点 A
子节点 B
子节点 C
子节点 D
子节点 E
第二层:收缩兄弟节点
如果为了同时展示原节点 A 的所有子节点和新建节点,画布会被缩得太小,就优先放弃展示其他子节点,先保证原节点 A 和新建节点可读。
原节点 A
子节点 B1
子节点 B
子节点 C
子节点 D
子节点 E
子节点 E1
第三层:聚焦新建节点
当只保留原节点 A 和新建节点仍然会让缩放过小、影响判断时,系统会进一步把画布聚焦到新建节点本身。这样用户至少能先把新增结果看清,再继续往下编辑。
原节点 A
子节点 B1
子节点 B2
子节点 C
子节点 D
子节点 E
原节点 A
体验 DEMO
这一部分把前面拆开的逻辑放回到同一个原型里:点击创建、拖拽创建、连接已有对象、Command + Enter、碰撞避让、工具栏、铅笔和高亮笔都放在一起。这里看的是整体工作流,而不是单个判断点。
输入文本
输入文本
输入文本
输入文本
输入文本