Skip to content
风起
风起

Figma Vector Networks: 重新定义矢量图形编辑

引言

在传统的矢量图形设计工具中,SVG Path 一直是描述矢量图形的标准方式。然而,Figma 引入了一种革命性的概念——Vector Networks(矢量网格),它从根本上改变了我们对矢量图形的理解和操作方式。本文将深入探讨 Vector Networks 的技术特性,并与传统的 SVG Path 进行对比,阐述其独特优势。

概述

简单理解:SVG Path 受限于线性的线条,而 Vector Networks(矢量网格)突破了这个限制,可以表示由节点和线条组成的任意网格。网格可以很容易降维表示线条,但线条只能通过复杂的手段来描述网格。

SVG Path:传统的矢量表示方式

SVG Path 的基本原理

SVG Path 使用一系列命令来描述路径:

svg
<path d="M 10,10 L 90,10 L 90,90 L 10,90 Z" />

常见命令包括:

  • M (moveto): 移动到起点
  • L (lineto): 画直线
  • C (curveto): 贝塞尔曲线
  • Z (closepath): 闭合路径

SVG Path 的局限性

  1. 单向性: Path 是有方向的,从起点到终点的单向序列
  2. 难以编辑: 修改中间节点可能需要重新计算整个路径
  3. 分支限制: 难以表示具有分支结构的复杂图形
  4. 拓扑约束: 必须遵循严格的点到点连接顺序

示例:绘制一个简单的 T 形

svg
<!-- 需要两个独立的 path -->
<path d="M 50,10 L 50,90" />        <!-- 竖线 -->
<path d="M 10,30 L 90,30" />        <!-- 横线 -->

我们移动顶点时,有时希望它们能够 粘连 在一起,但 SVG 没法做到。

Vector Networks:新一代矢量模型

核心概念

Vector Networks 将矢量图形抽象为一个图结构(Graph),包含:

  • 顶点 (Vertices): 图形中的点
  • 边 (Edges): 连接顶点的线段或曲线
  • 区域 (Regions): 由边围成的封闭区域

这是一种非方向性的拓扑结构,允许任意的连接关系。

数据结构

typescript
interface VectorNetwork {
  vertices: Vertex[];
  edges: Edge[];
  regions: Region[];
}

interface Vertex {
  id: string;
  x: number;
  y: number;
  // 可以连接任意数量的边
  connectedEdges: string[];
}

interface Edge {
  id: string;
  start: string;  // vertex id
  end: string;    // vertex id
  // 贝塞尔控制点
  handleStart?: Point;
  handleEnd?: Point;
}

interface Region {
  id: string;
  // 围成该区域的边的集合
  boundaryEdges: string[];
  fill?: Paint;
}

关键特性

1. 非方向性连接,自由分支

在 Vector Networks 中,一个顶点可以连接任意数量的边,没有起点和终点的概念,天然支持分支结构,这在绘制复杂图形时极为重要。

T 形结构在 Vector Network 中,既可以 不粘连 也可以 粘连,非常灵活:

2. 智能区域识别

Vector Networks 自动识别由边围成的封闭区域,每个区域可以独立填充。

绘制一个带孔的矩形,自动识别可填充区域:

typescript
// 绘制一个带孔的矩形
const network: VectorNetwork = {
  vertices: [
    // 外矩形
    { id: 'v1', x: 0, y: 0 },
    { id: 'v2', x: 100, y: 0 },
    { id: 'v3', x: 100, y: 100 },
    { id: 'v4', x: 0, y: 100 },
    // 内矩形(孔)
    { id: 'v5', x: 30, y: 30 },
    { id: 'v6', x: 70, y: 30 },
    { id: 'v7', x: 70, y: 70 },
    { id: 'v8', x: 30, y: 70 },
  ],
  edges: [
    // 外边
    { id: 'e1', start: 'v1', end: 'v2' },
    { id: 'e2', start: 'v2', end: 'v3' },
    { id: 'e3', start: 'v3', end: 'v4' },
    { id: 'e4', start: 'v4', end: 'v1' },
    // 内边
    { id: 'e5', start: 'v5', end: 'v6' },
    { id: 'e6', start: 'v6', end: 'v7' },
    { id: 'e7', start: 'v7', end: 'v8' },
    { id: 'e8', start: 'v8', end: 'v5' },
  ],
  regions: [
    // 自动识别的区域:外矩形减去内矩形
    { 
      id: 'r1', 
      boundaryEdges: ['e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8'],
      fill: { color: '#D9D9D9' }
    }
  ]
};

