# 扑克牌设计管理系统 - 设计规格文档 **日期:** 2026-05-31 **项目类型:** Web应用 - 个人扑克牌设计工具 **目标用户:** 个人用户从零开始设计扑克牌系列 --- ## 1. 项目概述 ### 1.1 核心目标 构建一个基于Web的扑克牌设计管理系统,支持: - 基于模板快速创建扑克牌系列 - 上传自定义素材(花色、人像、边框等) - 实时预览和编辑54张扑克牌 - 批量导出PNG格式图片 ### 1.2 设计原则 - **混合模式:** 系统提供基础模板,用户可选择性替换任意元素 - **自动对称化:** JQK人像上传后自动生成中心对称版本 - **预设布局:** 数字牌花色图案按标准模板排列,用户无需逐张设计 - **多图层支持:** JQK花牌支持多层次图像叠加(背景、边框、人像、装饰等) ### 1.3 扑克牌结构 **总计:54张牌** | 类型 | 数量 | 说明 | |------|------|------| | 数字牌 | 40张 | 4花色 × 10张(A, 2-10) | | 花牌 JQK | 12张 | 4花色 × 3张(J, Q, K) | | 大小王 | 2张 | 大王、小王 | **花色分类:** - 黑桃- 黑色 - 红桃- 红色 - 梅花- 黑色 - 方块- 红色 --- ## 2. 技术架构 ### 2.1 技术栈 | 技术 | 版本 | 用途 | |------|------|------| | Vue.js | 3.x | 前端框架,响应式UI | | Fabric.js | 6.x | Canvas图形库,图层管理 | | Pinia | 2.x | 状态管理 | | Element Plus | 2.x | UI组件库 | | Vite | 5.x | 构建工具 | | TypeScript | 5.x | 类型安全 | ### 2.2 架构特点 - **纯前端应用:** 无需后端服务器,所有处理在浏览器完成 - **本地存储:** 使用 IndexedDB 存储项目配置和素材 - **Canvas渲染:** Fabric.js 提供高性能图形渲染和图层操作 - **模块化设计:** 组件独立,易于维护和扩展 ### 2.3 目录结构 ``` poker-design-system/ ├── public/ │ └── templates/ # 预设模板素材 │ ├── classic/ │ ├── modern/ │ ├── cartoon/ │ └── vintage/ ├── src/ │ ├── assets/ # 静态资源 │ ├── components/ # Vue组件 │ │ ├── Editor/ # 编辑器组件 │ │ ├── Assets/ # 素材管理组件 │ │ ├── Preview/ # 预览组件 │ │ └── Export/ # 导出组件 │ ├── composables/ # Vue组合式函数 │ │ ├── useCanvas.js # Fabric.js封装 │ │ ├── useAssets.js # 素材管理 │ │ └── useExport.js # 导出功能 │ ├── stores/ # Pinia状态管理 │ │ ├── projectStore.js # 项目状态 │ │ ├── assetStore.js # 素材状态 │ │ └── editorStore.js # 编辑器状态 │ ├── utils/ # 工具函数 │ │ ├── cardLayout.js # 牌面布局计算 │ │ ├── symmetry.js # 中心对称处理 │ │ └── export.js # 导出工具 │ ├── templates/ # 模板配置 │ │ ├── classic.js │ │ ├── modern.js │ │ └── ... │ ├── App.vue │ └── main.js ├── package.json └── vite.config.js ``` --- ## 3. 功能模块设计 ### 3.1 模板系列库 #### 3.1.1 预设模板 **经典风格** - 标准扑克牌设计 - 传统花色图案(实心黑桃、红桃等) - 经典衬线字体 - 简洁边框 **现代简约** - 扁平化设计 - 简洁线条花色 - 无衬线字体 - 无边框或细边框 **卡通风格** - Q版可爱人像 - 圆润花色图案 - 活泼字体 - 彩色边框 **复古风格** - 复古色调(米黄、深红等) - 复杂花纹边框 - 装饰性字体 - 纹理背景 #### 3.1.2 模板数据结构 ```typescript interface Template { id: string; name: string; description: string; preview: string; // 预览图URL defaultAssets: { suitSymbols: { spade: string; heart: string; club: string; diamond: string; }; numberFont: FontConfig; faceCardBorder: string; // JQK边框SVG backPattern: string; // 背面图案 }; colorScheme: { spade: string; // 黑桃颜色 heart: string; // 红桃颜色 club: string; // 梅花颜色 diamond: string; // 方块颜色 background: string; // 牌面背景色 }; } ``` ### 3.2 素材管理模块 #### 3.2.1 可上传素材类型 | 素材类型 | 文件格式 | 数量 | 必需 | 说明 | |---------|---------|------|------|------| | 花色图案 | PNG/SVG | 4个 | 否 | 黑桃、红桃、梅花、方块 | | 数字字体 | TTF/OTF | 1套 | 否 | A, 2-10的数字样式 | | JQK人像 | PNG/JPG | 12张 | 否 | 每种花色的J/Q/K | | 大小王 | PNG/JPG | 2张 | 否 | 大王、小王独立图案 | | 背面图案 | PNG/JPG | 1张 | 否 | 扑克牌背面设计 | | 边框装饰 | SVG | 可选 | 否 | 牌面边框样式 | #### 3.2.2 素材存储 - **IndexedDB:** 存储上传的图片文件(Base64或Blob) - **项目配置:** 存储素材引用路径和配置参数 - **混合模式:** 未上传的素材自动使用模板默认值 #### 3.2.3 素材管理界面 ``` ┌────────────────────────────────────┐ │ 素材库 │ ├────────────────────────────────────┤ │ 花色图案 │ │ ┌────┬────┬────┬────┐ │ │ │ ♠ │ ♥ │ ♣ │ ♦ │ │ │ │上传│上传│上传│上传│ │ │ └────┴────┴────┴────┘ │ │ │ │ JQK人像 │ │ ┌─────────────────────────┐ │ │ │ 黑桃: J[上传] Q[上传] K[上传]│ │ │ │ 红桃: J[上传] Q[上传] K[上传]│ │ │ │ 梅花: J[上传] Q[上传] K[上传]│ │ │ │ 方块: J[上传] Q[上传] K[上传]│ │ │ └─────────────────────────┘ │ │ │ │ 大小王 │ │ ┌────┬────┐ │ │ │大王│小王│ │ │ │上传│上传│ │ │ └────┴────┘ │ │ │ │ 其他素材 │ │ 背面图案: [上传] │ │ 边框装饰: [上传] │ │ 数字字体: [上传] │ └────────────────────────────────────┘ ``` ### 3.3 设计编辑器 #### 3.3.1 界面布局 ``` ┌────────────────────────────────────────────────────────┐ │ 工具栏:[模板选择] [保存] [导出] [设置] │ ├──────────────┬─────────────────────────────────────────┤ │ │ │ │ 左侧面板 │ 中间画布区域 │ │ │ │ │ [素材库] │ ┌─────────────────────┐ │ │ [图层管理] │ │ │ │ │ [样式调整] │ │ 实时预览 │ │ │ │ │ 当前选中牌面 │ │ │ ┌────────┐ │ │ │ │ │ │图层列表│ │ │ 支持缩放/平移 │ │ │ │├ 背景 │ │ │ │ │ │ │├ 边框 │ │ └─────────────────────┘ │ │ │├ 人像 │ │ │ │ │├ 装饰 │ │ │ │ │└ 文字 │ │ │ │ └────────┘ │ │ │ │ │ ├──────────────┴─────────────────────────────────────────┤ │ 底部牌列表: │ │ [♠A][♠2]...[♠K][♥A]...[♥K][♣A]...[♣K][♦A]...[♦K][大][小]│ │ 点击切换编辑 │ └────────────────────────────────────────────────────────┘ ``` #### 3.3.2 Fabric.js 图层结构 **数字牌图层(A, 2-10):** ``` 图层栈(从下到上): ├─ 背景层(牌面底色) ├─ 边框层(可选装饰边框) ├─ 花色图案层(中间排列的花色图案) ├─ 角标数字层(左上、右下) └─ 角标花色层(左上、右下) ``` **花牌图层(JQK):** ``` 图层栈(从下到上): ├─ 背景层(牌面底色) ├─ 边框层(装饰边框) ├─ 背景装饰层(花纹、纹理) ├─ 主体图案层(上传的人像,自动中心对称) │ ├─ 上半部分人像(原始) │ └─ 下半部分人像(翻转180°) ├─ 花色装饰层(角标、装饰元素) ├─ 字母层(J/Q/K标识,四角) └─ 花色符号层(四角的花色图案) ``` **大小王图层:** ``` 图层栈(从下到上): ├─ 背景层 ├─ 边框层 ├─ 主体图案层(上传的图片) └─ 文字标识层("JOKER"等) ``` #### 3.3.3 核心功能 **实时预览** - 修改素材立即更新画布 - 支持缩放(50% - 200%) - 支持平移查看 **图层管理** - 调整图层顺序 - 控制图层可见性 - 设置图层透明度 - 锁定图层 **中心对称生成** - 用户上传单张JQK人像 - 系统自动分割为上下两部分 - 下半部分垂直翻转 - 拼接生成中心对称图案 **批量应用** - 应用花色图案到所有相关牌面 - 应用边框到整副牌 - 应用字体样式到所有文字 ### 3.4 数字牌布局模板 #### 3.4.1 标准布局规则 **牌面坐标系:** - 牌面尺寸:750×1050px(标准) - 安全区域:距边缘50px - 有效区域:650×950px **花色图案尺寸:** - 单个图案:60×60px(可调整) - 间距:根据点数自动计算 #### 3.4.2 各点数布局 **A(1个花色):** ``` ┌─────────────┐ │ │ │ │ │ ● │ 居中 │ │ │ │ └─────────────┘ ``` **2(2个花色):** ``` ┌─────────────┐ │ ● │ 上部居中 │ │ │ │ │ │ │ ● │ 下部居中 └─────────────┘ ``` **3(3个花色):** ``` ┌─────────────┐ │ ● │ 上部居中 │ │ │ ● │ 中部居中 │ │ │ ● │ 下部居中 └─────────────┘ ``` **4(4个花色):** ``` ┌─────────────┐ │ ● ● │ 上部左右 │ │ │ │ │ │ │ ● ● │ 下部左右 └─────────────┘ ``` **5(5个花色):** ``` ┌─────────────┐ │ ● ● │ 上部左右 │ │ │ ● │ 中部居中 │ │ │ ● ● │ 下部左右 └─────────────┘ ``` **6(6个花色):** ``` ┌─────────────┐ │ ● ● │ 上部左右 │ │ │ ● ● │ 中部左右 │ │ │ ● ● │ 下部左右 └─────────────┘ ``` **7(7个花色):** ``` ┌─────────────┐ │ ● ● │ 上部左右 │ ● │ 上中居中 │ ● ● │ 中部左右 │ │ │ ● ● │ 下部左右 └─────────────┘ ``` **8(8个花色):** ``` ┌─────────────┐ │ ● ● │ 上部左右 │ ● │ 上中居中 │ ● ● │ 中部左右 │ ● │ 下中居中 │ ● ● │ 下部左右 └─────────────┘ ``` **9(9个花色):** ``` ┌─────────────┐ │ ● ● │ 上部左右 │ ● │ 上中居中 │ ● ● ● │ 中部三列 │ ● │ 下中居中 │ ● ● │ 下部左右 └─────────────┘ ``` **10(10个花色):** ``` ┌─────────────┐ │ ● ● │ 上部左右 │ ● ● │ 上中左右 │ ● │ 中部居中 │ ● ● │ 下中左右 │ ● ● │ 下部左右 └─────────────┘ ``` ### 3.5 导出功能 #### 3.5.1 导出选项 **导出范围:** - 单张导出:当前选中的牌 - 批量导出:整副54张牌 - 分类导出:仅数字牌 / 仅花牌 / 仅大小王 **分辨率选项:** | 分辨率 | 尺寸 | 用途 | |--------|------|------| | 标准 | 750×1050px | 打印质量 | | 高清 | 1500×2100px | 2倍分辨率 | | 超高清 | 3000×4200px | 4倍分辨率 | **文件格式:** - PNG(带透明通道) - 文件命名规则: - 数字牌:`{suit}-{number}.png`(如:spade-A.png, heart-7.png) - 花牌:`{suit}-{face}.png`(如:club-J.png, diamond-Q.png) - 大小王:`joker-big.png`, `joker-small.png` - 背面:`back.png` #### 3.5.2 导出流程 ``` 用户点击导出 ↓ 选择导出范围和分辨率 ↓ 系统遍历所有需要导出的牌 ↓ 对每张牌: - 创建临时Canvas - 按图层顺序渲染 - 应用分辨率缩放 - 导出为PNG Blob ↓ 打包为ZIP文件(批量导出时) ↓ 触发浏览器下载 ``` --- ## 4. 数据结构设计 ### 4.1 项目配置 ```typescript interface Project { id: string; name: string; createdAt: Date; updatedAt: Date; template: string; // 模板ID cardSize: { width: number; height: number; }; assets: AssetCollection; exportSettings: ExportSettings; } ``` ### 4.2 素材集合 ```typescript interface AssetCollection { suitSymbols: { spade?: Asset; heart?: Asset; club?: Asset; diamond?: Asset; }; faceCards: { spade: { J?: Asset; Q?: Asset; K?: Asset }; heart: { J?: Asset; Q?: Asset; K?: Asset }; club: { J?: Asset; Q?: Asset; K?: Asset }; diamond: { J?: Asset; Q?: Asset; K?: Asset }; }; jokers: { big?: Asset; small?: Asset; }; backPattern?: Asset; border?: Asset; numberFont?: FontAsset; } interface Asset { id: string; type: 'image' | 'font' | 'svg'; name: string; data: string; // Base64或Blob URL width?: number; height?: number; uploadedAt: Date; } ``` ### 4.3 图层配置 ```typescript interface Layer { id: string; name: string; type: 'background' | 'border' | 'pattern' | 'image' | 'text' | 'symbol'; visible: boolean; locked: boolean; opacity: number; // 0-1 zIndex: number; properties: { x: number; y: number; width: number; height: number; rotation?: number; // 旋转角度 scaleX?: number; scaleY?: number; }; } ``` ### 4.4 导出设置 ```typescript interface ExportSettings { resolution: 'standard' | 'hd' | 'ultra-hd'; format: 'png'; includeBack: boolean; // 是否导出背面 namingPattern: string; // 文件命名模式 } ``` --- ## 5. 核心算法 ### 5.1 中心对称生成算法 **输入:** 单张JQK人像图片 **输出:** 中心对称的人像图案 ``` 算法步骤: 1. 加载原始图片 2. 获取图片高度 height 3. 计算分割点:midpoint = height / 2 4. 创建上半部分: - 从原始图片裁剪 [0, 0, width, midpoint] 5. 创建下半部分: - 从原始图片裁剪 [0, midpoint, width, midpoint] - 垂直翻转(scaleY = -1) 6. 创建新画布,高度 = midpoint * 2 7. 将上半部分绘制到画布顶部 8. 将翻转后的下半部分绘制到画布底部 9. 返回中心对称图案 ``` **Fabric.js实现伪代码:** ```javascript function createSymmetricalImage(originalImage) { const width = originalImage.width; const height = originalImage.height; const halfHeight = height / 2; // 创建上半部分 const topHalf = new fabric.Image(originalImage, { clipPath: new fabric.Rect({ width: width, height: halfHeight, originX: 'left', originY: 'top' }) }); // 创建下半部分并翻转 const bottomHalf = new fabric.Image(originalImage, { top: halfHeight, scaleY: -1, clipPath: new fabric.Rect({ width: width, height: halfHeight, originX: 'left', originY: 'top' }) }); // 组合成最终图案 const group = new fabric.Group([topHalf, bottomHalf]); return group; } ``` ### 5.2 数字牌花色排列算法 **输入:** 点数(1-10)、花色图案、牌面尺寸 **输出:** 花色图案的位置数组 ```javascript const LAYOUT_TEMPLATES = { 1: [{ x: 0.5, y: 0.5 }], // A 2: [{ x: 0.5, y: 0.25 }, { x: 0.5, y: 0.75 }], 3: [{ x: 0.5, y: 0.2 }, { x: 0.5, y: 0.5 }, { x: 0.5, y: 0.8 }], 4: [{ x: 0.3, y: 0.25 }, { x: 0.7, y: 0.25 }, { x: 0.3, y: 0.75 }, { x: 0.7, y: 0.75 }], 5: [{ x: 0.3, y: 0.2 }, { x: 0.7, y: 0.2 }, { x: 0.5, y: 0.5 }, { x: 0.3, y: 0.8 }, { x: 0.7, y: 0.8 }], // ... 6-10的布局 }; function calculateSuitPositions(rank, cardWidth, cardHeight, symbolSize) { const template = LAYOUT_TEMPLATES[rank]; return template.map(pos => ({ x: pos.x * cardWidth - symbolSize / 2, y: pos.y * cardHeight - symbolSize / 2 })); } ``` --- ## 6. 用户交互流程 ### 6.1 首次使用流程 ``` 用户打开应用 ↓ 欢迎页面:选择模板系列 ├─ 经典风格 ├─ 现代简约 ├─ 卡通风格 ├─ 复古风格 └─ 自定义 ↓ 进入设计编辑器(加载模板默认素材) ↓ 用户可立即预览54张牌面 ↓ 开始上传自定义素材(可选) ↓ 实时预览更新 ↓ 导出PNG ``` ### 6.2 素材上传流程 ``` 用户点击"上传"按钮 ↓ 文件选择对话框 ↓ 选择文件(验证格式和尺寸) ↓ 文件读取为Base64或Blob ↓ 存储到IndexedDB ↓ 更新项目配置 ↓ 触发重新渲染 ↓ 画布实时更新 ``` ### 6.3 导出流程 ``` 用户点击"导出"按钮 ↓ 导出设置对话框: - 选择范围(单张/批量) - 选择分辨率 - 是否包含背面 ↓ 用户确认 ↓ 显示进度条 ↓ 遍历需要导出的牌: - 创建临时Canvas - 按图层渲染 - 应用分辨率 - 生成PNG Blob ↓ 打包为ZIP(批量导出) ↓ 触发下载 ↓ 完成提示 ``` --- ## 7. 性能优化 ### 7.1 渲染优化 - **虚拟滚动:** 底部54张牌缩略图使用虚拟滚动 - **懒加载:** 切换到某张牌时才完整渲染 - **缓存:** 已渲染的牌面缓存到内存 - **防抖:** 快速切换牌时不立即渲染,等待300ms ### 7.2 导出优化 - **并行导出:** 使用Web Worker并行生成PNG - **分批处理:** 大批量导出时分批进行,避免内存溢出 - **进度反馈:** 实时显示导出进度 ### 7.3 存储优化 - **压缩:** 上传的图片压缩后再存储 - **IndexedDB:** 大文件使用IndexedDB而非localStorage - **清理:** 提供清理缓存功能 --- ## 8. 扩展性设计 ### 8.1 模板扩展 系统支持添加新模板,只需创建模板配置文件: ```javascript // templates/custom.js export default { id: 'custom', name: '自定义模板', defaultAssets: { ... }, colorScheme: { ... } }; ``` ### 8.2 布局扩展 数字牌布局模板可配置,支持非标准玩法: ```javascript // 自定义布局 const customLayout = { 1: [{ x: 0.5, y: 0.5 }], // ... 自定义位置 }; ``` ### 8.3 导出格式扩展 未来可扩展支持: - PDF导出(整副牌) - SVG矢量格式 - 打印店对接格式 --- ## 9. 测试策略 ### 9.1 单元测试 - 中心对称生成算法 - 布局计算算法 - 文件命名规则 - 数据结构验证 ### 9.2 集成测试 - 素材上传流程 - 导出流程 - 模板加载流程 ### 9.3 视觉测试 - 54张牌面渲染正确性 - 中心对称效果验证 - 不同分辨率导出质量 --- ## 10. 项目约束 ### 10.1 技术约束 - 纯前端,无后端依赖 - 浏览器兼容:Chrome 90+, Firefox 88+, Safari 14+ - 最大图片尺寸:4096×4096px - 最大项目数量:本地存储限制 ### 10.2 设计约束 - 牌面比例固定:2.5:3.5(标准扑克牌比例) - JQK必须中心对称 - 数字牌花色排列遵循标准模板 - 导出格式仅支持PNG ### 10.3 性能约束 - 单张牌渲染时间:<100ms - 批量导出(54张):<30秒 - 图片上传响应:<500ms --- ## 11. 未来增强 ### 11.1 短期增强 - 撤销/重做功能 - 复制/粘贴样式 - 对齐辅助线 - 网格显示 ### 11.2 中期增强 - 云端存储(需后端) - 项目分享功能 - 协作编辑 - 更多模板 ### 11.3 长期增强 - AI辅助设计 - 自动配色建议 - 3D预览 - AR预览 --- ## 附录:标准扑克牌尺寸参考 | 类型 | 尺寸 | 用途 | |------|------|------| | 标准 | 2.5" × 3.5" (63.5×88.9mm) | 常见扑克牌 | | 桥牌 | 2.25" × 3.5" (57×88.9mm) | 桥牌用牌 | | 大号 | 3" × 4.5" (76.2×114.3mm) | 魔术表演 | | 迷你 | 1.75" × 2.5" (44.5×63.5mm) | 旅行便携 | **像素尺寸(300 DPI):** - 标准:750×1050px - 高清(600 DPI):1500×2100px - 超高清(1200 DPI):3000×4200px