Figma: 协作画布

Figma如何构建实时多人设计:存在指示器、无限画布、Dev Mode和设计令牌。包含CSS和JavaScript实现模式。

5 分钟阅读 422 字
Figma: 协作画布 screenshot

Figma:协作画布

"在 Figma 的理念中,我们希望让 AI 也能实现多人协作。协作始终是我们一切工作的核心。" — Figma 团队

Figma 将设计从一项独立的技艺转变为团队运动。作为首款支持实时协作编辑的设计工具,Figma 证明了复杂的创意工具也可以像 Google Docs 一样流畅——同时保持设计师所要求的精确度。


为什么 Figma 如此重要

Figma 不仅仅是在设计工具中添加了多人协作功能,而是重新构想了设计的工作方式。通过将协作融入产品根基,Figma 改变了工作流程、团队协作模式以及整个设计到开发的交付流程。

核心成就: - 首款支持实时多人编辑的设计工具 - 开创了"无限画布"作为 UI 范式 - 让设计系统变得人人可用 - 通过 Dev Mode 架起设计与开发之间的桥梁 - 在协作理念上打造了价值 200 亿美元的创意帝国


核心要点

  1. 多人协作需要简洁 - Figma 构建了一套比操作变换更简单的自研方案,因为更简单的系统更易于调试和维护
  2. 无限画布激发探索 - 不同于基于页面的工具,开放式画布鼓励迭代,避免了人为的限制
  3. 上下文感知的界面降低认知负荷 - 工具栏和面板根据选择自适应,只显示相关的控件
  4. 设计令牌连接设计与代码 - 从原始值 → 语义化 → 组件层级的变量体系,为设计师和开发者创造了共同语言
  5. Dev Mode 是专属工作区 - 将开发者工具与设计工具分离,尊重了不同的思维模型和工作流程

核心设计原则

1. 以多人协作为根基

Figma 构建了一套比传统方案(如操作变换 OT)更简单的自研多人协作方案。他们的目标是清晰:系统复杂度不超过必要程度。

设计哲学: 由于 Figma 不是文本编辑器,他们不需要 OT 的强大能力,可以采用更简单的方案。更简单的系统更易于理解、实现、调试、测试和维护。

多人协作的视觉模式:

PRESENCE INDICATORS:
┌─────────────────────────────────────────────────────────────────┐
│  Canvas                                                          │
│                                                                  │
│  ┌──────────────────────────────────────┐                       │
│  │  Component: Button                    │   (o) Alice          │
│  │  ┌────────────────────┐              │   <- 实时光标         │
│  │  │  Primary Button    │              │                       │
│  │  └────────────────────┘              │                       │
│  └──────────────────────────────────────┘   (*) Bob             │
│                                              <- 选择框           │
│                                                                  │
│  ┌──────────────────────────────────────┐                       │
│  │  Input Field          (+) Carol      │   <- 编辑模式         │
│  │  ┌────────────────────────────────┐  │                       │
│  │  │ |                              │  │                       │
│  │  └────────────────────────────────┘  │                       │
│  └──────────────────────────────────────┘                       │
└─────────────────────────────────────────────────────────────────┘

CURSOR DESIGN:
┌─────────────────────────────────────────────────────────────────┐
│                                                                  │
│  光标结构:                                                       │
│                                                                  │
│     ▲                                                            │
│    ╱ ╲                                                           │
│   ╱   ╲ ← 箭头(用户专属颜色)                                    │
│  ╱_____╲                                                         │
│  ┌─────────┐                                                     │
│  │  Alice  │ ← 名称标签(悬停/活动时显示)                         │
│  └─────────┘                                                     │
│                                                                  │
│  状态:                                                          │
│  • 空闲:仅显示光标                                               │
│  • 活跃:光标 + 名称标签                                          │
│  • 编辑中:光标 + 名称 + "Editing..." 徽章                        │
│  • 离开:淡化光标(50% 透明度)                                    │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

实现原则: - 用户通过颜色识别,而不仅仅是名字 - 选择框显示谁在哪里工作 - 光标移动经过防抖处理以提升性能 - 用户空闲时在线状态指示器会淡出


