ImageMerge - 极客拼图
DevShots - 极客晒图
Design Document - Image Merge
Overview
Image Merge 是一个纯前端的单页面网页应用,使用 HTML5 Canvas API 实现图片的加载、处理和合并。应用采用原生 JavaScript 开发,无需外部依赖,确保轻量和快速加载。
核心工作流程:
- 用户通过文件输入上传两张图片
- 系统验证图片格式和尺寸匹配
- 在 Canvas 上渲染两张图片的合并预览
- 用户拖动垂直辅助线调整合并位置
- 实时更新预览显示
- 用户点击下载按钮导出合并后的图片
Architecture
应用采用模块化的客户端架构:
┌─────────────────────────────────────┐
│ User Interface │
│ (Upload, Preview, Controls) │
└──────────────┬──────────────────────┘
│
┌──────────────┴──────────────────────┐
│ Event Handlers Layer │
│ (Upload, Drag, Download, Reset) │
└──────────────┬──────────────────────┘
│
┌──────────────┴──────────────────────┐
│ Image Processing Core │
│ - Image Loader │
│ - Dimension Validator │
│ - Canvas Renderer │
│ - Merge Engine │
└──────────────┬──────────────────────┘
│
┌──────────────┴──────────────────────┐
│ Browser APIs │
│ (Canvas, File, Blob, Download) │
└─────────────────────────────────────┘
关键设计决策
- 纯客户端处理: 所有图片处理在浏览器中完成,无需服务器,保护用户隐私
- Canvas 渲染: 使用 Canvas API 进行高性能的图片合并和渲染
- 实时预览: 拖动辅助线时立即更新预览,提供即时反馈
- 响应式设计: 适配不同屏幕尺寸,但保持图片原始尺寸
Error Handling
Image Loading Errors
- Invalid file format: Display error message “请上传有效的图片文件 (PNG, JPEG, GIF, WebP)”
- Image load failure: Display error message “图片加载失败,请重试”
- File read error: Display error message “无法读取文件,请检查文件是否损坏”
Dimension Validation Errors
- Dimension mismatch: Display error message “两张图片的尺寸不匹配。第一张图片: {width1}×{height1}, 第二张图片: {width2}×{height2}”
- Zero dimension: Display error message “图片尺寸无效”
Export Errors
- Canvas export failure: Display error message “导出图片失败,请重试”
- Download trigger failure: Log error to console and display message “下载失败,请重试”
General Error Handling Strategy
- Graceful degradation: 错误不应导致应用崩溃
- User-friendly messages: 所有错误消息使用中文,清晰描述问题
- Error recovery: 提供重置按钮让用户可以从错误状态恢复
- Console logging: 所有错误同时记录到控制台便于调试
Testing Strategy
Unit Testing
使用 Vitest 作为测试框架,针对核心功能模块编写单元测试:
ImageLoader 测试:
- 测试有效图片格式的识别
- 测试无效格式的拒绝
- 测试图片加载成功和失败场景
DimensionValidator 测试:
- 测试相同尺寸图片的验证
- 测试不同尺寸图片的拒绝
- 测试边界情况(零尺寸、极大尺寸)
MergeEngine 测试:
- 测试基本的图片合并功能
- 测试不同分割位置的合并结果
- 测试边界位置(0, 0.5, 1)
MergeLineController 测试:
- 测试拖动事件处理
- 测试位置约束逻辑
- 测试位置更新回调
ImageExporter 测试:
- 测试 Canvas 到 Blob 的转换
- 测试文件名生成
- 测试下载触发机制
Property-Based Testing
使用 fast-check 库进行基于属性的测试,验证系统在各种随机输入下的正确性:
配置要求:
- 每个属性测试至少运行 100 次迭代
- 每个测试必须使用注释标记对应的设计文档中的正确性属性
- 标记格式:
// Feature: image-merge, Property {number}: {property_text}
测试生成器:
arbitraryImageDimensions(): 生成随机但合理的图片尺寸 (10-4000 像素)arbitrarySplitPosition(): 生成 0-1 之间的随机分割位置arbitraryImageFormat(): 生成随机的图片格式字符串arbitraryCoordinate(): 生成随机坐标(包括越界值)
属性测试覆盖:
- 格式验证属性(Property 1)
- 尺寸匹配属性(Property 2)
- 边界约束属性(Property 4)
- 分割正确性属性(Property 5)
- 尺寸保持属性(Property 8)
- 格式一致性属性(Property 9)
- 状态重置属性(Property 11)
Integration Testing
测试组件间的集成:
- 完整的上传-合并-下载流程
- UI 控制器与核心引擎的交互
- 错误处理流程的端到端测试
Manual Testing Checklist
需要手动验证的 UI/UX 方面:
- 界面布局和视觉设计(Requirements 6.1-6.4)
- 拖动交互的流畅性
- 不同浏览器的兼容性
- 不同屏幕尺寸的响应式表现
- 大尺寸图片的性能表现
Implementation Notes
Browser Compatibility
目标浏览器:
- Chrome/Edge 90+
- Firefox 88+
- Safari 14+
关键 API 支持:
- Canvas API (广泛支持)
- File API (广泛支持)
- Blob API (广泛支持)
- Drag events (广泛支持)
Performance Considerations
- 大图片处理: 对于超过 4000×4000 像素的图片,考虑显示警告
- Canvas 渲染优化: 使用
requestAnimationFrame进行拖动时的重绘 - 内存管理: 在重置或加载新图片时,清理旧的图片对象引用
- 防抖处理: 拖动事件可能需要节流以提高性能
Accessibility
虽然这是一个视觉为主的应用,仍需考虑:
- 为所有按钮提供清晰的文本标签
- 使用
aria-label为图片上传区域提供描述 - 确保键盘可以访问所有交互元素
- 为错误消息使用适当的 ARIA 角色
Future Enhancements
可能的功能扩展:
- 支持水平方向的合并线
- 支持多种合并模式(渐变过渡、羽化边缘)
- 支持调整输出图片质量
- 支持批量处理多对图片
- 添加撤销/重做功能
- 保存和加载合并配置

