35 KiB
35 KiB
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 渐变设计原理
为什么使用渐变?
- 增加深度感: 单色背景显得扁平,渐变营造空间感
- 引导视线: 从左上到右下的渐变自然引导用户视线
- 品牌识别: 蓝紫渐变成为平台的视觉签名
渐变方向规范:
- 背景:
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 不使用框架的理由
- 轻量快速: 无需构建步骤,直接部署
- 游戏性能: 原生 DOM 操作比框架更高效
- 简单场景: 游戏界面相对固定,不需要复杂的状态管理
- 学习成本: 团队成员都能直接维护
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 短期优化
-
暗色/亮色主题切换
[data-theme="light"] { --bg-primary: #f5f5f5; --text-primary: #333; } -
更多动效
- 胜利庆祝动画(彩花、闪光)
- 发牌音效配合视觉
- 手势操作支持
-
无障碍增强
- ARIA 标签
- 键盘导航支持
- 屏幕阅读器优化
13.2 长期规划
-
设计系统组件库
- 将常用组件抽取为可复用模块
- 组件文档和示例
- 设计令牌(Design Tokens)
-
多主题支持
- 节日主题(春节、圣诞)
- 用户自定义主题
- 品牌合作主题
-
跨游戏组件共享
- 统一的头像组件
- 通用的积分显示
- 共享的弹窗系统
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
状态: 活跃