2. 无限画布

Figma 的画布是一个开放、灵活的环境,支持快速迭代。与基于页面的工具不同,无限画布鼓励探索。

画布交互模式:

NAVIGATION:
┌─────────────────────────────────────────────────────────────────┐
│  Space + 拖动    平移画布                                        │
│  滚轮            垂直平移                                        │
│  Shift + 滚轮    水平平移                                        │
│  Cmd/Ctrl + +/-  放大/缩小                                       │
│  Cmd/Ctrl + 0    缩放至 100%                                     │
│  Cmd/Ctrl + 1    缩放以适应                                      │
│  Cmd/Ctrl + 2    缩放至选区                                      │
└─────────────────────────────────────────────────────────────────┘

ZOOM LEVELS WITH PURPOSE:
┌─────────────────────────────────────────────────────────────────┐
│  100%+     像素级细节处理                                        │
│  50-100%   组件编辑                                              │
│  25-50%    页面/屏幕级别                                         │
│  10-25%    流程概览                                              │
│  <10%      鸟瞰导航                                              │
│                                                                  │
│  UI 随缩放级别自适应:                                            │
│  • 文字在低于可读阈值时隐藏                                       │
│  • 远距离时细节简化                                               │
│  • 框架标签始终可见                                               │
└─────────────────────────────────────────────────────────────────┘

小地图模式:

/* Canvas navigation mini-map */
.minimap {
  position: fixed;
  bottom: 16px;
  right: 16px;
  width: 200px;
  height: 150px;
  background: rgba(0, 0, 0, 0.8);
  border-radius: 8px;
  overflow: hidden;
}

.minimap-viewport {
  /* 当前可视区域 */
  border: 2px solid var(--color-primary);
  background: rgba(255, 255, 255, 0.1);
  cursor: grab;
}

.minimap-content {
  /* 所有框架的简化渲染 */
  opacity: 0.6;
}

3. 工具栏即指挥中心

Figma 的工具栏体现了渐进式披露的理念:初看简洁,深入探索后功能强大。

工具栏架构:

FIGMA TOOLBAR ANATOMY:
┌─────────────────────────────────────────────────────────────────┐
│                                                                  │
│  ┌─────┬─────┬─────┬─────┬─────┬─────────────────┬───────────┐  │
│  │ [=] │ [>] │ [R] │ [O] │ [-] │  T  (H)  [...]  │  Share v  │  │
│  └──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴────────┬────────┴─────┬─────┘  │
│     │     │     │     │     │           │              │        │
│  菜单  移动  框架  形状  线条       文字/抓手/      协作功能        │
│               工具  工具          评论                           │
│                                                                  │
│  弹出菜单模式:                                                   │
│  ┌─────┐                                                         │
│  │ [R] │ <- 主工具(点击)                                        │
│  └──┬──┘                                                         │
│     │  ┌─────────────────────────┐                               │
│     └──│ [R] Rectangle       R   │ <- 长按显示更多选项             │
│        │ [O] Ellipse         O   │                               │
│        │ [^] Polygon             │                               │
│        │ [*] Star                │                               │
│        │ [I] Place image  Cmd+K  │                               │
│        └─────────────────────────┘                               │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

CONTEXT-AWARE TOOLBAR:
选择不同对象时工具栏选项动态变化:

无选择:          [移动] [框架] [形状] [钢笔] [文字]
选中框架:        [移动] [框架] [自动布局 ▼] [网格 ▼]
选中文字:        [移动] [字体 ▼] [字号 ▼] [字重 ▼] [对齐]
选中组件:        [移动] [变体] [属性] [分离]

4. 属性面板:上下文智能

右侧面板完全根据选择内容自适应,只显示相关的控件。

面板架构:

