资讯动态

TiXL 图编辑器连线分割(Connection Splitting):在连线中间插入算子的完整指南

发布时间:2026/9/19 23:10:35 来源:尧图企业网站定制
TiXL 图编辑器连线分割Connection Splitting在连线中间插入算子的完整指南【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址: https://gitcode.com/GitHub_Trending/t3/t3在 TiXL开源实时动态图形创作工具的图编辑器中重新布线通常意味着断开一条连接、重新接线这既繁琐又容易弄丢连线。4.3版本引入并验证了**连线分割Connection Splitting**能力你既可以把鼠标悬停在一条连线中间、单击并在搜索框中挑选一个类型匹配的算子让它在源与目标之间插队也可以把一个现成的算子直接拖到一条已吸附snapped的连线上完成同样的插入。本文以仓库中的手动测试集 graph-connection-splitting.md 为骨架逐场景讲解操作步骤与预期结果并结合 ConnectionMaker.cs、ConnectionSplitHelper.cs 等源码剖析悬停指示器、类型匹配、环检测、布局重排与撤销机制背后的实现原理。背景什么是连线分割为什么需要它连线分割解决的是图编辑中最常见的布线痛点当A → B这条连接已经存在而你想在中间插入一个处理算子C如把A → B变成A → C → B时传统做法需要先断开A → B再手动连两条线。分割功能把它压缩成一个动作——单击连线或拖拽算子TiXL 自动完成断开旧线 插入新算子 建立两条新连接的全过程且整个操作可通过CtrlZ一键还原。该测试集于2026-06-10加入、随版本4.3发布作用域为graph-window标签为user, essential面向用户的核心路径详见下文测试集格式说明。前置条件根据测试集 frontmatter 中的prerequisites运行这套验证需要准备一个可以在Graph Window图窗口中编辑的已打开项目一张可编辑的图例如一个新建的空算子其中包含至少一个Input 节点图左侧若干个普通算子一个Output 节点图右侧。这套测试的核心断言可以概括为一句话无论被分割的连线是从 Input 节点出发、还是通向 Output 节点新算子都必须成功嵌入连线连线绝不应当凭空消失。测试集格式一份可以被未来运行器驱动的手写规范在深入场景之前先说明这份文档的定位。.tests-manual/目录存放 TiXL 的人工验证走查Human-run verification walkthroughs每个文件是一个test set测试集由有序的steps步骤组成。目录规范见 .tests-manual/README.md一个测试集对应一个文件文件名即 frontmatter 中的idkebab-case。本文件的 frontmatter 结构如下--- id: graph-connection-splitting # kebab-case与文件名一致 title: Splitting Connections on the Graph # 运行器 UI 中显示的人类可读标题 added: 2026-06-10 # 加入日期驱动 Recently added 排序 added-in-version: 4.3 # 首次随发布的版本 scope: graph-window # 功能域 tags: [user, essential] # user面向艺术家用户的验证essential核心主路径 prerequisites: # 运行前提 - A project you can edit is open in the Graph Window. - A graph you can edit ... related-help: # 指向 .help/ 的深度阅读链接 - ../.help/using/graph-window.md ---按 README 的约定tags使用smoke/essential/edge/perf/flaky等受控词汇essential表示某功能的主路径每个测试集必须且只能有一个受众标签——user艺术家视角、用屏幕上的名称而非类名描述或dev贡献者视角、保留技术细节。本文件属于user因此所有步骤都按你在屏幕上看到什么来撰写例如用 the insert indicator 而非内部类名。每个步骤以## Step: 简短祈使句标题开头正文由**Action:**给测试者的操作指令用散文方式书写像带新人一样和**Expected:**只写可观察结果的现在时断言不允许 should probably 这类模糊措辞组成。运行时的步骤结果pass/fail/other不属于文件本身而属于某一次运行。该目录未来计划由编辑器内的运行器解析并驱动见 README 中提到的Plan_ManualTestRunner.md。场景一单击分割两个普通算子之间的连线这是最基本、也最常见的分割方式。Action:将鼠标悬停在两个普通算子之间一条连线的中段直到出现插入指示器insert indicator然后点击。在弹出的搜索框中挑选一个类型匹配type matches的算子。Expected:新算子嵌入连线拓扑变为source → new operator → target按CtrlZ可恢复为原来的直连同时移除插入的算子。这个流程在源码中对应 ConnectionSplitHelper.cs 的悬停检测与点击回调每一帧都会计算鼠标与各条连线中点的距离只接受SnapDistance 50像素范围内的命中RegisterAsPotentialSplit悬停时长足够后指示器会以EaseFunctions.EaseOutElastic弹性曲线放大radius EaseOutElastic(hoverDuration) * 4随后绘制一个InvisibleButton(splitMe)承载点击。点击后调用ConnectionMaker.SplitConnectionWithSymbolBrowser打开符号浏览器。场景二单击分割从 Input 节点出发的连线Action:将鼠标悬停在一条从图左侧 Input 节点出发的连线中段并单击从搜索框挑选一个类型匹配的算子。Expected:新算子嵌入input node → new operator → 原目标连线是被替换而非丢失——Input 节点经由新算子继续保持连通CtrlZ恢复直连。这一场景验证了分割对容器边界连线的兼容性。在 ConnectionMaker.cs 中连接输入/输出节点的特殊 ID 是UseSymbolContainerId Guid.Empty即连接的源或目标不是某个子算子而是符号容器自身的 Input/Output 节点。测试集把连线不消失作为显式断言正是为了覆盖这类最容易在重构中出问题的边界情况。场景三单击分割通向 Output 节点的连线Action:将鼠标悬停在馈送给图 Output 节点的那条连线中段并单击从搜索框挑选一个类型匹配的算子。Expected:新算子嵌入原来源 → new operator → output nodeCtrlZ恢复直连。场景四用现成算子拖拽分割Drag-splitAction:先将两个算子吸附在一起snapped水平或垂直方向均可然后拖拽第三个输入与输出类型都匹配的算子将其悬停在二者之间的 snapped 连线上直到插入高亮insert highlight出现松开放下。Expected:被拖拽的算子嵌入连线其后方的算子自动让位移动以腾出空间CtrlZ恢复此前的布局与连线。这里的让位并非装饰而是有意的布局引擎行为。拖拽分割对应 SplitConnectionWithDraggedNode它在完成连线操作前会调用AdjustGraphLayoutForNewNodeL276-L328以源、目标节点的中心为基准通过RecursivelyAddChildren递归收集目标节点上游沿输入反向的所有连通算子将位于中心线左侧的节点整体左移一个DefaultOpSize.X SnapPadding.X的间距保证新算子有足够的落点水平吸附时还会把新算子的PosOnCanvas直接设置到源与目标之间的插槽位置L890-L899并把布局变更一并登记为可撤销命令。场景五拖拽分割必须拒绝成环Action:将两个算子A → B吸附在一起。加入第三个类型匹配的算子C用一条长线把B的输出接到C的某个输入。现在把C拖到A与B之间的 snapped 连线上尝试放下。Expected:插入被拒绝控制台日志会记录该连接将导致环 / would create a cycleC不会被嵌入图保持完整且响应正常不崩溃、不卡死。这是整套测试中唯一的负向断言验证分割操作具备环检测保护。源码中环检查发生在连接提交阶段CompleteAtInputSlot 在建立新连接前调用Structure.CheckForCycle(sourceInstance.Outputs[0], targetUi.Id)一旦命中立即Log.Debug(This action is not allowed. This connection would result in a cycle.)并AbortOperation回滚CompleteAtOutputSlot 也有同样的检查Structure.CheckForCycle(sourceInstance, targetId)。文档中控制台记录环错误的预期正是这些日志语句在运行时的体现。分割操作走的是先删旧线、再建两条新线的组合路径如果插入算子后的任意一侧构成环整体操作会被原子性地中止因此图不会处于半成品状态——这与图保持完整且响应正常的预期一致。场景六拖拽分割吸附过的输入/输出节点连线Action:先把 Input 节点直接吸附到一个后续算子并且单独地把一个算子直接吸附到 Output 节点。再拖拽一个类型匹配的算子到吸附后的连线上并放下。Expected:算子嵌入链路保持完整——输入或输出节点依然连通只是现在经由新算子CtrlZ恢复直接吸附的连线。结合场景二、三本场景确认拖拽与单击两条路径对容器边界连接的行为一致分割只改变路径绝不破坏输入/输出节点的连通性。源码级原理一次分割操作在内部发生了什么把六个场景合起来看分割功能的内部机制可以归纳为四层1. 悬停检测与插入指示器旧版图窗口LegacyConnectionSplitHelper.cs 以SnapDistance 50像素为命中阈值悬停后绘制弹性放大的圆点指示器并在 Tooltip 中渲染来源输出值的实时缩略图通过outputUi.DrawValue(...)缩略图分辨率取自渲染输出窗口以及连接信息SourceOp.Output 类型 -- TargetOp.InputL83-L145。新图窗口MagGraphConnectionHovering.cs 是旧版拆分助手的派生版本与旧图窗口解耦。它把连线划分为LineRegionsBeginning起点 50% 内、Center中段、End终点 50% 内Tooltip 文案为 Click to insert operator or drag to disconnect...L125-L136支持多条类型一致、输出一致的连线合并悬停。从源码注释可见MagGraph 版本中的分割落地TODO: Implement splittingL148-L166仍在演进中本测试集即为该行为提供了明确的验收契约。2. 分割操作删一条旧线建两条新线单击路径 SplitConnectionWithSymbolBrowser 与拖拽路径 SplitConnectionWithDraggedNode 共享同一套临时连接模型用TempConnection记录两条待建连接其中新算子的位置用特殊 IDUseDraftChildIdffffffff-...标记为草稿节点L982-L986先执行DeleteConnectionCommand删除旧连接再依次AddConnectionCommand建立源 → 新算子与新算子 → 原目标两条新连接拖拽路径还会做输入侧校验算子必须有主输出instance.Outputs.Count 1时拒绝、必须有未被占用的匹配类型输入、且主输出类型与匹配输入类型一致否则分别输出Cant use node without outputs for splitting、Op doesnt have valid connections、Op doesnt match connection type等警告L860-L881——这解释了测试中必须挑选类型匹配的算子的要求从何而来。3. 撤销整件事是一次宏命令两类分割都把全部子命令布局移动、删除旧线、添加两条新线打包进一个MacroCommand命名如Split connection with new Operator或Split connection with {算子名}最后提交到UndoRedoStackL238-L260。因此一次CtrlZ就能同时回滚连线拓扑与画布布局——这正是六个场景中CtrlZ恢复原状预期得以成立的基础。4. 边界情况的实现现状需要诚实指出的是旧版SplitConnectionWithSymbolBrowser中仍保留了对容器边界连线的早期返回守卫遇到IsConnectedToSymbolOutput/IsConnectedToSymbolInput时会输出Splitting connections to output is not implemented yet/Splitting connections from inputs is not implemented yetL775-L785。因此测试集中场景二、三、六所验证的输入/输出节点连线可被分割行为本质上是新版图交互MagGraph 路径需要满足的验收契约这也正是这份测试集存在的意义——它把维护者期望的行为固化成可逐条验证的步骤防止重构回归。常见失败模式与排查要点结合源码中的日志与测试集的负向断言整理排查清单现象可能原因依据插入被拒控制台输出 would result in a cycle插入后任一侧形成环ConnectionMaker.cs 中的Structure.CheckForCycle拖拽的算子无法落位算子无输出 / 主输出与输入类型不匹配 / 匹配输入已被占用ConnectionMaker.cs 的三条Log.Warning旧版路径上输入/输出节点连线点击无效旧版SplitConnectionWithSymbolBrowser的守卫尚未移除ConnectionMaker.cs 的 not implemented yet 日志悬停指示器不出现鼠标距连线中点超过 50 像素命中阈值ConnectionSplitHelper.cs 的SnapDistance结语测试集即契约graph-connection-splitting这份测试集的价值不仅在于六个可复现的操作步骤更在于它把连线分割这一高频编辑动作的行为边界完整固化了下来单击与拖拽两条路径、输入/输出节点边界、类型匹配、环拒绝、布局让位与撤销还原。对使用者而言它可以当作功能操作手册对贡献者而言它是修改ConnectionMaker、ConnectionHovering等实现时不可跳过的回归网。当你下次需要在两条算子之间插入处理节点时记住这个动作悬停、单击或拖拽、挑选类型匹配的算子——TiXL 会替你把线重新接好CtrlZ也永远兜底。【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址: https://gitcode.com/GitHub_Trending/t3/t3创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价