Figma: 协作画布
Figma如何构建实时多人设计:存在指示器、无限画布、Dev Mode和设计令牌。包含CSS和JavaScript实现模式。
Figma:协作画布
"在 Figma 的理念中,我们希望让 AI 也能实现多人协作。协作始终是我们一切工作的核心。" — Figma 团队
Figma 将设计从一项独立的技艺转变为团队运动。作为首款支持实时协作编辑的设计工具,Figma 证明了复杂的创意工具也可以像 Google Docs 一样流畅——同时保持设计师所要求的精确度。
为什么 Figma 如此重要
Figma 不仅仅是在设计工具中添加了多人协作功能,而是重新构想了设计的工作方式。通过将协作融入产品根基,Figma 改变了工作流程、团队协作模式以及整个设计到开发的交付流程。
核心成就: - 首款支持实时多人编辑的设计工具 - 开创了"无限画布"作为 UI 范式 - 让设计系统变得人人可用 - 通过 Dev Mode 架起设计与开发之间的桥梁 - 在协作理念上打造了价值 200 亿美元的创意帝国
核心要点
- 多人协作需要简洁 - Figma 构建了一套比操作变换更简单的自研方案,因为更简单的系统更易于调试和维护
- 无限画布激发探索 - 不同于基于页面的工具,开放式画布鼓励迭代,避免了人为的限制
- 上下文感知的界面降低认知负荷 - 工具栏和面板根据选择自适应,只显示相关的控件
- 设计令牌连接设计与代码 - 从原始值 → 语义化 → 组件层级的变量体系,为设计师和开发者创造了共同语言
- 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>
相关原则
- 格式塔:邻近与分组:面板组织
- 视觉层次:图层列表设计
- 色彩理论:功能性色彩:状态与选择
- 间距与节奏:8px 网格系统
常见问题
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% 用于鸟瞰式导航。