PROPERTIES PANEL STATES:
┌─────────────────────────────────────────────────────────────────┐
│                                                                  │
│  无选择:                        选中框架:                       │
│  ┌────────────────────┐         ┌────────────────────┐          │
│  │ Design   Prototype │         │ Design   Prototype │          │
│  ├────────────────────┤         ├────────────────────┤          │
│  │                    │         │ Frame                         │
│  │  选择某个对象       │         │ W: 375   H: 812    │          │
│  │  以查看属性        │         │ X: 100   Y: 200    │          │
│  │                    │         ├────────────────────┤          │
│  │                    │         │ Auto Layout        │          │
│  │                    │         │ ═══ ↕ 16  ↔ 24    │          │
│  │                    │         ├────────────────────┤          │
│  │                    │         │ Fill               │          │
│  │                    │         │ ■ #FFFFFF     100% │          │
│  │                    │         ├────────────────────┤          │
│  │                    │         │ Stroke             │          │
│  │                    │         │ + 添加描边          │          │
│  │                    │         ├────────────────────┤          │
│  │                    │         │ Effects            │          │
│  │                    │         │ + 添加效果          │          │
│  └────────────────────┘         └────────────────────┘          │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

CSS 实现模式:

/* Figma 风格属性面板 */
.properties-panel {
  width: 240px;
  background: var(--bg-secondary);
  border-left: 1px solid var(--border-subtle);
  display: flex;
  flex-direction: column;
}

.property-section {
  padding: 12px 16px;
  border-bottom: 1px solid var(--border-subtle);
}

.property-section-header { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(–text-secondary); margin-bottom: 8px; }

/ 可折叠区块 / .property-section[data-collapsed="true"] .property-section-content { display: none; }

/ 内联输入组 / .property-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }

.property-label { width: 24px; font-size: 11px; color: var(–text-tertiary); }

.property-input { flex: 1; height: 28px; padding: 0 8px; font-size: 11px; background: var(–bg-tertiary); border: 1px solid transparent; border-radius: 4px; }

.property-input:focus { border-color: var(–color-primary); outline: none; }


5. 变量与设计令牌

到 2025/2026 年,最具前瞻性的团队已经完全基于 Figma Variables 构建系统:这些原子级设计决策在设计与代码之间架起桥梁。

令牌架构:

变量结构:
┌─────────────────────────────────────────────────────────────────┐
│                                                                  │
│  基础值(原始数值)                                                │
│  ├── colors/                                                     │
│  │   ├── blue-50:  #EBF5FF                                       │
│  │   ├── blue-100: #D1E9FF                                       │
│  │   ├── blue-500: #2563EB  ← 品牌主色                           │
│  │   └── ...                                                     │
│  ├── spacing/                                                    │
│  │   ├── 4:  4px                                                 │
│  │   ├── 8:  8px                                                 │
│  │   ├── 16: 16px                                                │
│  │   └── ...                                                     │
│  └── radius/                                                     │
│      ├── sm: 4px                                                 │
│      ├── md: 8px                                                 │
│      └── lg: 16px                                                │
│                                                                  │
│  语义层(上下文含义)                                               │
│  ├── surface/                                                    │
│  │   ├── primary:    → colors/white                              │
│  │   ├── secondary:  → colors/gray-50                            │
│  │   └── elevated:   → colors/white                              │
│  ├── text/                                                       │
│  │   ├── primary:    → colors/gray-900                           │
│  │   ├── secondary:  → colors/gray-600                           │
│  │   └── disabled:   → colors/gray-400                           │
│  └── interactive/                                                │
│      ├── default:    → colors/blue-500                           │
│      ├── hover:      → colors/blue-600                           │
│      └── pressed:    → colors/blue-700                           │
│                                                                  │
│  组件层(特定用途)                                                 │
│  ├── button/                                                     │
│  │   ├── background: → interactive/default                       │
│  │   ├── text:       → colors/white                              │
│  │   └── radius:     → radius/md                                 │
│  └── card/                                                       │
│      ├── background: → surface/elevated                          │
│      ├── padding:    → spacing/16                                │
│      └── radius:     → radius/lg                                 │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

从 Figma 变量导出的 CSS 自定义属性:

/* 从 Figma Variables 导出 */
:root {
  /* 基础值 */
  --color-blue-500: #2563EB;
  --color-gray-900: #111827;
  --spacing-16: 16px;
  --radius-md: 8px;

  /* 语义令牌 */
  --color-interactive-default: var(--color-blue-500);
  --color-text-primary: var(--color-gray-900);

  /* 组件令牌 */
  --button-bg: var(--color-interactive-default);
  --button-radius: var(--radius-md);
  --card-padding: var(--spacing-16);
}

