Files
nanocode/net-games/docs/UI_DESIGN_GUIDELINES.md
Ubuntu 32b43f85bd a
2026-07-03 16:58:28 +08:00

35 KiB
Raw Permalink Blame History

Net-Games & Happy-Games UI 设计规范

设计风格: 深色游戏风 (Dark Gaming Theme)
设计哲学: 沉浸式游戏体验 + 清晰的信息层级
版本: v1.0
更新日期: 2026-04-09


1. 设计理念

1.1 核心设计原则

我们的游戏平台采用深色游戏风格,设计理念基于以下核心原则:

原则 说明 设计意图
沉浸式体验 深色背景减少视觉疲劳,让玩家专注于游戏内容 长时间游戏不疲劳
清晰层级 通过颜色、大小、位置区分信息重要性 快速获取关键信息
即时反馈 所有交互元素都有明确的视觉反馈 增强操控感
品牌一致性 跨游戏保持统一的视觉语言 降低学习成本
响应式设计 适配从手机到桌面的各种设备 随时随地游戏

1.2 与 Neobrutalism 的对比

参考了 personal-blog 的新粗野主义设计,但游戏平台采用了不同的风格:

特性 博客 (Neobrutalism) 游戏平台 (Dark Gaming)
主背景 #FEF9E7 奶油色 #0d2847 深海蓝渐变
边框风格 2px 纯黑硬边框 1px 半透明边框
阴影效果 4px 硬阴影 柔和光晕 + 模糊
圆角 直角 (0px) 圆角 (8-20px)
交互反馈 点击位移 缩放 + 光晕
氛围 活泼、创意 沉浸、专注

1.3 参考来源

来源 参考内容 应用位置
QQ斗地主 牌桌布局、扑克牌样式、玩家位置布局 happy-games/doudizhu
Slither.io 深色主题、霓虹光效、简洁悬浮UI happy-games/slither-io
Poki.com 游戏卡片设计、响应式网格布局 happy-games/index.html
Steam 深色模式、信息层级、按钮样式 全局参考
Discord 状态指示器、用户头像样式 net-games/client

2. 色彩系统

2.1 CSS 变量定义