SVG 需要使用 fill-rule 和复杂的路径方向来实现相同效果。

Vector Networks vs SVG Path:深度对比

1. 编辑灵活性

特性SVG PathVector Networks
添加节点需要重新计算路径序列直接添加顶点和边
删除节点可能断开路径自动调整连接关系
创建分支需要创建新路径直接从顶点引出新边
合并图形复杂的布尔运算合并顶点和边

实例:在线段中间添加分支

SVG Path:

svg
<!-- 原始:一条直线 -->
<path d="M 0,0 L 100,0" />

<!-- 添加向上分支:需要拆分 -->
<path d="M 0,0 L 50,0" />
<path d="M 50,0 L 100,0" />
<path d="M 50,0 L 50,-50" />

Vector Networks:

typescript
// 原始
vertices: [
  { id: 'v1', x: 0, y: 0 },
  { id: 'v2', x: 100, y: 0 }
]
edges: [
  { id: 'e1', start: 'v1', end: 'v2' }
]

// 添加分支:只需插入新顶点,调整边的连接
vertices: [
  { id: 'v1', x: 0, y: 0 },
  { id: 'v2', x: 50, y: 0 },  // 新顶点
  { id: 'v3', x: 100, y: 0 },
  { id: 'v4', x: 50, y: -50 } // 分支顶点
]
edges: [
  { id: 'e1', start: 'v1', end: 'v2' },
  { id: 'e2', start: 'v2', end: 'v3' },
  { id: 'e3', start: 'v2', end: 'v4' } // 分支边
]

2. 拓扑表达能力

Vector Networks 可以表示任意的图拓扑结构,而 SVG Path 受限于路径的线性特性。

复杂示例:绘制一个星形网格

Vector Networks:

typescript
// Vector Network 可以优雅地表示中心节点连接多个外围节点
const starNetwork = {
  vertices: [
    { id: 'center', x: 50, y: 50 },
    { id: 'p1', x: 50, y: 0 },
    { id: 'p2', x: 93, y: 25 },
    { id: 'p3', x: 93, y: 75 },
    { id: 'p4', x: 50, y: 100 },
    { id: 'p5', x: 7, y: 75 },
    { id: 'p6', x: 7, y: 25 },
  ],
  edges: [
    { id: 'e1', start: 'center', end: 'p1' },
    { id: 'e2', start: 'center', end: 'p2' },
    { id: 'e3', start: 'center', end: 'p3' },
    { id: 'e4', start: 'center', end: 'p4' },
    { id: 'e5', start: 'center', end: 'p5' },
    { id: 'e6', start: 'center', end: 'p6' },
  ]
};

SVG Path 需要 6 条独立的路径来表示。

3. 填充和描边处理

场景SVG PathVector Networks
单一闭合区域直接填充自动识别区域填充
带孔的形状使用 fill-rule自动计算拓扑区域
开放路径只能描边可以单独对边描边
复杂相交需要路径运算自动识别所有区域

示例:相交的两个圆

SVG 需要使用复杂的路径布尔运算或 clip-path

svg
<defs>
  <clipPath id="clip">
    <circle cx="50" cy="50" r="40"/>
  </clipPath>
</defs>
<circle cx="50" cy="50" r="40" fill="red"/>
<circle cx="70" cy="50" r="40" fill="blue" clip-path="url(#clip)"/>

Vector Networks 自动识别相交产生的 3 个区域(左月牙、中间交集、右月牙),可以分别填充。

4. 性能和存储

指标SVG PathVector Networks
存储大小路径字符串(紧凑)结构化数据(略大)
解析速度快速需要构建图结构
编辑性能局部修改需要重解析O(1) 修改顶点/边
适用场景静态展示、导出交互式编辑

Vector Networks 的独特优势

1. 设计工作流优化

  • 钢笔工具增强: 可以从任意点引出新路径,无需创建新图层
  • 智能连接: 顶点自动吸附和合并
  • 非破坏性编辑: 保持完整的拓扑关系,便于修改

2. 复杂图形绘制

非常适合绘制:

  • 流程图、线框图
  • 建筑平面图
  • 电路图、网络拓扑图
  • 有机形态的插画

参考资源


本文深入探讨了 Figma Vector Networks 的技术原理和设计哲学,希望能为矢量图形编辑工具的开发提供启发。