/* 通过变量模式实现深色模式 */
[data-theme="dark"] {
  --color-text-primary: #F9FAFB;
  --color-surface-primary: #1F2937;
}

6. 开发模式:连接设计与代码

Figma 的开发模式是专为开发者打造的工作空间,将设计意图转化为可用于生产的代码。

开发模式工作流:

设计 → 开发交接流程:
┌─────────────────────────────────────────────────────────────────┐
│                                                                  │
│  1. 设计师标记就绪                                                 │
│  ┌─────────────────────────────────────────────────────────────┐│
│  │  画板:登录界面                          [✓ 已准备好开发]     ││
│  │                                                             ││
│  │  标记就绪后:                                                 ││
│  │  • 出现在开发者的任务队列中                                    ││
│  │  • 锁定主要编辑                                               ││
│  │  • 启用变更追踪                                               ││
│  └─────────────────────────────────────────────────────────────┘│
│                                                                  │
│  2. 开发者检查                                                    │
│  ┌─────────────────────────────────────────────────────────────┐│
│  │  ┌──────────────────┐  ┌──────────────────────────────────┐ ││
│  │  │                  │  │  CSS                              │ ││
│  │  │   [Button]       │  │  .button {                        │ ││
│  │  │                  │  │    display: flex;                 │ ││
│  │  │                  │  │    padding: 12px 24px;            │ ││
│  │  └──────────────────┘  │    background: var(--primary);    │ ││
│  │                        │    border-radius: 8px;            │ ││
│  │  选中:Button          │  }                                │ ││
│  │  组件:ui/Button       │                                   │ ││
│  │  最后编辑:2小时前      │  [复制] [切换到 Swift]              │ ││
│  │                        └──────────────────────────────────┘ ││
│  └─────────────────────────────────────────────────────────────┘│
│                                                                  │
│  3. 变更对比                                                      │
│  ┌─────────────────────────────────────────────────────────────┐│
│  │  自上次开发查看以来的变更:                                     ││
│  │                                                             ││
│  │  - 内边距:16px → 12px                                       ││
│  │  + 圆角:8px(新增)                                          ││
│  │  ~ 颜色:#2563EB → var(--primary)                           ││
│  └─────────────────────────────────────────────────────────────┘│
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

色彩系统

Figma 的界面采用克制的中性色调,确保用户的内容始终是视觉焦点。

/* Figma 的界面色彩方案 */
:root {
  /* 表面色 */
  --bg-canvas: #E5E5E5;        /* 画布背景 */
  --bg-primary: #FFFFFF;        /* 面板、画板 */
  --bg-secondary: #F5F5F5;      /* 次级面板 */
  --bg-tertiary: #E8E8E8;       /* 输入框、凹槽区域 */

  /* 文本色 */
  --text-primary: #000000;
  --text-secondary: #666666;
  --text-tertiary: #999999;

  /* 边框色 */
  --border-subtle: rgba(0, 0, 0, 0.1);
  --border-strong: rgba(0, 0, 0, 0.2);

  /* 交互色彩 */
  --color-primary: #0D99FF;     /* 选中、聚焦 */
  --color-primary-hover: #0085EB;
  --color-success: #14AE5C;
  --color-warning: #FFCD29;
  --color-error: #F24822;

  /* 多人协作色彩(分配给用户) */
  --cursor-1: #F24822;  /* 红色 */
  --cursor-2: #FF7262;  /* 珊瑚色 */
  --cursor-3: #FFCD29;  /* 黄色 */
  --cursor-4: #14AE5C;  /* 绿色 */
  --cursor-5: #0D99FF;  /* 蓝色 */
  --cursor-6: #9747FF;  /* 紫色 */
  --cursor-7: #FF00FF;  /* 品红色 */
}

