diff --git a/docs/03-组件设计规范/01-设计系统概述.md b/docs/03-组件设计规范/01-设计系统概述.md new file mode 100644 index 0000000..b97c788 --- /dev/null +++ b/docs/03-组件设计规范/01-设计系统概述.md @@ -0,0 +1,437 @@ +# 设计系统概述 + +本文档介绍阑山桌面的设计系统理念、设计原则和设计工作流程。 + +## 🎯 设计目标 + +阑山桌面的设计系统旨在: + +1. **统一视觉语言** - 确保所有组件拥有一致的外观和感觉 +2. **提升开发效率** - 提供开箱即用的设计资源和组件 +3. **保证品质** - 通过规范确保组件的专业性和美观度 +4. **灵活扩展** - 允许开发者在规范内发挥创意 + +## 🏛️ 设计原则 + +### 1. 简约至上(Simplicity First) + +**核心思想**: 少即是多,去除一切不必要的视觉元素。 + +**实践方法**: +- ✅ 只展示最关键的信息 +- ✅ 使用简洁的图标和符号 +- ✅ 避免过度装饰 +- ❌ 不要堆砌大量信息 +- ❌ 避免使用过多颜色 + +**示例对比**: + +``` +❌ 过于复杂: +┌─────────────────────────────────┐ +│ ═══ 天气预报系统 v2.0 ═══ │ +│ ┌─────┐ 北京市朝阳区 │ +│ │ ☀️ │ 温度: 25°C │ +│ │ │ 湿度: 60% │ +│ └─────┘ 风速: 3m/s │ +│ 气压: 1013hPa │ +│ 能见度: 10km │ +│ [更新] [设置] [关于] [帮助] │ +└─────────────────────────────────┘ + +✅ 简洁设计: +┌──────────────────┐ +│ 📍 北京 │ +│ │ +│ ☀️ │ +│ 25°C │ +│ 晴 │ +│ │ +│ 🔄 ⚙️ │ +└──────────────────┘ +``` + +### 2. 融入系统(System Integration) + +**核心思想**: 组件应该像 Windows 11 原生应用一样自然。 + +**设计要求**: +- ✅ 使用 Fluent Design 设计语言 +- ✅ 遵循 Windows 11 视觉规范 +- ✅ 使用系统字体(Microsoft YaHei UI / Segoe UI) +- ✅ 适配系统主题(亮色/暗色) +- ✅ 使用标准的圆角和阴影 + +**Windows 11 Fluent Design 元素**: +- 🎨 **Mica 材质** - 半透明背景,融入桌面 +- 🌊 **Acrylic 亚克力** - 模糊背景,增加层次 +- 🔲 **圆角矩形** - 柔和的 8px 圆角 +- 💫 **微妙阴影** - 轻量的投影效果 +- 🎭 **主题感知** - 响应系统主题变化 + +### 3. 层级清晰(Clear Hierarchy) + +**核心思想**: 用户应该立即知道什么最重要。 + +**视觉层级工具**: + +| 层级 | 字号 | 字重 | 颜色 | 用途 | +|-----|------|------|------|------| +| **一级** | 32-48px | Bold | 主要文本色 | 核心数据(温度、时间) | +| **二级** | 16-18px | SemiBold | 主要文本色 | 标题、位置 | +| **三级** | 14px | Regular | 主要文本色 | 正文内容 | +| **四级** | 12px | Regular | 次要文本色 | 辅助信息、说明 | + +**示例**: + +``` +┌──────────────────────────┐ +│ 📍 北京 [一级标题] +│ │ +│ ☀️ │ +│ 25°C [核心数据] +│ ↑ 30° ↓ 18° [二级数据] +│ │ +│ 晴天,空气质量良好 [辅助信息] +│ │ +│ 更新时间: 14:30 [次要信息] +└──────────────────────────┘ +``` + +### 4. 即时反馈(Instant Feedback) + +**核心思想**: 所有交互都应该有立即的视觉反馈。 + +**反馈类型**: + +**悬停状态(Hover)**: +``` +正常: Background = #FFFFFF +悬停: Background = #F3F3F3 ← 轻微变暗 +``` + +**按下状态(Pressed)**: +``` +正常: Background = #FFFFFF +按下: Background = #E8E8E8 ← 明显变暗 +``` + +**加载状态(Loading)**: +``` +┌──────────────┐ +│ ⏳ 加载中... │ ← 动画 + 文字提示 +└──────────────┘ +``` + +**错误状态(Error)**: +``` +┌──────────────┐ +│ ❌ 加载失败 │ ← 红色图标 + 说明 +│ 点击重试 │ +└──────────────┘ +``` + +### 5. 无障碍优先(Accessibility First) + +**核心思想**: 设计应该对所有用户友好。 + +**无障碍要求**: + +**色彩对比度**: +- ✅ 正文文字对比度 ≥ 4.5:1 +- ✅ 大号文字对比度 ≥ 3:1 +- ✅ UI 元素对比度 ≥ 3:1 + +**字体大小**: +- ✅ 最小字号 12px(辅助信息) +- ✅ 正文字号 14px +- ✅ 标题字号 ≥ 16px + +**交互区域**: +- ✅ 按钮最小尺寸 32×32px +- ✅ 可点击区域清晰可见 +- ✅ 提供悬停提示(Tooltip) + +**示例 - 对比度检查**: + +``` +亮色主题: +✅ 黑色文字 (#1C1C1C) on 白色背景 (#FFFFFF) = 16.1:1 +✅ 灰色文字 (#616161) on 白色背景 (#FFFFFF) = 5.7:1 +❌ 浅灰文字 (#CCCCCC) on 白色背景 (#FFFFFF) = 1.6:1 [不合格] + +暗色主题: +✅ 白色文字 (#FFFFFF) on 深灰背景 (#1C1C1C) = 16.1:1 +✅ 浅灰文字 (#EBEBEB) on 深灰背景 (#1C1C1C) = 13.1:1 +``` + +## 🎨 设计语言 + +### 视觉元素 + +#### 形状 +- **圆角矩形**: 标准圆角 8px,营造柔和感 +- **图标**: 圆润风格,线条粗细一致 +- **分割线**: 1px 细线,颜色使用边框色 + +#### 颜色 +- **中性为主**: 大量使用灰度色 +- **强调色少**: 蓝色仅用于强调 +- **语义颜色**: 红色(错误)、绿色(成功)、橙色(警告) + +#### 空间 +- **留白充足**: 不要填满所有空间 +- **对齐严格**: 所有元素精确对齐 +- **间距统一**: 使用 4px 基础网格 + +### 动效 + +#### 时长 +- **微交互**: 150ms(悬停、点击) +- **过渡动画**: 300ms(展开、收起) +- **页面切换**: 500ms(进入、退出) + +#### 缓动函数 +```csharp +// 标准缓动 +Easing.CubicEaseOut + +// 弹性效果 +Easing.BackEaseOut + +// 线性(加载动画) +Easing.Linear +``` + +#### 动画示例 + +**悬停动画**: +```xml + + + +``` + +## 🔄 设计工作流 + +### 1. 需求分析 + +**问自己这些问题**: +- ❓ 这个组件要解决什么问题? +- ❓ 用户最关心的信息是什么? +- ❓ 组件需要多久更新一次? +- ❓ 用户会如何与它交互? + +**输出**: 功能清单和信息优先级 + +### 2. 信息架构 + +**定义信息层级**: +``` +层级 1: 核心数据(大字号) + └─ 例如: 温度、时间 + +层级 2: 重要信息(中字号) + └─ 例如: 位置、日期 + +层级 3: 辅助信息(小字号) + └─ 例如: 更新时间、详细说明 +``` + +**输出**: 信息层级图 + +### 3. 布局设计 + +**选择布局模式**: +- **单列布局**: 简单信息展示(时钟、天气) +- **网格布局**: 多项数据展示(系统监控) +- **分栏布局**: 对比信息展示(股票涨跌) + +**遵循规范**: +- ✅ 16px 安全边距 +- ✅ 8px 元素间距 +- ✅ 使用 4px 基础网格 + +**输出**: 布局草图 + +### 4. 视觉设计 + +**应用设计系统**: +1. 使用系统颜色资源 +2. 使用系统字体和字号 +3. 添加标准圆角和阴影 +4. 确保亮色和暗色主题适配 + +**输出**: 高保真设计稿 + +### 5. 开发实现 + +**编写 AXAML 代码**: +```xml + + + +``` + +**输出**: 可运行的组件代码 + +### 6. 测试验证 + +**测试清单**: +- [ ] 亮色主题显示正常 +- [ ] 暗色主题显示正常 +- [ ] 不同尺寸下布局正确 +- [ ] 长文本正确处理 +- [ ] 错误状态显示友好 +- [ ] 加载状态有反馈 +- [ ] 交互流畅无卡顿 + +**输出**: 测试通过的组件 + +### 7. 文档编写 + +**文档内容**: +- 组件功能说明 +- 配置选项说明 +- 截图和演示 +- 已知问题和限制 + +**输出**: 完整的组件文档 + +## 🛠️ 设计工具 + +### 推荐工具 + +| 工具 | 用途 | 链接 | +|-----|------|------| +| **Figma** | UI 设计 | https://figma.com | +| **Sketch** | UI 设计(Mac) | https://sketch.com | +| **Adobe XD** | UI 设计 | https://adobe.com/xd | +| **ColorSpace** | 颜色方案 | https://mycolor.space | +| **WhoCanUse** | 对比度检查 | https://whocanuse.com | + +### 设计资源 + +**Windows 11 设计资源**: +- [Figma Toolkit](https://aka.ms/windows11-figma) +- [Design Guidelines](https://learn.microsoft.com/windows/apps/design/) + +**图标资源**: +- [Fluent UI Icons](https://aka.ms/fluentui-icons) +- [Iconify](https://iconify.design/) +- [Emoji](https://emojipedia.org/) + +## 📏 设计标准 + +### 组件尺寸标准 + +| 类型 | 宽度 | 高度 | 说明 | +|-----|------|------|------| +| **小型组件** | 120-150px | 80-100px | 单一信息 | +| **中型组件** | 200-300px | 150-250px | 常规信息 | +| **大型组件** | 350-500px | 300-400px | 丰富信息 | +| **超大组件** | 500px+ | 400px+ | 复杂功能 | + +### 文本标准 + +| 场景 | 字号 | 行高 | 字重 | +|-----|------|------|------| +| **超大数字** | 48px | 56px | Bold (700) | +| **大数字** | 32px | 40px | Bold (700) | +| **大标题** | 24px | 32px | SemiBold (600) | +| **标题** | 18px | 24px | SemiBold (600) | +| **小标题** | 16px | 22px | SemiBold (600) | +| **正文** | 14px | 20px | Regular (400) | +| **辅助文字** | 12px | 18px | Regular (400) | + +### 间距标准 + +| 用途 | 值 | 使用场景 | +|-----|---|---------| +| **安全边距** | 16px | 内容到组件边缘 | +| **区块间距** | 16px | 不同功能区之间 | +| **元素间距** | 8px | 相关元素之间 | +| **紧密间距** | 4px | 图标和文字之间 | +| **最小间距** | 2px | 边框到内容 | + +## ✨ 最佳实践 + +### DO - 应该这样做 + +``` +✅ 使用系统提供的设计资源 +✅ 保持视觉一致性 +✅ 注重信息层级 +✅ 测试两种主题 +✅ 考虑边缘情况(长文本、加载失败等) +✅ 提供清晰的交互反馈 +✅ 遵循无障碍标准 +✅ 保持代码整洁 +``` + +### DON'T - 不应该这样做 + +``` +❌ 硬编码颜色值 +❌ 忽略暗色主题 +❌ 使用过小的字号 +❌ 堆砌过多信息 +❌ 使用不统一的间距 +❌ 忽略加载和错误状态 +❌ 使用低对比度的颜色组合 +❌ 复制粘贴未测试的代码 +``` + +## 🎓 设计进阶 + +### 从优秀设计中学习 + +**观察 Windows 11 原生应用**: +- 天气应用 +- 日历应用 +- 小组件面板 +- 任务栏图标 + +**分析其设计**: +- 如何组织信息? +- 如何使用颜色? +- 如何处理交互? +- 如何适配主题? + +### 迭代改进 + +**收集反馈**: +- 自己使用一周 +- 邀请朋友试用 +- 查看使用数据 +- 倾听用户意见 + +**持续优化**: +- 简化复杂的地方 +- 增强不清晰的地方 +- 修复体验问题 +- 提升视觉质量 + +## 📖 下一步 + +- **必读**: [布局规范](03-布局规范.md) - 学习安全区域和间距系统 +- **必读**: [视觉规范](02-视觉规范.md) - 掌握颜色、字体、图标 +- **推荐**: [交互规范](04-交互规范.md) - 了解交互设计标准 +- **推荐**: [主题系统](05-主题系统.md) - 实现主题切换 + +--- + +**记住**: 好的设计是简单的、一致的、有目的的。从规范开始,在实践中成长。 diff --git a/docs/03-组件设计规范/02-视觉规范.md b/docs/03-组件设计规范/02-视觉规范.md new file mode 100644 index 0000000..56f2852 --- /dev/null +++ b/docs/03-组件设计规范/02-视觉规范.md @@ -0,0 +1,556 @@ +# 视觉规范 + +本文档详细说明组件视觉设计规范,包括颜色系统、字体排版、图标规范、阴影与圆角等。 + +## 🎨 颜色系统 + +### 设计原则 + +- **语义化** - 颜色传达明确的含义 +- **主题适配** - 完美支持亮色和暗色主题 +- **对比度** - 确保文字清晰可读 +- **一致性** - 在整个系统中保持统一 + +### 亮色主题(Light Theme) + +#### 背景色 + +| 名称 | 颜色值 | 用途 | AXAML 资源 | +|-----|--------|------|-----------| +| **主背景** | `#F3F3F3` | 桌面背景 | `DesktopBackgroundBrush` | +| **卡片背景** | `#FFFFFF` | 组件背景 | `CardBackgroundBrush` | +| **次级背景** | `#F9F9F9` | 悬停背景 | `CardBackgroundSecondaryBrush` | +| **输入框背景** | `#FFFFFF` | 输入框 | `TextBoxBackgroundBrush` | + +#### 文本色 + +| 名称 | 颜色值 | 对比度 | 用途 | AXAML 资源 | +|-----|--------|--------|------|-----------| +| **主要文本** | `#1C1C1C` | 16.1:1 | 标题、重要信息 | `TextFillColorPrimaryBrush` | +| **次要文本** | `#616161` | 5.7:1 | 正文、描述 | `TextFillColorSecondaryBrush` | +| **辅助文本** | `#8E8E8E` | 3.5:1 | 提示、说明 | `TextFillColorTertiaryBrush` | +| **禁用文本** | `#C7C7C7` | 1.9:1 | 禁用状态 | `TextFillColorDisabledBrush` | + +#### 强调色 + +| 名称 | 颜色值 | 用途 | AXAML 资源 | +|-----|--------|------|-----------| +| **主色** | `#0078D4` | 按钮、链接、选中状态 | `AccentBrush` | +| **主色悬停** | `#106EBE` | 按钮悬停 | `AccentHoverBrush` | +| **主色按下** | `#005A9E` | 按钮按下 | `AccentPressedBrush` | + +#### 语义色 + +| 名称 | 颜色值 | 用途 | AXAML 资源 | +|-----|--------|------|-----------| +| **成功** | `#107C10` | 成功提示 | `SuccessBrush` | +| **警告** | `#FF8C00` | 警告提示 | `WarningBrush` | +| **错误** | `#E81123` | 错误提示 | `ErrorBrush` | +| **信息** | `#0078D4` | 信息提示 | `InfoBrush` | + +#### 边框与分割线 + +| 名称 | 颜色值 | 用途 | AXAML 资源 | +|-----|--------|------|-----------| +| **边框** | `#E0E0E0` | 卡片边框 | `CardBorderBrush` | +| **分割线** | `#EBEBEB` | 分隔线 | `DividerBrush` | +| **输入框边框** | `#E0E0E0` | 输入框边框 | `TextBoxBorderBrush` | + +### 暗色主题(Dark Theme) + +#### 背景色 + +| 名称 | 颜色值 | 用途 | AXAML 资源 | +|-----|--------|------|-----------| +| **主背景** | `#202020` | 桌面背景 | `DesktopBackgroundBrush` | +| **卡片背景** | `#2C2C2C` | 组件背景 | `CardBackgroundBrush` | +| **次级背景** | `#343434` | 悬停背景 | `CardBackgroundSecondaryBrush` | +| **输入框背景** | `#2C2C2C` | 输入框 | `TextBoxBackgroundBrush` | + +#### 文本色 + +| 名称 | 颜色值 | 对比度 | 用途 | AXAML 资源 | +|-----|--------|--------|------|-----------| +| **主要文本** | `#FFFFFF` | 15.3:1 | 标题、重要信息 | `TextFillColorPrimaryBrush` | +| **次要文本** | `#C8C8C8` | 8.5:1 | 正文、描述 | `TextFillColorSecondaryBrush` | +| **辅助文本** | `#8E8E8E` | 4.2:1 | 提示、说明 | `TextFillColorTertiaryBrush` | +| **禁用文本** | `#5E5E5E` | 2.3:1 | 禁用状态 | `TextFillColorDisabledBrush` | + +#### 强调色 + +| 名称 | 颜色值 | 用途 | AXAML 资源 | +|-----|--------|------|-----------| +| **主色** | `#60CDFF` | 按钮、链接、选中状态 | `AccentBrush` | +| **主色悬停** | `#3DB8FF` | 按钮悬停 | `AccentHoverBrush` | +| **主色按下** | `#1AA7FF` | 按钮按下 | `AccentPressedBrush` | + +#### 语义色 + +| 名称 | 颜色值 | 用途 | AXAML 资源 | +|-----|--------|------|-----------| +| **成功** | `#6CCB5F` | 成功提示 | `SuccessBrush` | +| **警告** | `#FCE100` | 警告提示 | `WarningBrush` | +| **错误** | `#FF99A4` | 错误提示 | `ErrorBrush` | +| **信息** | `#60CDFF` | 信息提示 | `InfoBrush` | + +#### 边框与分割线 + +| 名称 | 颜色值 | 用途 | AXAML 资源 | +|-----|--------|------|-----------| +| **边框** | `#3F3F3F` | 卡片边框 | `CardBorderBrush` | +| **分割线** | `#3A3A3A` | 分隔线 | `DividerBrush` | +| **输入框边框** | `#3F3F3F` | 输入框边框 | `TextBoxBorderBrush` | + +### 颜色使用示例 + +```xml + + + + + + +``` + +#### 次要按钮(Secondary Button) + +```xml + +``` + +#### 图标按钮 + +```xml + +``` + +### 输入框状态 + +```xml + + + + + + + + + + + + + + +``` + +### 光标样式 + +```xml + + + + + + + +拖动我 + + +调整大小 + + + +``` + +## 🎬 动画与过渡 + +### 动画时长标准 + +| 类型 | 时长 | 使用场景 | +|-----|------|---------| +| **微交互** | 100-150ms | 悬停、点击 | +| **短动画** | 200-300ms | 展开、收起 | +| **中动画** | 300-500ms | 页面切换、弹出 | +| **长动画** | 500-800ms | 复杂过渡 | + +### 缓动函数(Easing) + +| 函数 | 效果 | 使用场景 | +|-----|------|---------| +| **Linear** | 线性 | 加载动画、循环动画 | +| **CubicEaseOut** | 快进慢出 | 大部分交互动画 | +| **CubicEaseIn** | 慢进快出 | 元素退出 | +| **CubicEaseInOut** | 慢进慢出 | 平滑过渡 | +| **BackEaseOut** | 回弹效果 | 强调动画 | +| **ElasticEaseOut** | 弹性效果 | 有趣的交互 | + +### 悬停动画 + +```xml + + + + + + + +``` + +### 点击动画 + +```xml + +``` + +### 展开/收起动画 + +```xml + + + + + + + + + +``` + +### 淡入/淡出动画 + +```xml + + + + + + + + + + + + + + +``` + +### 旋转动画(加载中) + +```xml + + + + + + + + + +``` + +### 脉冲动画(加载中) + +```xml + + + + + + + +``` + +## 💬 反馈机制 + +### 加载状态 + +#### 加载指示器 + +```xml + + + + + + + + + + + + + +``` + +#### 骨架屏 + +```xml + + + + + + + + + + + + + +``` + +### 错误状态 + +```xml + + + + + + + + + + + + + + + + +``` + +## 🖐️ 拖拽与调整 + +### 拖拽组件 + +组件应支持拖拽移动: + +```csharp +public class DraggableComponent : ComponentBase +{ + private Point _dragStartPoint; + private bool _isDragging; + + protected override void OnPointerPressed(PointerPressedEventArgs e) + { + _dragStartPoint = e.GetPosition(this); + _isDragging = true; + Cursor = new Cursor(StandardCursorType.SizeAll); + } + + protected override void OnPointerMoved(PointerEventArgs e) + { + if (_isDragging) + { + var currentPosition = e.GetPosition(this.Parent as Visual); + var offset = currentPosition - _dragStartPoint; + + // 更新位置 + Canvas.SetLeft(this, Canvas.GetLeft(this) + offset.X); + Canvas.SetTop(this, Canvas.GetTop(this) + offset.Y); + } + } + + protected override void OnPointerReleased(PointerReleasedEventArgs e) + { + _isDragging = false; + Cursor = new Cursor(StandardCursorType.Arrow); + + // 保存位置 + SavePosition(); + } +} +``` + +### 调整大小 + +组件应支持调整尺寸: + +```xml + + + + + + + + + + + + + + +``` + +```csharp +private void OnResizeHandlePressed(object sender, PointerPressedEventArgs e) +{ + _isResizing = true; + _resizeStartPoint = e.GetPosition(this.Parent as Visual); + _initialWidth = Width; + _initialHeight = Height; +} + +private void OnResizeHandleMoved(object sender, PointerEventArgs e) +{ + if (_isResizing) + { + var currentPoint = e.GetPosition(this.Parent as Visual); + var delta = currentPoint - _resizeStartPoint; + + Width = Math.Max(MinWidth, _initialWidth + delta.X); + Height = Math.Max(MinHeight, _initialHeight + delta.Y); + } +} + +private void OnResizeHandleReleased(object sender, PointerReleasedEventArgs e) +{ + _isResizing = false; + SaveSize(); +} +``` + +### 拖拽反馈 + +```xml + + + + +``` + +## ⌨️ 键盘交互 + +### 快捷键 + +常用快捷键: + +| 快捷键 | 操作 | +|-------|------| +| **Enter** | 确认、提交 | +| **Esc** | 取消、关闭 | +| **Tab** | 焦点切换 | +| **Space** | 激活按钮 | +| **方向键** | 导航、选择 | +| **Ctrl+S** | 保存 | +| **Ctrl+Z** | 撤销 | +| **Ctrl+Y** | 重做 | + +### 实现快捷键 + +```csharp +protected override void OnKeyDown(KeyEventArgs e) +{ + switch (e.Key) + { + case Key.Enter: + ConfirmAction(); + e.Handled = true; + break; + + case Key.Escape: + CancelAction(); + e.Handled = true; + break; + + case Key.S when e.KeyModifiers.HasFlag(KeyModifiers.Control): + SaveAction(); + e.Handled = true; + break; + } + + base.OnKeyDown(e); +} +``` + +### 焦点管理 + +```xml + + + + +private void OnLoaded(object sender, RoutedEventArgs e) +{ + UsernameBox.Focus(); +} + + + + + +