你以为节点丢了,其实是被裁掉了
我在搭一个 BPMN 工作流编辑器,用的是 bpmn-js。
那天我打开画布,看到默认的三个元素——开始事件、审核任务、结束事件。但我手动拖了一个排他网关和一个注释框进去,保存后刷新页面,它们不见了。
我发了截图给你,红色边框的注释框里显示了一个「[」,旁边有个 X 菱形网关,还有一些虚线。我以为是渲染出了 bug。
我用 CDP 检查了实际页面,结果是这样:
1 | viewportSize: 1384 x 805 (整个浏览器窗口) |
画布上只有 5 个元素——开始、任务、结束和两个标签。你截图里多出来的 X 网关和红色注释框,不在 CDP 查到的 DOM 里。
这意味着那些元素是你手动拖到画布上的,但没有被保存到默认 XML。刷新页面后,只有 XML 里的元素会被加载。
但更关键的是:那些元素即使被加载了,也会被画布裁掉。
什么是无限画布
bpmn-js 的画布容器设置了 overflow: hidden。这意味着画布不会显示滚动条,也不会显示画布边界。
你可以把元素拖到画布可见区域之外——它们不会消失,只是被裁剪了。
你想看到它们?用鼠标中键拖动来平移画布,或者按住 Shift 加鼠标拖动。用 Ctrl 加滚轮缩放。
没有滚动条。没有边界线。没有”当前你看到哪里”的指示器。
这就是无限画布设计。
代价:你不知道自己在哪
无限画布设计的好处很明显——你可以画任意大的流程图,不需要担心画布边界。一个审批流程可能有几十个节点、几十条连线,如果画布有边界,你的流程就会被迫缩小或者换页。
但代价是:你失去了位置感。
我那次看到截图里有红色注释框和 X 网关,以为渲染出错了。其实不是——那些元素是被拖到了画布外面,被 overflow: hidden 裁掉了。
我问的是:”节点少吗?还是因为样式的问题,没显示全?没滚动条吗?”
答案很简单:
- 节点不少——DOM 里有 5 个元素
- 不是样式问题——是溢出裁剪
- 确实没有滚动条——因为这是无限画布设计
三个问题,三个答案,但第一个问题的”答案”本身就是一个问题。
我以为节点丢了,因为无限画布给了我一种”所有内容都应该在这里”的错觉。但实际上,画布上显示的东西只是”当前视口”里的内容。你把元素拖到了视口外面,它就看不见了——但你没有任何提示告诉你”这里还有东西”。
固定画布 vs 无限画布:一个被低估的 trade-off
大多数工具的画布是有边界的。Word 有页面边缘,Excel 有单元格网格,VS Code 有滚动条,浏览器有窗口边界。
当你看到边界,你知道:
- 内容在哪里结束
- 滚动条的位置告诉你当前在看第几行/第几列
- 你永远不会”丢东西”——因为画布会提醒你”这里还有内容”
但 bpmn-js、Figma、Excalidraw 这类工具选择了无限画布。
无限画布省掉了滚动条的 UI 复杂度,省掉了画布边界的视觉噪音。当你画一个 100 节点的流程图时,你不需要缩小视图到 20% 才能看到全貌——你可以把每个节点都正常大小,然后用平移来查看不同区域。
但代价是空间感知消失了。
一个实际例子
我在 BPMN 编辑器里遇到了这个问题。我拖了一个注释框到画布的右下角,但那个位置刚好在 1004×687 的可见区域之外。我刷新页面后,注释框没了。
我以为是 bug。我花了几分钟检查 DOM、检查 CSS、检查渲染逻辑,才意识到:
注释框还在画布里,只是被裁掉了。
如果我用的是一种有滚动条的工具——比如 Word 或传统 IDE——我一眼就能看到右侧或底部有滚动条,拉一下就能看到被裁掉的内容。
但 bpmn-js 没有滚动条。它给你一个无限的空间,代价是你必须自己知道”我在这里,那里还有东西”。
怎么解决
bpmn-js 提供了几种方式来应对这个问题:
- 鼠标中键拖动——平移画布,看到被裁掉的内容
- Shift + 鼠标拖动——同上
- Ctrl + 滚轮——缩放,缩小后所有元素都能显示在视口内
- F2 键——重置视图,自动缩放并居中显示所有元素
- 双击空白处——触发 zoom-fit,同上
但这些都不是”一眼就能看到”的。你需要知道这些快捷键,或者在 UI 上放一个”适应视图”按钮。
我后来决定加一个工具栏按钮,一键 zoom-fit。这样用户不用记快捷键,也不用猜”是不是有东西被裁掉了”。
无限画布适合什么
无限画布不是万能的。它适合:
- 内容大小不可预测的场景(流程图可能有 5 个节点,也可能有 500 个)
- 空间位置很重要的场景(你拖元素到不同位置是有意义的——比如 BPMN 的布局反映流程走向)
- 内容不会被”意外丢失”的场景(元素不会因为超出边界而消失,只是被裁剪)
固定画布+滚动条适合:
- 内容大小可预测的场景(一页 Word 文档、一张 Excel 表格)
- 用户需要知道”当前位置”的场景(第 50 行、第 3 页)
- 内容不会因为超出边界而”看起来消失”的场景
没有对错,只有适合不适合。
bpmn-js 选择无限画布,是因为 BPMN 流程图的规模不可预测。一个审批流程可能只有 3 个节点,也可能有几十个节点跨多页。如果用固定画布,大流程图会被迫缩小到看不清,或者被迫分页——而分页在 BPMN 里意味着把流程切断了。
但它也应该提供足够的视觉提示,让用户知道”画布外面还有东西”。
设计工具的人,需要为用户的困惑负责
我那次花了很长时间在检查 DOM、检查 CSS、检查渲染逻辑——我才意识到问题不是 bug,而是设计。
用户看到截图里有红色注释框和 X 网关,然后刷新后看不见了。用户的第一反应是”出错了”,不是”哦,那是无限画布设计,元素被裁掉了”。
这不是用户的错。这是工具没有提供足够的空间感知。
无限画布设计省掉了滚动条,但如果你不加”适应视图”按钮、不加小地图、不加缩略图预览——用户就只能靠猜。
猜的成本是时间。而我花了二十分钟在猜”是不是有东西被裁掉了”。
如果当时工具栏上有一个”适应视图”按钮,或者右下角有一个小地图显示当前视口在画布里的位置——这二十分钟就不会花。
结论
无限画布是一个合理的设计选择,但它有一个被低估的代价:用户会失去空间感知。
当你选择无限画布,你也在选择让用户用”快捷键+记忆”来替代”滚动条+视觉提示”。
如果你的工具选择了无限画布,你需要提供足够的补偿:
- 一个”适应视图”按钮(让用户一键看到所有内容)
- 一个小地图或缩略图(让用户知道当前位置)
- 至少一个视觉提示(比如画布边缘的渐变色,暗示”外面还有东西”)
否则,你的用户会在画布外面迷路——而他们的第一反应是”你的工具有 bug”。