/* 深色模式 */
[data-theme="dark"] {
  --bg-canvas: #1E1E1E;
  --bg-primary: #2C2C2C;
  --bg-secondary: #383838;
  --bg-tertiary: #444444;

  --text-primary: #FFFFFF;
  --text-secondary: #ABABAB;
  --text-tertiary: #7B7B7B;
}

字体排版

Figma 的界面使用 Inter 字体,这是一款专为屏幕显示设计的字体。

/* Figma 的字体排版系统 */
:root {
  --font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;

  /* 字号比例 */
  --text-xs: 11px;    /* 标签、元数据 */
  --text-sm: 12px;    /* 正文、属性 */
  --text-md: 13px;    /* 标题 */
  --text-lg: 14px;    /* 区块标题 */

  /* 字重 */
  --font-regular: 400;
  --font-medium: 500;
  --font-semibold: 600;

  /* 行高 */
  --leading-tight: 1.2;
  --leading-normal: 1.4;
  --leading-relaxed: 1.6;
}

/* 应用示例 */
.section-header {
  font-size: var(--text-xs);
  font-weight: var(--font-semibold);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-secondary);
}

.property-label {
  font-size: var(--text-xs);
  color: var(--text-tertiary);
}

.layer-name {
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
}

动效与微交互

Figma 采用细腻而有目的性的动效来提供反馈,同时不会分散用户注意力。

/* Figma 的动效原则 */
:root {
  /* 时长 */
  --duration-instant: 50ms;   /* 悬停状态 */
  --duration-fast: 100ms;     /* 开关切换、小型变化 */
  --duration-normal: 200ms;   /* 面板过渡 */
  --duration-slow: 300ms;     /* 页面过渡 */

  /* 缓动曲线 */
  --ease-out: cubic-bezier(0, 0, 0.2, 1);
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
}

/* 面板滑入 */
.panel {
  transform: translateX(100%);
  transition: transform var(--duration-normal) var(--ease-out);
}

.panel[data-visible="true"] {
  transform: translateX(0);
}

/* 选中高亮 */
.layer-item[data-selected="true"] {
  background: var(--color-primary);
  transition: background var(--duration-fast) var(--ease-out);
}

/* 远程光标淡入淡出 */
.remote-cursor {
  transition: opacity var(--duration-slow) var(--ease-out);
}

.remote-cursor[data-idle="true"] {
  opacity: 0.5;
}

关键创新

FigJam:拓展画布的边界

FigJam 将 Figma 的画布延伸到白板协作领域,证明了无限画布不仅适用于像素级设计,同样适用于头脑风暴和创意构思。

设计决策: - 温暖、活泼的色彩方案,有别于 Figma 的中性色调 - 便签带有物理特性(可以"抛出") - 印章和表情反馈,支持异步协作 - 计时器和投票功能,便于会议引导

Variables:原生支持设计令牌

Figma Variables 将设计令牌提升为一等公民,实现了: - 模式切换(浅色/深色、品牌主题) - 响应式令牌(移动端/桌面端数值) - 数字变量,支持原型交互逻辑

AI 集成(2025 年及以后)

Figma 的 AI 策略以协作为核心: - AI 驱动的设计规范检查,确保令牌合规性 - 智能变量推荐 - 布局优化建议 - Weave 中的生成式设计探索


落地实践的经验

1. 从第一天起就为多人协作而构建

// 在线状态系统架构
class PresenceManager {
  constructor(roomId) {
    this.users = new Map();
    this.localUser = null;
    this.socket = new WebSocket(`wss://collab.example.com/${roomId}`);

    // Debounce cursor updates
    this.broadcastCursor = debounce((position) => {
      this.socket.send(JSON.stringify({
        type: 'cursor',
        userId: this.localUser.id,
        position,
        timestamp: Date.now()
      }));
    }, 50);
  }

  updateCursor(x, y) {
    this.localUser.cursor = { x, y };
    this.broadcastCursor({ x, y });
  }

  // Fade idle users
  checkIdleUsers() {
    const now = Date.now();
    const IDLE_THRESHOLD = 30000; // 30 seconds

    this.users.forEach(user => {
      user.isIdle = (now - user.lastActivity) > IDLE_THRESHOLD;
    });
  }
}

