DevShots - 极客晒图

Design Document - Image Merge

Overview

Image Merge 是一个纯前端的单页面网页应用,使用 HTML5 Canvas API 实现图片的加载、处理和合并。应用采用原生 JavaScript 开发,无需外部依赖,确保轻量和快速加载。

核心工作流程:

  1. 用户通过文件输入上传两张图片
  2. 系统验证图片格式和尺寸匹配
  3. 在 Canvas 上渲染两张图片的合并预览
  4. 用户拖动垂直辅助线调整合并位置
  5. 实时更新预览显示
  6. 用户点击下载按钮导出合并后的图片

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)     │
└─────────────────────────────────────┘

关键设计决策

  1. 纯客户端处理: 所有图片处理在浏览器中完成,无需服务器,保护用户隐私
  2. Canvas 渲染: 使用 Canvas API 进行高性能的图片合并和渲染
  3. 实时预览: 拖动辅助线时立即更新预览,提供即时反馈
  4. 响应式设计: 适配不同屏幕尺寸,但保持图片原始尺寸

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

  1. Graceful degradation: 错误不应导致应用崩溃
  2. User-friendly messages: 所有错误消息使用中文,清晰描述问题
  3. Error recovery: 提供重置按钮让用户可以从错误状态恢复
  4. 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

  1. 大图片处理: 对于超过 4000×4000 像素的图片,考虑显示警告
  2. Canvas 渲染优化: 使用 requestAnimationFrame 进行拖动时的重绘
  3. 内存管理: 在重置或加载新图片时,清理旧的图片对象引用
  4. 防抖处理: 拖动事件可能需要节流以提高性能

Accessibility

虽然这是一个视觉为主的应用,仍需考虑:

  • 为所有按钮提供清晰的文本标签
  • 使用 aria-label 为图片上传区域提供描述
  • 确保键盘可以访问所有交互元素
  • 为错误消息使用适当的 ARIA 角色

Future Enhancements

可能的功能扩展:

  • 支持水平方向的合并线
  • 支持多种合并模式(渐变过渡、羽化边缘)
  • 支持调整输出图片质量
  • 支持批量处理多对图片
  • 添加撤销/重做功能
  • 保存和加载合并配置

马上使用

全部项目

  • appicon
    DevShots