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

引言

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

概述

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

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

SVG Path 的基本原理

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

ini 复制代码
<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 形

xml 复制代码
<!-- 需要两个独立的 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) : 由边围成的封闭区域

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

数据结构

ini 复制代码
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 自动识别由边围成的封闭区域,每个区域可以独立填充。

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

css 复制代码
// 绘制一个带孔的矩形
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 Path Vector Networks
添加节点 需要重新计算路径序列 直接添加顶点和边
删除节点 可能断开路径 自动调整连接关系
创建分支 需要创建新路径 直接从顶点引出新边
合并图形 复杂的布尔运算 合并顶点和边

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

SVG Path:

xml 复制代码
<!-- 原始:一条直线 -->
<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:

yaml 复制代码
// 原始
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:

yaml 复制代码
// 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 Path Vector Networks
单一闭合区域 直接填充 自动识别区域填充
带孔的形状 使用 fill-rule 自动计算拓扑区域
开放路径 只能描边 可以单独对边描边
复杂相交 需要路径运算 自动识别所有区域

示例:相交的两个圆

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

ini 复制代码
<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 Path Vector Networks
存储大小 路径字符串(紧凑) 结构化数据(略大)
解析速度 快速 需要构建图结构
编辑性能 局部修改需要重解析 O(1) 修改顶点/边
适用场景 静态展示、导出 交互式编辑

Vector Networks 的独特优势

1. 设计工作流优化

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

2. 复杂图形绘制

非常适合绘制:

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

参考资源


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

更多精彩内容可关注风起的博客,微信公众号:听风说图

相关推荐
y***03172 小时前
Node.js npm 安装过程中 EBUSY 错误的分析与解决方案
前端·npm·node.js
肥猪大大2 小时前
Rsbuild迁移之node-sass引发的血案
前端·javascript
用户4099322502122 小时前
Vue3计算属性与侦听器的核心差异是什么?如何快速选对使用场景?
前端·ai编程·trae
九年义务漏网鲨鱼2 小时前
【Agentic RL 专题】五、深入浅出Reasoning and Acting (ReAct)
前端·react.js·大模型·智能体
爱泡脚的鸡腿2 小时前
uni-app D3实战(小兔仙)
前端
嬉皮客3 小时前
Gird布局详解
前端·css
烛阴3 小时前
C#常量(const)与枚举(enum)使用指南
前端·c#
Wect3 小时前
学习React-DnD:实现多任务项拖拽-useDrag处理
前端
mucheni3 小时前
迅为RK3568开发板OpeHarmony学习开发手册-修改应用程序名称
linux·前端·学习