:root {
  /* ========== 背景色 ========== */
  --bg-primary: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
  --bg-game-table: linear-gradient(135deg, #0d2847 0%, #1a3a5c 50%, #0d2847 100%);
  --bg-card: linear-gradient(145deg, #1e293b 0%, #0f172a 100%);
  --bg-glass: rgba(0, 0, 0, 0.4);
  --bg-glass-light: rgba(255, 255, 255, 0.1);
  
  /* ========== 文字色 ========== */
  --text-primary: #ffffff;
  --text-secondary: rgba(255, 255, 255, 0.8);
  --text-muted: #888888;
  --text-gold: #ffd700;
  
  /* ========== 强调色 ========== */
  --accent-purple: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  --accent-pink: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
  --accent-blue: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
  --accent-gold: linear-gradient(135deg, #ffd700 0%, #ff8c00 100%);
  --accent-green: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%);
  --accent-red: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%);
  
  /* ========== 状态色 ========== */
  --status-online: #2ecc71;
  --status-offline: #e74c3c;
  --status-connecting: #3498db;
  --status-warning: #f1c40f;
  
  /* ========== 边框 ========== */
  --border-subtle: 1px solid rgba(255, 255, 255, 0.1);
  --border-accent: 1px solid rgba(102, 126, 234, 0.5);
  --border-gold: 1px solid rgba(255, 215, 0, 0.3);
}

2.2 使用规范

颜色变量 用途 设计意图
--bg-primary 页面背景 营造深海/夜空的沉浸感
--bg-game-table 牌桌/游戏区背景 突出游戏区域,模拟真实牌桌
--bg-card 卡片、面板背景 与背景区分,形成层级
--text-gold 积分、奖励、重要数字 金色代表价值和成就
--accent-purple 主按钮、主要操作 紫色传达神秘和高级感
--accent-pink 次要按钮、危险操作 醒目的对比色
--accent-blue 提示按钮、信息 冷静、可信赖
--accent-gold 开始游戏、重要CTA 吸引注意力,激发行动

2.3 渐变设计原理

为什么使用渐变?

  1. 增加深度感: 单色背景显得扁平,渐变营造空间感
  2. 引导视线: 从左上到右下的渐变自然引导用户视线
  3. 品牌识别: 蓝紫渐变成为平台的视觉签名

渐变方向规范:

  • 背景: 135deg (从左上到右下)
  • 按钮: 135deg 或 to right
  • 卡片: 145deg (稍微偏移,增加变化)

3. 排版系统

3.1 字体选择

font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 
             'Helvetica Neue', Arial, sans-serif;

选择理由:

  • 系统字体栈,无需加载外部字体
  • 跨平台一致性
  • 游戏场景下可读性好

3.2 字号规范

元素 桌面端 移动端 字重 用途
页面标题 2.5rem (40px) 1.8rem (29px) 700 游戏大厅标题
卡片标题 1rem (16px) 0.9rem (14px) 600 游戏卡片名称
正文 0.875rem (14px) 0.8rem (13px) 400 描述文字
小字/标签 0.75rem (12px) 0.7rem (11px) 500 状态、时间
按钮 0.875rem (14px) 0.8rem (13px) 700 按钮文字
积分数字 1.125rem (18px) 1rem (16px) 700 积分显示

3.3 文字样式规范

标题样式:

.header h1 {
  font-size: 2.5rem;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  text-shadow: 0 0 30px rgba(102, 126, 234, 0.3);
}

设计意图: 渐变色文字增加视觉吸引力,光晕效果营造游戏感

积分高亮:

.score-value {
  font-size: 16px;
  font-weight: bold;
  color: #ffd700;
  text-shadow: 0 0 10px rgba(255, 215, 0, 0.5);
}

设计意图: 金色+发光效果强调积分的价值感


4. 阴影与光效系统

4.1 阴影定义

/* 卡片悬停阴影 */
--shadow-card: 0 20px 40px rgba(102, 126, 234, 0.3);

/* 按钮阴影 */
--shadow-button: 0 4px 8px rgba(0, 0, 0, 0.3);
--shadow-button-hover: 0 6px 12px rgba(0, 0, 0, 0.4);

/* 光晕效果 */
--glow-gold: 0 0 10px rgba(255, 215, 0, 0.5);
--glow-purple: 0 0 20px rgba(102, 126, 234, 0.4);

/* 模态框阴影 */
--shadow-modal: 0 10px 40px rgba(0, 0, 0, 0.5);

4.2 使用场景

阴影类型 应用场景 设计意图
--shadow-card 游戏卡片悬停 营造"浮起"感,吸引点击
--shadow-button 按钮默认状态 增加立体感
--glow-gold 积分、奖励 强调价值和重要性
--glow-purple 标题、品牌元素 强化品牌色

4.3 玻璃态效果 (Glassmorphism)

.glass-panel {
  background: rgba(0, 0, 0, 0.4);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.1);
}

应用场景:

  • 顶部状态栏
  • 玩家信息面板
  • 弹窗背景
  • 悬浮提示

设计意图: 玻璃态效果让UI层与游戏背景融合,不遮挡游戏内容的同时提供信息


5. 组件规范

5.1 按钮 (Button)

5.1.1 基础样式

.btn {
  padding: 10px 25px;
  border: none;
  border-radius: 25px;
  font-size: 14px;
  font-weight: bold;
  cursor: pointer;
  transition: all 0.2s ease;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
  color: white;
}

.btn:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.4);
}