2. 上下文感知界面

// Panel content based on selection
function getPropertiesForSelection(selection) {
  if (selection.length === 0) {
    return { type: 'empty', message: 'Select something to see properties' };
  }

  if (selection.length > 1) {
    return { type: 'mixed', items: selection };
  }

  const item = selection[0];

  switch (item.type) {
    case 'FRAME':
      return {
        type: 'frame',
        sections: ['dimensions', 'autoLayout', 'fill', 'stroke', 'effects']
      };
    case 'TEXT':
      return {
        type: 'text',
        sections: ['font', 'paragraph', 'fill']
      };
    case 'COMPONENT':
      return {
        type: 'component',
        sections: ['properties', 'variants', 'dimensions']
      };
    default:
      return {
        type: 'generic',
        sections: ['dimensions', 'fill', 'stroke']
      };
  }
}

3. 工具栏中的渐进式披露

<!-- Tool with flyout variants -->
<div class="tool-button" data-tool="shape">
  <button class="tool-primary" title="Rectangle (R)">
    <svg><!-- Rectangle icon --></svg>
  </button>

  <div class="tool-flyout" hidden>
    <button data-variant="rectangle">
      <svg></svg> Rectangle <kbd>R</kbd>
    </button>
    <button data-variant="ellipse">
      <svg></svg> Ellipse <kbd>O</kbd>
    </button>
    <button data-variant="polygon">
      <svg></svg> Polygon
    </button>
    <button data-variant="star">
      <svg></svg> Star
    </button>
    <hr>
    <button data-variant="image">
      <svg></svg> Place image <kbd>Cmd+Shift+K</kbd>
    </button>
  </div>
</div>

<script>
// Long-press to reveal flyout
const LONG_PRESS_DURATION = 300;

toolButtons.forEach(btn => {
  let pressTimer;

  btn.addEventListener('pointerdown', () => {
    pressTimer = setTimeout(() => {
      btn.querySelector('.tool-flyout').hidden = false;
    }, LONG_PRESS_DURATION);
  });

  btn.addEventListener('pointerup', () => {
    clearTimeout(pressTimer);
  });
});
</script>


常见问题

Figma 的多人协作技术是如何工作的?

Figma 构建了一套比传统操作转换(OT)更简洁的自研解决方案。由于 Figma 处理的是画布上的对象而非文档中的文本,因此可以使用更简单的冲突解决系统。变更通过 WebSocket 连接同步,光标位置以 50ms 间隔进行防抖处理以优化性能。用户通过带有彩色标识的光标进行区分,光标在活动时会显示用户名标签。

Figma 和 FigJam 有什么区别?

Figma 是一款精密的 UI/UX 设计工具,提供像素级控制、组件和自动布局功能。FigJam 是一个用于创意构思的协作白板,采用更温暖的色彩方案,具有带物理效果的便签、印章、表情反馈,以及计时器和投票等引导工具。两者都采用无限画布范式,但在设计流程中服务于不同目的。

Figma Variables 如何用于设计系统?

Variables 遵循三层架构:原始值(如 blue-500: #2563EB 这样的原始数值)、语义化 token(具有上下文含义,如 interactive-default → blue-500)和组件级 token(特定用途,如 button-background → interactive-default)。这种分层结构支持亮色/暗色主题的模式切换和响应式数值,同时保持单一数据源。

什么是 Dev Mode?它面向哪些用户?

Dev Mode 是一个专门的开发者工作空间,将设计意图转化为可用于生产的代码。设计师将画框标记为"ready for dev"(可供开发),这会锁定主要编辑并启用变更追踪。开发者可以看到生成的 CSS、Swift 或其他代码片段、组件引用,以及显示自上次查看以来变更内容的 diff 视图。

为什么 Figma 使用无限画布而不是页面?

无限画布消除了基于页面的工具所带来的人为限制。设计师可以将完整的用户流程并排布置、在不同缩放级别比较变体,并在无需管理页面导航的情况下探索创意。不同的缩放级别服务于不同目的:100% 以上用于像素级工作,25-50% 用于页面级审查,低于 10% 用于鸟瞰式导航。


参考来源