pencil-ui-design
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePencil MCP 工业级 UI 设计 Skills
Pencil MCP 工业级 UI 设计 Skills
本 Skills 提供了一套工业级标准的 UI 设计规范,用于 Pencil MCP 设计工作。
本 Skills 提供了一套工业级标准的 UI 设计规范,用于 Pencil MCP 设计工作。
快速开始
快速开始
1. 初始化设计系统变量
1. 初始化设计系统变量
在开始设计前,先设置设计系统变量:
javascript
mcp_pencil_set_variables({
filePath: "<your-file.pen>",
variables: {
// 参考 design-tokens.json 中的完整变量定义
}
})在开始设计前,先设置设计系统变量:
javascript
mcp_pencil_set_variables({
filePath: "<your-file.pen>",
variables: {
// 参考 design-tokens.json 中的完整变量定义
}
})2. 创建可复用组件
2. 创建可复用组件
使用 创建组件,通过 复用:
reusable: truerefjavascript
// 创建组件
buttonPrimary=I(document, {type: "frame", reusable: true, name: "Button/Primary", ...})
// 使用组件
btn1=I(someParent, {type: "ref", ref: "buttonPrimary"})使用 创建组件,通过 复用:
reusable: truerefjavascript
// 创建组件
buttonPrimary=I(document, {type: "frame", reusable: true, name: "Button/Primary", ...})
// 使用组件
btn1=I(someParent, {type: "ref", ref: "buttonPrimary"})设计系统规范
设计系统规范
颜色系统 (Color Tokens)
颜色系统 (Color Tokens)
| 变量名 | Light Mode | Dark Mode | 用途 |
|---|---|---|---|
| | | 页面背景 |
| | | 主文本 |
| | | 卡片背景 |
| | | 卡片文本 |
| | | 次要背景 |
| | | 次要文本 |
| | | 边框 |
| | | 主按钮 |
| | | 主按钮文本 |
| | | 次按钮 |
| | | 强调色 |
| | | 危险操作 |
| | | Focus ring |
| 变量名 | Light Mode | Dark Mode | 用途 |
|---|---|---|---|
| | | 页面背景 |
| | | 主文本 |
| | | 卡片背景 |
| | | 卡片文本 |
| | | 次要背景 |
| | | 次要文本 |
| | | 边框 |
| | | 主按钮 |
| | | 主按钮文本 |
| | | 次按钮 |
| | | 强调色 |
| | | 危险操作 |
| | | Focus ring |
字体层级 (Typography Scale)
字体层级 (Typography Scale)
| 层级 | 大小 | 字重 | 行高 | 用途 |
|---|---|---|---|---|
| Display | 36px | 700 | 1.2 | 大标题 |
| H1 | 24px | 600 | 1.3 | 页面标题 |
| H2 | 20px | 600 | 1.4 | 区块标题 |
| H3 | 18px | 600 | 1.4 | 卡片标题 |
| Body | 14px | 400 | 1.5 | 正文 |
| Small | 12px | 400 | 1.4 | 辅助文本 |
| Caption | 10px | 500 | 1.3 | 标签 |
推荐字体: (英文), (中文)
InterNoto Sans SC| 层级 | 大小 | 字重 | 行高 | 用途 |
|---|---|---|---|---|
| Display | 36px | 700 | 1.2 | 大标题 |
| H1 | 24px | 600 | 1.3 | 页面标题 |
| H2 | 20px | 600 | 1.4 | 区块标题 |
| H3 | 18px | 600 | 1.4 | 卡片标题 |
| Body | 14px | 400 | 1.5 | 正文 |
| Small | 12px | 400 | 1.4 | 辅助文本 |
| Caption | 10px | 500 | 1.3 | 标签 |
推荐字体: (英文), (中文)
InterNoto Sans SC间距系统 (Spacing)
间距系统 (Spacing)
基于 4px 网格:
- : 4px
xs - : 8px
sm - : 12px
md - : 16px
lg - : 24px
xl - : 32px
2xl - : 48px
3xl
基于 4px 网格:
- : 4px
xs - : 8px
sm - : 12px
md - : 16px
lg - : 24px
xl - : 32px
2xl - : 48px
3xl
圆角规范 (Border Radius)
圆角规范 (Border Radius)
| 变量 | 值 | 用途 |
|---|---|---|
| 6px | 小元素 (Badge, Chip) |
| 8px | 按钮、输入框 |
| 12px | 卡片、弹窗 |
| 16px | 大卡片 |
| 9999px | 圆形头像 |
| 变量 | 值 | 用途 |
|---|---|---|
| 6px | 小元素 (Badge, Chip) |
| 8px | 按钮、输入框 |
| 12px | 卡片、弹窗 |
| 16px | 大卡片 |
| 9999px | 圆形头像 |
阴影系统 (Shadows)
阴影系统 (Shadows)
json
{
"shadow-sm": {
"type": "shadow",
"shadowType": "outer",
"color": "#0000000D",
"blur": 2,
"offset": {"x": 0, "y": 1}
},
"shadow-md": {
"type": "shadow",
"shadowType": "outer",
"color": "#0000000A",
"blur": 6,
"offset": {"x": 0, "y": 4}
},
"shadow-lg": {
"type": "shadow",
"shadowType": "outer",
"color": "#00000014",
"blur": 15,
"offset": {"x": 0, "y": 8}
}
}json
{
"shadow-sm": {
"type": "shadow",
"shadowType": "outer",
"color": "#0000000D",
"blur": 2,
"offset": {"x": 0, "y": 1}
},
"shadow-md": {
"type": "shadow",
"shadowType": "outer",
"color": "#0000000A",
"blur": 6,
"offset": {"x": 0, "y": 4}
},
"shadow-lg": {
"type": "shadow",
"shadowType": "outer",
"color": "#00000014",
"blur": 15,
"offset": {"x": 0, "y": 8}
}
}组件规范
组件规范
Button 按钮
Button 按钮
Primary Button
Primary Button
json
{
"type": "frame",
"name": "Button/Primary",
"reusable": true,
"height": 40,
"layout": "horizontal",
"padding": [16, 10],
"gap": 8,
"alignItems": "center",
"justifyContent": "center",
"fill": "#18181B",
"cornerRadius": 8,
"effect": {
"type": "shadow",
"shadowType": "outer",
"color": "#0000001A",
"blur": 2,
"offset": {"x": 0, "y": 1}
}
}
// 文本: fill="#FFFFFF", fontFamily="Inter", fontSize=14, fontWeight=500json
{
"type": "frame",
"name": "Button/Primary",
"reusable": true,
"height": 40,
"layout": "horizontal",
"padding": [16, 10],
"gap": 8,
"alignItems": "center",
"justifyContent": "center",
"fill": "#18181B",
"cornerRadius": 8,
"effect": {
"type": "shadow",
"shadowType": "outer",
"color": "#0000001A",
"blur": 2,
"offset": {"x": 0, "y": 1}
}
}
// 文本: fill="#FFFFFF", fontFamily="Inter", fontSize=14, fontWeight=500Secondary Button
Secondary Button
json
{
"fill": "#F4F4F5",
"stroke": "#E4E4E7",
"strokeThickness": 1,
"cornerRadius": 8
}
// 文本: fill="#18181B"json
{
"fill": "#F4F4F5",
"stroke": "#E4E4E7",
"strokeThickness": 1,
"cornerRadius": 8
}
// 文本: fill="#18181B"Ghost Button
Ghost Button
json
{
"fill": "transparent",
"cornerRadius": 8
}
// Hover: fill="#F4F4F5"json
{
"fill": "transparent",
"cornerRadius": 8
}
// Hover: fill="#F4F4F5"Destructive Button
Destructive Button
json
{
"fill": "#EF4444",
"cornerRadius": 8
}
// 文本: fill="#FFFFFF"json
{
"fill": "#EF4444",
"cornerRadius": 8
}
// 文本: fill="#FFFFFF"Card 卡片
Card 卡片
json
{
"type": "frame",
"name": "Card",
"reusable": true,
"layout": "vertical",
"padding": 16,
"gap": 12,
"fill": "#FFFFFF",
"stroke": "#E4E4E7",
"strokeThickness": 1,
"cornerRadius": 12,
"effect": {
"type": "shadow",
"shadowType": "outer",
"color": "#0000000A",
"blur": 4,
"offset": {"x": 0, "y": 2}
}
}json
{
"type": "frame",
"name": "Card",
"reusable": true,
"layout": "vertical",
"padding": 16,
"gap": 12,
"fill": "#FFFFFF",
"stroke": "#E4E4E7",
"strokeThickness": 1,
"cornerRadius": 12,
"effect": {
"type": "shadow",
"shadowType": "outer",
"color": "#0000000A",
"blur": 4,
"offset": {"x": 0, "y": 2}
}
}Input 输入框
Input 输入框
json
{
"type": "frame",
"name": "Input",
"reusable": true,
"height": 40,
"layout": "horizontal",
"padding": [12, 10],
"gap": 8,
"alignItems": "center",
"fill": "#FFFFFF",
"stroke": "#E4E4E7",
"strokeThickness": 1,
"cornerRadius": 8
}
// Focus 状态: stroke="#18181B", strokeThickness=2json
{
"type": "frame",
"name": "Input",
"reusable": true,
"height": 40,
"layout": "horizontal",
"padding": [12, 10],
"gap": 8,
"alignItems": "center",
"fill": "#FFFFFF",
"stroke": "#E4E4E7",
"strokeThickness": 1,
"cornerRadius": 8
}
// Focus 状态: stroke="#18181B", strokeThickness=2Avatar 头像
Avatar 头像
json
{
"type": "frame",
"name": "Avatar",
"reusable": true,
"width": 40,
"height": 40,
"cornerRadius": 9999,
"fill": "#F4F4F5",
"layout": "vertical",
"alignItems": "center",
"justifyContent": "center"
}json
{
"type": "frame",
"name": "Avatar",
"reusable": true,
"width": 40,
"height": 40,
"cornerRadius": 9999,
"fill": "#F4F4F5",
"layout": "vertical",
"alignItems": "center",
"justifyContent": "center"
}Badge 徽章
Badge 徽章
json
{
"type": "frame",
"name": "Badge",
"reusable": true,
"height": 22,
"layout": "horizontal",
"padding": [6, 8],
"alignItems": "center",
"justifyContent": "center",
"fill": "#F4F4F5",
"stroke": "#E4E4E7",
"strokeThickness": 1,
"cornerRadius": 6
}
// 文本: fontSize=10, fontWeight=500json
{
"type": "frame",
"name": "Badge",
"reusable": true,
"height": 22,
"layout": "horizontal",
"padding": [6, 8],
"alignItems": "center",
"justifyContent": "center",
"fill": "#F4F4F5",
"stroke": "#E4E4E7",
"strokeThickness": 1,
"cornerRadius": 6
}
// 文本: fontSize=10, fontWeight=500图标规范
图标规范
⚠️ 重要: Pencil MCP 使用图标字体,不是 Lucide!Material Symbols Rounded
⚠️ 重要: Pencil MCP 使用图标字体,不是 Lucide!Material Symbols Rounded
基本用法
基本用法
json
{
"type": "icon_font",
"iconFontFamily": "Material Symbols Rounded",
"iconFontName": "home",
"fontSize": 24,
"width": 24,
"height": 24,
"fill": "#71717A"
}注意: 必须同时设置、fontSize和width属性,否则图标可能不显示!height
json
{
"type": "icon_font",
"iconFontFamily": "Material Symbols Rounded",
"iconFontName": "home",
"fontSize": 24,
"width": 24,
"height": 24,
"fill": "#71717A"
}注意: 必须同时设置、fontSize和width属性,否则图标可能不显示!height
常用图标速查表
常用图标速查表
| 类别 | 图标名称 | 用途 |
|---|---|---|
| 导航 | | 导航和菜单 |
| 操作 | | 常用操作 |
| 状态 | | 状态提示 |
| 媒体 | | 音频视频 |
| 社交 | | 社交功能 |
| 文件 | | 文件文档 |
| 通信 | | 消息通知 |
| 游戏 | | 游戏奖励 |
| 学习 | | 教育学习 |
| 类别 | 图标名称 | 用途 |
|---|---|---|
| 导航 | | 导航和菜单 |
| 操作 | | 常用操作 |
| 状态 | | 状态提示 |
| 媒体 | | 音频视频 |
| 社交 | | 社交功能 |
| 文件 | | 文件文档 |
| 通信 | | 消息通知 |
| 游戏 | | 游戏奖励 |
| 学习 | | 教育学习 |
图标尺寸规范
图标尺寸规范
| 尺寸 | 值 | 用途 |
|---|---|---|
| XS | 16px | 辅助小图标、徽章内 |
| SM | 20px | 按钮内图标、列表图标 |
| MD | 24px | 标准图标、导航图标 |
| LG | 32px | 大按钮、空状态图标 |
| XL | 48px | 特殊强调、卡片主图标 |
| 尺寸 | 值 | 用途 |
|---|---|---|
| XS | 16px | 辅助小图标、徽章内 |
| SM | 20px | 按钮内图标、列表图标 |
| MD | 24px | 标准图标、导航图标 |
| LG | 32px | 大按钮、空状态图标 |
| XL | 48px | 特殊强调、卡片主图标 |
完整示例
完整示例
javascript
// 创建一个带图标的按钮
iconBtn=I(parent, {
type: "frame",
width: 48,
height: 48,
layout: "vertical",
alignItems: "center",
justifyContent: "center",
fill: "#1E2A2F",
cornerRadius: 9999
})
icon=I(iconBtn, {
type: "icon_font",
iconFontFamily: "Material Symbols Rounded",
iconFontName: "add",
fontSize: 24,
width: 24,
height: 24,
fill: "#FFFFFF"
})javascript
// 创建一个带图标的按钮
iconBtn=I(parent, {
type: "frame",
width: 48,
height: 48,
layout: "vertical",
alignItems: "center",
justifyContent: "center",
fill: "#1E2A2F",
cornerRadius: 9999
})
icon=I(iconBtn, {
type: "icon_font",
iconFontFamily: "Material Symbols Rounded",
iconFontName: "add",
fontSize: 24,
width: 24,
height: 24,
fill: "#FFFFFF"
})图片素材处理
图片素材处理
使用 G() 操作生成图片
使用 G() 操作生成图片
Pencil MCP 提供 操作来生成或获取图片,支持两种方式:
G()Pencil MCP 提供 操作来生成或获取图片,支持两种方式:
G()AI 生成图片 (推荐用于插画、头像、图标)
AI 生成图片 (推荐用于插画、头像、图标)
javascript
// 先创建一个 frame 容器
avatar=I(parent, {type: "frame", width: 48, height: 48, cornerRadius: 9999})
// 使用 AI 生成图片填充
G(avatar, "ai", "cute cartoon boy avatar, friendly smile, warm colors, children illustration style")javascript
// 先创建一个 frame 容器
avatar=I(parent, {type: "frame", width: 48, height: 48, cornerRadius: 9999})
// 使用 AI 生成图片填充
G(avatar, "ai", "cute cartoon boy avatar, friendly smile, warm colors, children illustration style")Stock 图片 (推荐用于真实照片)
Stock 图片 (推荐用于真实照片)
javascript
// 获取 Unsplash 图片
heroImg=I(parent, {type: "frame", width: 400, height: 300})
G(heroImg, "stock", "modern office workspace laptop natural light")javascript
// 获取 Unsplash 图片
heroImg=I(parent, {type: "frame", width: 400, height: 300})
G(heroImg, "stock", "modern office workspace laptop natural light")Prompt 编写技巧
Prompt 编写技巧
| 类型 | 好的 Prompt | 不好的 Prompt |
|---|---|---|
| 头像 | "cute cartoon boy, round face, brown hair, warm yellow background, simple illustration" | "boy" |
| 图标 | "isometric cloud server icon, soft gradients, minimalist" | "server" |
| 背景 | "abstract gradient purple blue, soft blur, dreamy atmosphere" | "background" |
| 类型 | 好的 Prompt | 不好的 Prompt |
|---|---|---|
| 头像 | "cute cartoon boy, round face, brown hair, warm yellow background, simple illustration" | "boy" |
| 图标 | "isometric cloud server icon, soft gradients, minimalist" | "server" |
| 背景 | "abstract gradient purple blue, soft blur, dreamy atmosphere" | "background" |
图片使用注意事项
图片使用注意事项
- 没有 image 节点类型 - 图片只能作为 frame/rectangle 的填充
- 先创建容器 - 必须先用 创建 frame,再用
I()应用图片G() - 设置正确尺寸 - frame 的 width/height 决定显示尺寸
- 圆角裁剪 - 设置 可实现圆形图片
cornerRadius: 9999
- 没有 image 节点类型 - 图片只能作为 frame/rectangle 的填充
- 先创建容器 - 必须先用 创建 frame,再用
I()应用图片G() - 设置正确尺寸 - frame 的 width/height 决定显示尺寸
- 圆角裁剪 - 设置 可实现圆形图片
cornerRadius: 9999
文本处理规范
文本处理规范
防止文本溢出
防止文本溢出
当文本内容较长时,必须设置以下属性防止溢出:
json
{
"type": "text",
"content": "这是一段很长的文本内容...",
"width": "fill_container",
"textGrowth": "fixed-width",
"lineHeight": 1.5
}当文本内容较长时,必须设置以下属性防止溢出:
json
{
"type": "text",
"content": "这是一段很长的文本内容...",
"width": "fill_container",
"textGrowth": "fixed-width",
"lineHeight": 1.5
}textGrowth 属性说明
textGrowth 属性说明
| 值 | 说明 | 适用场景 |
|---|---|---|
| 文本根据内容自动调整宽度(默认) | 短文本、标签 |
| 固定宽度,超出自动换行 | 段落、描述文本 |
| 固定宽度,超出显示省略号 | 列表项标题 |
| 值 | 说明 | 适用场景 |
|---|---|---|
| 文本根据内容自动调整宽度(默认) | 短文本、标签 |
| 固定宽度,超出自动换行 | 段落、描述文本 |
| 固定宽度,超出显示省略号 | 列表项标题 |
常见文本样式
常见文本样式
javascript
// 段落文本 (自动换行)
paragraph=I(parent, {
type: "text",
content: "这是一段较长的描述文本,需要自动换行显示。",
width: "fill_container",
textGrowth: "fixed-width",
fontSize: 14,
lineHeight: 1.5,
fill: "#71717A"
})
// 标题文本 (单行)
title=I(parent, {
type: "text",
content: "标题文本",
fontSize: 18,
fontWeight: 600,
fill: "#1E2A2F"
})javascript
// 段落文本 (自动换行)
paragraph=I(parent, {
type: "text",
content: "这是一段较长的描述文本,需要自动换行显示。",
width: "fill_container",
textGrowth: "fixed-width",
fontSize: 14,
lineHeight: 1.5,
fill: "#71717A"
})
// 标题文本 (单行)
title=I(parent, {
type: "text",
content: "标题文本",
fontSize: 18,
fontWeight: 600,
fill: "#1E2A2F"
})设计工作流
设计工作流
第一步:设置设计系统
第一步:设置设计系统
- 打开或创建 .pen 文件
- 使用 设置颜色变量
mcp_pencil_set_variables - 创建可复用组件
- 打开或创建 .pen 文件
- 使用 设置颜色变量
mcp_pencil_set_variables - 创建可复用组件
第二步:创建页面结构
第二步:创建页面结构
- 创建页面 Frame (390x844 for iPhone)
- 设置背景色
#FAFAFA - 使用垂直布局
layout: "vertical"
- 创建页面 Frame (390x844 for iPhone)
- 设置背景色
#FAFAFA - 使用垂直布局
layout: "vertical"
第三步:使用组件构建 UI
第三步:使用组件构建 UI
- 通过 引用可复用组件
ref - 使用 覆盖特定属性
U() - 保持设计一致性
- 通过 引用可复用组件
ref - 使用 覆盖特定属性
U() - 保持设计一致性
第四步:验证设计
第四步:验证设计
- 使用 截图检查
mcp_pencil_get_screenshot - 验证对齐、间距、颜色
- 检查字体和图标一致性
- 使用 截图检查
mcp_pencil_get_screenshot - 验证对齐、间距、颜色
- 检查字体和图标一致性
第五步:迭代优化
第五步:迭代优化
- 根据反馈调整细节
- 确保无视觉错误
- 输出最终设计稿
- 根据反馈调整细节
- 确保无视觉错误
- 输出最终设计稿
批量更新样式
批量更新样式
使用 批量替换属性:
mcp_pencil_replace_all_matching_propertiesjavascript
mcp_pencil_replace_all_matching_properties({
filePath: "design.pen",
parents: ["pageId1", "pageId2"],
properties: {
"fillColor": {"#FFF9F2": "#FAFAFA"},
"fontFamily": {"Fredoka": "Inter"},
"cornerRadius": {24: 12}
}
})使用 批量替换属性:
mcp_pencil_replace_all_matching_propertiesjavascript
mcp_pencil_replace_all_matching_properties({
filePath: "design.pen",
parents: ["pageId1", "pageId2"],
properties: {
"fillColor": {"#FFF9F2": "#FAFAFA"},
"fontFamily": {"Fredoka": "Inter"},
"cornerRadius": {24: 12}
}
})质量检查清单
质量检查清单
- 所有页面背景统一 ()
#FAFAFA - 所有卡片有边框 ()
1px #E4E4E7 - 阴影效果一致 (blur 2-6px)
- 按钮圆角统一 (8px)
- 字体统一 (Inter)
- 图标库统一 (Lucide)
- 字体层级正确 (12/14/16/18/20/24px)
- 间距遵循 4px 网格
- 所有页面背景统一 ()
#FAFAFA - 所有卡片有边框 ()
1px #E4E4E7 - 阴影效果一致 (blur 2-6px)
- 按钮圆角统一 (8px)
- 字体统一 (Inter)
- 图标库统一 (Lucide)
- 字体层级正确 (12/14/16/18/20/24px)
- 间距遵循 4px 网格