.btn:active:not(:disabled) {
  transform: translateY(0);
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

5.1.2 按钮变体

变体 背景 用途 设计意图
.btn-primary linear-gradient(135deg, #667eea, #764ba2) 主要操作 品牌色,最高优先级
.btn-secondary linear-gradient(135deg, #f093fb, #f5576c) 次要操作 对比色,次要优先级
.btn-hint linear-gradient(135deg, #4facfe, #00f2fe) 提示、帮助 冷静的蓝,信息类
.btn-start linear-gradient(135deg, #ffd700, #ff8c00) 开始游戏 金色,吸引点击
.btn-danger linear-gradient(135deg, #e74c3c, #c0392b) 危险操作 红色,警示作用

5.1.3 尺寸变体

.btn-small {
  padding: 6px 15px;
  font-size: 12px;
  border-radius: 15px;
}

.btn-large {
  padding: 15px 50px;
  font-size: 20px;
  border-radius: 30px;
}

5.1.4 交互状态

/* 悬停状态 */
.btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.4);
}

/* 点击状态 */
.btn:active {
  transform: translateY(0);
}

/* 禁用状态 */
.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

设计意图:

  • 圆角按钮更友好、现代
  • 渐变背景增加视觉吸引力
  • 悬停上浮提供即时反馈
  • 禁用状态明确告知不可操作

5.2 游戏卡片 (Game Card)

5.2.1 结构

<div class="game-card" data-id="doudizhu" data-url="/doudizhu/">
  <span class="hot-badge">🔥 HOT</span>
  <div class="game-icon">🃏</div>
  <div class="game-info">
    <div class="game-title">斗地主</div>
    <div class="game-desc">经典三人扑克游戏</div>
    <span class="game-tag">棋牌</span>
    <div class="game-score">🏆 积分: 100</div>
  </div>
</div>

5.2.2 样式定义

.game-card {
  position: relative;
  background: linear-gradient(145deg, #1e293b 0%, #0f172a 100%);
  border-radius: 16px;
  overflow: hidden;
  cursor: pointer;
  transition: all 0.3s ease;
  border: 1px solid rgba(255, 255, 255, 0.1);
  aspect-ratio: 3/4;
  display: flex;
  flex-direction: column;
}

.game-card:hover {
  transform: translateY(-8px) scale(1.02);
  box-shadow: 0 20px 40px rgba(102, 126, 234, 0.3);
  border-color: rgba(102, 126, 234, 0.5);
}

.game-card:active {
  transform: translateY(-4px) scale(0.98);
}

.game-icon {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 4rem;
  background: linear-gradient(135deg, rgba(102, 126, 234, 0.2) 0%, rgba(118, 75, 162, 0.2) 100%);
  position: relative;
  overflow: hidden;
}

/* 闪光动画 */
.game-icon::before {
  content: '';
  position: absolute;
  top: -50%;
  left: -50%;
  width: 200%;
  height: 200%;
  background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 60%);
  animation: shimmer 3s infinite;
}

@keyframes shimmer {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.game-info {
  padding: 15px;
  background: rgba(0, 0, 0, 0.3);
}

.game-title {
  font-size: 1rem;
  font-weight: 600;
  margin-bottom: 5px;
  color: #fff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.game-desc {
  font-size: 0.75rem;
  color: #888;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.game-tag {
  display: inline-block;
  padding: 3px 8px;
  background: rgba(102, 126, 234, 0.3);
  border-radius: 12px;
  font-size: 0.7rem;
  color: #a5b4fc;
  margin-top: 8px;
}

.game-score {
  display: inline-block;
  padding: 3px 10px;
  background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
  border-radius: 12px;
  font-size: 0.75rem;
  color: #fff;
  margin-top: 8px;
  margin-left: 6px;
  font-weight: 600;
}

5.2.3 徽章设计

.hot-badge {
  position: absolute;
  top: 10px;
  right: 10px;
  background: linear-gradient(135deg, #ff6b6b 0%, #ee5a5a 100%);
  color: #fff;
  padding: 4px 10px;
  border-radius: 12px;
  font-size: 0.7rem;
  font-weight: 600;
  z-index: 10;
  box-shadow: 0 2px 8px rgba(255, 107, 107, 0.4);
}

.new-badge {
  position: absolute;
  top: 10px;
  right: 10px;
  background: linear-gradient(135deg, #4ade80 0%, #22c55e 100%);
  color: #fff;
  padding: 4px 10px;
  border-radius: 12px;
  font-size: 0.7rem;
  font-weight: 600;
  z-index: 10;
}

设计意图:

  • 3:4 的宽高比适合展示游戏图标和信息
  • 悬停时的上浮和光晕效果吸引点击
  • 闪光动画增加活力感
  • 徽章突出热门和新游戏

5.3 模态框 (Modal)

5.3.1 基础样式

.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background: rgba(0, 0, 0, 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
}

.modal-content {
  background: linear-gradient(135deg, #1a3a5c 0%, #0d2847 100%);
  padding: 40px 60px;
  border-radius: 20px;
  border: 2px solid #4a7ab8;
  text-align: center;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
  max-width: 90vw;
  max-height: 90vh;
  overflow-y: auto;
}

.modal-title {
  color: white;
  margin-bottom: 25px;
  font-size: 24px;
  font-weight: bold;
}

.modal-buttons {
  display: flex;
  gap: 20px;
  justify-content: center;
  flex-wrap: wrap;
}

5.3.2 游戏结束弹窗

.game-result {
  margin: 20px 0;
  padding: 20px;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 10px;
  font-size: 18px;
}

.game-result .winner {
  font-size: 22px;
  font-weight: bold;
  color: #ffd700;
  margin-bottom: 8px;
}

.game-result .winner-identity {
  font-size: 16px;
  color: #aaa;
  margin-bottom: 10px;
}

.score-changes {
  margin-top: 20px;
  padding-top: 15px;
  border-top: 1px solid rgba(255, 255, 255, 0.2);
}

.score-title {
  font-size: 16px;
  font-weight: bold;
  margin-bottom: 10px;
  color: #4a7ab8;
}

.score-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 5px 0;
}

.score-change {
  font-weight: bold;
}

.score-up { color: #2ecc71; }
.score-down { color: #e74c3c; }
.score-zero { color: #888; }

设计意图:

  • 深色半透明遮罩聚焦注意力
  • 边框和渐变背景与整体风格一致
  • 金色突出获胜者
  • 积分变动用颜色区分正负

5.4 输入框 (Input)

.input-field {
  width: 100%;
  padding: 12px 15px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.1);
  color: white;
  font-size: 16px;
  text-align: center;
  transition: all 0.2s;
}

.input-field:focus {
  outline: none;
  border-color: #667eea;
  background: rgba(255, 255, 255, 0.15);
  box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.2);
}

.input-field::placeholder {
  color: rgba(255, 255, 255, 0.5);
}

变体:

/* 小尺寸 */
.input-small {
  padding: 8px 12px;
  font-size: 14px;
  border-radius: 6px;
}

/* 深色背景 */
.input-dark {
  background: rgba(0, 0, 0, 0.3);
  border-color: rgba(255, 255, 255, 0.1);
}

5.5 下拉选择 (Select)

.select-field {
  padding: 8px 15px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.3);
  color: white;
  font-size: 14px;
  cursor: pointer;
}

.select-field option {
  background: #1a3a5c;
  color: white;
}

6. 游戏界面布局

6.1 斗地主游戏布局

┌─────────────────────────────────────────────┐
│  [底牌区]                          [房间信息] │
│  🂠 🂠 🂠                          房间:ABC123 │
├─────────────────────────────────────────────┤
│                                             │
│  ┌─────────┐              ┌─────────┐      │
│  │  农民甲  │              │  农民乙  │      │
│  │  [头像]  │   [桌面区]    │  [头像]  │      │
│  │  17张   │    上家出牌    │  17张   │      │
│  └─────────┘              └─────────┘      │
│                                             │
│              ┌───────────┐                 │
│              │           │                 │
│              │  出牌区域  │                 │
│              │           │                 │
│              └───────────┘                 │
│                                             │
├─────────────────────────────────────────────┤
│  [我 - 地主]                                │
│  🃏🃏🃏🃏🃏🃏🃏🃏🃏🃏🃏🃏🃏🃏🃏🃏🃏🃏🃏🃏        │
│                                             │
│         [出牌] [不出] [提示]                │
└─────────────────────────────────────────────┘

6.1.1 玩家位置设计

/* 左侧玩家 */
.player-left {
  position: absolute;
  left: 20px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  gap: 15px;
}

/* 右侧玩家 */
.player-right {
  position: absolute;
  right: 20px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  gap: 15px;
  flex-direction: row-reverse;
}

/* 自己(底部) */
.player-self {
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 15px;
}

设计意图:

  • 三人呈三角形分布,模拟真实牌桌
  • 自己始终在底部,符合操作习惯
  • 头像+剩余牌数清晰展示对手状态

6.1.2 头像组件

.avatar {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
}

.avatar-img {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  font-size: 18px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  border: 2px solid rgba(255, 255, 255, 0.2);
}

.avatar-img.me {
  background: linear-gradient(135deg, #ffd700 0%, #ff8c00 100%);
  color: #333;
}

.player-name {
  font-size: 14px;
  color: rgba(255, 255, 255, 0.9);
}

.player-role {
  font-size: 12px;
  padding: 2px 8px;
  background: rgba(0, 0, 0, 0.5);
  border-radius: 10px;
  color: #ffd700;
}

6.2 扑克牌样式

.card {
  width: 80px;
  height: 112px;
  background: white;
  border-radius: 8px;
  border: 1px solid #ccc;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 6px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  cursor: pointer;
  transition: transform 0.2s, box-shadow 0.2s;
  user-select: none;
  position: relative;
  overflow: hidden;
}

.card:hover {
  transform: translateY(-5px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
}

.card.selected {
  transform: translateY(-15px);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.5);
}

/* 牌背 */
.card.back {
  background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
  border: 1px solid #4a7ab8;
}

.card.back::after {
  content: '🎮';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 24px;
  opacity: 0.5;
}

/* 小尺寸牌(用于显示剩余牌数) */
.card-small {
  width: 40px;
  height: 56px;
  border-radius: 4px;
}

设计意图:

  • 标准扑克牌比例 (80x112)
  • 选中时上移15px,清晰显示选择状态
  • 牌背使用品牌蓝,带logo增加识别度

7. 响应式设计

7.1 断点定义

断点 宽度 设备类型 布局变化
xs < 640px 手机 单列,紧凑布局
sm 640px - 899px 大屏手机/平板 2-3列
md 900px - 1199px 小笔记本 4列
lg 1200px - 1599px 桌面 5-6列
xl ≥ 1600px 大屏 8列

7.2 游戏大厅响应式

.games-grid {
  display: grid;
  gap: 20px;
  /* 手机默认:每行2个 */
  grid-template-columns: repeat(2, 1fr);
}

/* 平板:每行3个 */
@media (min-width: 640px) {
  .games-grid { grid-template-columns: repeat(3, 1fr); }
}

/* 小屏幕电脑:每行4个 */
@media (min-width: 900px) {
  .games-grid { grid-template-columns: repeat(4, 1fr); }
}

/* 中等屏幕:每行5-6个 */
@media (min-width: 1200px) {
  .games-grid { grid-template-columns: repeat(5, 1fr); }
}

/* 大屏幕:每行8个 */
@media (min-width: 1600px) {
  .games-grid { grid-template-columns: repeat(8, 1fr); }
}

7.3 斗地主游戏响应式

/* 手机适配 */
@media (max-width: 768px) {
  .game-container {
    max-width: 100vw;
    max-height: 100vh;
  }
  
  /* 缩小牌尺寸 */
  .card {
    width: 60px;
    height: 84px;
  }
  
  /* 手牌重叠更多 */
  .hand-cards .card {
    margin-left: -40px;
  }
  
  /* 隐藏左右玩家的详细信息 */
  .player-left .player-name,
  .player-right .player-name {
    display: none;
  }
  
  /* 头像缩小 */
  .avatar-img {
    width: 40px;
    height: 40px;
    font-size: 14px;
  }
}

7.4 字体响应式

html {
  font-size: 16px;
}

@media (max-width: 768px) {
  html { font-size: 14px; }
}

@media (max-width: 480px) {
  html { font-size: 12px; }
}

设计意图:

  • 移动优先:从手机布局开始,逐步增强
  • 牌类游戏在手机上需要调整牌尺寸和重叠度
  • 字体随屏幕缩小,保持可读性

8. 动效规范

8.1 过渡时间

类型 时长 缓动函数 应用场景
快速 150ms ease 按钮点击、状态切换
标准 200ms ease 悬停效果、小动画
慢速 300ms ease-out 卡片悬停、页面切换
特殊 500ms cubic-bezier 发牌动画、胜利庆祝

8.2 关键动画

8.2.1 发牌动画

@keyframes dealCard {
  0% {
    opacity: 0;
    transform: translateY(-100px) scale(0.5);
  }
  50% {
    opacity: 1;
  }
  100% {
    transform: translateY(0) scale(1);
  }
}

.card.dealing {
  animation: dealCard 0.5s ease-out forwards;
}

8.2.2 脉冲动画(连接状态)

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

.status-connecting {
  animation: pulse 1.5s infinite;
}

8.2.3 抖动动画(错误提示)

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-10px); }
  75% { transform: translateX(10px); }
}

.error-shake {
  animation: shake 0.3s ease-in-out;
}

8.2.4 闪光动画(卡片悬停)

@keyframes shimmer {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.game-icon::before {
  animation: shimmer 3s infinite linear;
}

8.3 性能优化

/* 使用 will-change 优化动画性能 */
.game-card {
  will-change: transform;
}

/* 使用 transform 而非 top/left */
.card:hover {
  transform: translateY(-5px);
}

/* 避免动画引起的重排 */
.modal-overlay {
  will-change: opacity;
}

9. 特殊组件

9.1 连接状态栏

.connection-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 50px;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(10px);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 15px;
  padding: 0 20px;
  z-index: 10000;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.connection-status {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 12px;
  border-radius: 15px;
  font-size: 14px;
  font-weight: bold;
}

.connection-status.connected {
  background: rgba(46, 204, 113, 0.2);
  color: #2ecc71;
}

.connection-status.disconnected {
  background: rgba(231, 76, 60, 0.2);
  color: #e74c3c;
}

.connection-status.connecting {
  background: rgba(52, 152, 219, 0.2);
  color: #3498db;
  animation: pulse 1.5s infinite;
}

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
}

设计意图:

  • 固定在顶部,随时可见
  • 颜色编码状态(绿=连接,红=断开,蓝=连接中)
  • 毛玻璃效果与背景融合

9.2 用户积分显示

.user-score-area {
  margin: 15px 0;
  padding: 12px 20px;
  background: linear-gradient(135deg, rgba(245, 158, 11, 0.2) 0%, rgba(217, 119, 6, 0.2) 100%);
  border: 1px solid rgba(245, 158, 11, 0.3);
  border-radius: 25px;
  display: inline-block;
}

.score-display {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
}

.score-label {
  color: #fbbf24;
}

.score-value {
  font-weight: bold;
  color: #f59e0b;
  font-size: 18px;
}

设计意图:

  • 金色系强调积分的价值
  • 圆角胶囊形状,友好现代
  • 半透明背景与页面融合

9.3 倒计时提示

.countdown {
  position: fixed;
  top: 60px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(231, 76, 60, 0.9);
  color: white;
  padding: 8px 20px;
  border-radius: 20px;
  font-size: 16px;
  font-weight: bold;
  z-index: 9998;
  animation: pulse 1s infinite;
}

.countdown.warning {
  background: rgba(241, 196, 15, 0.9);
  color: #333;
}

.countdown.danger {
  background: rgba(231, 76, 60, 0.9);
  animation: pulse 0.5s infinite;
}

设计意图:

  • 顶部中央位置,醒目但不遮挡游戏
  • 颜色随时间变化(绿→黄→红)
  • 脉冲动画增加紧迫感

9.4 操作按钮组

.action-buttons {
  display: flex;
  gap: 15px;
  justify-content: center;
  flex-wrap: wrap;
}

.action-buttons .btn {
  min-width: 100px;
}

布局原则:

  • 主要操作在左侧(出牌、叫地主)
  • 次要操作在右侧(不出、提示)
  • 危险操作使用红色(退出、解散)
  • 按钮间距15px,防止误触

10. 代码组织规范

10.1 文件结构

net-games/
├── client/
│   ├── index.html          # 主页面
│   ├── style.css           # 主样式文件
│   ├── game.js             # 游戏逻辑
│   └── assets/
│       └── images/         # 图片资源
├── hub/
│   ├── index.html          # 游戏大厅
│   └── style.css
└── docs/
    └── UI_DESIGN_GUIDELINES.md  # 本文档

happy-games/
├── index.html              # 游戏大厅
├── games/
│   ├── doudizhu/
│   │   ├── index.html
│   │   ├── style.css
│   │   └── game.js
│   └── slither-io/
│       └── ...

10.2 CSS 命名规范

使用 BEM (Block Element Modifier) 命名法:

/* Block */
.game-card { }

/* Element */
.game-card__icon { }
.game-card__title { }

/* Modifier */
.game-card--hot { }
.game-card--disabled { }

实际项目中的简化:

/* 使用连字符命名 */
.game-card { }
.game-icon { }
.game-title { }
.game-card.hot { }
.game-card.disabled { }

10.3 样式组织顺序

/* 1. CSS 变量 */
:root { }

/* 2. 重置和基础 */
* { }
body { }

/* 3. 工具类 */
.text-center { }
.hidden { }

/* 4. 布局组件 */
.header { }
.container { }

/* 5. UI 组件 */
.btn { }
.card { }
.modal { }

/* 6. 游戏特定 */
.card-poker { }
.player-avatar { }

/* 7. 动画 */
@keyframes { }

/* 8. 媒体查询 */
@media { }

11. 技术栈

11.1 前端技术

技术 版本 用途 选择理由
原生 HTML 5 页面结构 轻量,无需构建
原生 CSS 3 样式 使用现代特性(变量、渐变、网格)
原生 JavaScript ES6+ 交互逻辑 现代API支持,无需编译
Socket.IO Client 4.x 实时通信 WebSocket 封装,自动重连

11.2 不使用框架的理由

  1. 轻量快速: 无需构建步骤,直接部署
  2. 游戏性能: 原生 DOM 操作比框架更高效
  3. 简单场景: 游戏界面相对固定,不需要复杂的状态管理
  4. 学习成本: 团队成员都能直接维护

11.3 现代 CSS 特性使用

/* CSS 变量 */
:root { --primary: #667eea; }

/* 网格布局 */
.games-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

/* 弹性盒子 */
.flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

/* 渐变 */
.gradient-text {
  background: linear-gradient(135deg, #667eea, #764ba2);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

/*  backdrop-filter 毛玻璃 */
.glass {
  backdrop-filter: blur(10px);
}

/* 过渡和动画 */
.animate {
  transition: all 0.3s ease;
}

12. 最佳实践

12.1 性能优化

/* 1. 使用 transform 代替 top/left */
/* 好 */
.card:hover { transform: translateY(-5px); }

/* 不好 */
.card:hover { top: -5px; }

/* 2. 使用 opacity 和 transform 做动画 */
/* 这些属性不会引起重排 */
.fade-in {
  animation: fadeIn 0.3s ease;
}

/* 3. 延迟加载非关键资源 */
<img loading="lazy" src="...">

/* 4. 使用 will-change 谨慎 */
.game-card {
  will-change: transform;
}

12.2 可访问性

/* 焦点样式 */
button:focus-visible,
input:focus-visible {
  outline: 2px solid #667eea;
  outline-offset: 2px;
}

/* 减少动画 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* 颜色对比度 */
/* 确保文字与背景对比度至少 4.5:1 */
.text-on-dark {
  color: rgba(255, 255, 255, 0.9);
}

12.3 移动端优化

/* 禁用双击缩放 */
* {
  touch-action: manipulation;
}

/* 禁用文本选择(游戏场景) */
.no-select {
  user-select: none;
  -webkit-user-select: none;
}

/* 优化滚动 */
.scrollable {
  -webkit-overflow-scrolling: touch;
}

13. 扩展建议

13.1 短期优化

  1. 暗色/亮色主题切换

    [data-theme="light"] {
      --bg-primary: #f5f5f5;
      --text-primary: #333;
    }
    
  2. 更多动效

    • 胜利庆祝动画(彩花、闪光)
    • 发牌音效配合视觉
    • 手势操作支持
  3. 无障碍增强

    • ARIA 标签
    • 键盘导航支持
    • 屏幕阅读器优化

13.2 长期规划

  1. 设计系统组件库

    • 将常用组件抽取为可复用模块
    • 组件文档和示例
    • 设计令牌(Design Tokens)
  2. 多主题支持

    • 节日主题(春节、圣诞)
    • 用户自定义主题
    • 品牌合作主题
  3. 跨游戏组件共享

    • 统一的头像组件
    • 通用的积分显示
    • 共享的弹窗系统

14. 示例代码

14.1 完整游戏卡片组件

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>游戏卡片示例</title>
  <style>
    :root {
      --accent-purple: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    }
    
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    body {
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
      background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
      min-height: 100vh;
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 20px;
    }
    
    .game-card {
      width: 200px;
      background: linear-gradient(145deg, #1e293b 0%, #0f172a 100%);
      border-radius: 16px;
      overflow: hidden;
      cursor: pointer;
      transition: all 0.3s ease;
      border: 1px solid rgba(255, 255, 255, 0.1);
    }
    
    .game-card:hover {
      transform: translateY(-8px) scale(1.02);
      box-shadow: 0 20px 40px rgba(102, 126, 234, 0.3);
      border-color: rgba(102, 126, 234, 0.5);
    }
    
    .game-icon {
      height: 150px;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 4rem;
      background: linear-gradient(135deg, rgba(102, 126, 234, 0.2) 0%, rgba(118, 75, 162, 0.2) 100%);
    }
    
    .game-info {
      padding: 15px;
    }
    
    .game-title {
      font-size: 1rem;
      font-weight: 600;
      color: #fff;
      margin-bottom: 5px;
    }
    
    .game-desc {
      font-size: 0.75rem;
      color: #888;
    }
  </style>
</head>
<body>
  <div class="game-card">
    <div class="game-icon">🃏</div>
    <div class="game-info">
      <div class="game-title">斗地主</div>
      <div class="game-desc">经典三人扑克游戏</div>
    </div>
  </div>
</body>
</html>

14.2 完整按钮组件

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <style>
    body {
      background: #0d2847;
      display: flex;
      gap: 20px;
      padding: 50px;
      flex-wrap: wrap;
    }
    
    .btn {
      padding: 12px 30px;
      border: none;
      border-radius: 25px;
      font-size: 14px;
      font-weight: bold;
      cursor: pointer;
      transition: all 0.2s ease;
      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
      color: white;
    }
    
    .btn:hover {
      transform: translateY(-2px);
      box-shadow: 0 6px 12px rgba(0, 0, 0, 0.4);
    }
    
    .btn-primary {
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    }
    
    .btn-secondary {
      background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
    }
    
    .btn-start {
      background: linear-gradient(135deg, #ffd700 0%, #ff8c00 100%);
      color: #333;
      padding: 15px 50px;
      font-size: 18px;
    }
    
    .btn:disabled {
      opacity: 0.5;
      cursor: not-allowed;
      transform: none;
    }
  </style>
</head>
<body>
  <button class="btn btn-primary">主要按钮</button>
  <button class="btn btn-secondary">次要按钮</button>
  <button class="btn btn-start">开始游戏</button>
  <button class="btn btn-primary" disabled>禁用状态</button>
</body>
</html>

15. 参考资源

15.1 设计灵感

资源 链接 参考内容
Dribbble https://dribbble.com 游戏UI设计灵感
Behance https://behance.net 完整项目案例
Mobbin https://mobbin.com 移动端设计模式
Game UI Database https://gameuidatabase.com 游戏界面截图库

15.2 技术文档

资源 链接 用途
MDN CSS https://developer.mozilla.org/zh-CN/docs/Web/CSS CSS 参考
Can I Use https://caniuse.com 浏览器兼容性
Tailwind CSS https://tailwindcss.com 工具类命名参考

15.3 游戏设计

资源 链接 参考内容
QQ斗地主 客户端 牌桌布局、交互
Slither.io https://slither.io 深色主题、光效
Poki.com https://poki.com 游戏大厅设计

16. 更新日志

日期 版本 变更内容
2026-04-09 v1.0 初始版本,整合 Happy-Games 和 Net-Games 设计规范

17. 附录

17.1 颜色速查表

名称 色值 用途
深海蓝 #0d2847 游戏背景
紫罗兰 #667eea 主品牌色
品红 #f093fb 次要按钮
金色 #ffd700 积分、奖励
成功绿 #2ecc71 在线状态
错误红 #e74c3c 错误、断开
警告黄 #f1c40f 倒计时警告

17.2 间距速查表

名称 值 用途
xs 4px 图标内边距
sm 8px 紧凑间距
md 15px 标准间距
lg 20px 组件间距
xl 30px 区块间距
2xl 40px 大区块间距

17.3 响应式断点速查

/* 手机 */
@media (max-width: 639px) { }

/* 平板 */
@media (min-width: 640px) and (max-width: 899px) { }

/* 小桌面 */
@media (min-width: 900px) and (max-width: 1199px) { }

/* 桌面 */
@media (min-width: 1200px) and (max-width: 1599px) { }

/* 大屏 */
@media (min-width: 1600px) { }

本文档由 AI 助手生成,作为 Net-Games 和 Happy-Games 项目的 UI 设计参考。

维护者: 开发团队
最后更新: 2026-04-09
状态: 活跃