欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net

一、项目概述

运行效果图

image-20260409223927837

image-20260409223935580

image-20260409223939826

image-20260409223944272

1.1 应用简介

老照片动画化是一款创意工具类应用,为用户提供照片动画制作服务。应用以棕色为主色调,象征怀旧与经典。界面设计采用复古现代结合的风格,让用户能够轻松让静止的回忆"活"过来。

应用支持多种动画效果,包括眨眼、微笑、点头、摇头、呼吸、挥手等,用户可以自由组合动画效果,调整动画强度和速度,为老照片注入生命力,让珍贵的回忆更加生动。

1.2 核心功能

功能模块功能描述实现方式
动画效果多种动画类型选择动画控制器
强度调节动画效果强度控制Slider组件
速度控制播放速度调节枚举选择
滤镜效果多种复古滤镜颜色渐变
年代标签照片年代分类枚举定义
预设模板快速应用动画组合预设数据

1.3 动画类型定义

序号动画名称Emoji颜色描述
1眨眼👁️蓝色让眼睛自然眨动
2微笑😊绿色嘴角微微上扬
3点头👇橙色轻轻点头致意
4摇头↔️粉红左右轻轻摇头
5呼吸💨青色自然的呼吸起伏
6挥手👋紫色友好的挥手动作
7缩放🔍蓝灰镜头缓慢推进
8旋转🔄棕色照片轻微旋转

1.4 照片年代定义

序号年代名称时间跨度颜色
1现代2010-至今蓝色
2千禧年代2000-2010绿色
390年代1990-2000橙色
480年代1980-1990粉红
570年代1970-1980紫色
6复古1960年前棕色

1.5 播放速度定义

序号速度名称时长(ms)Emoji颜色
1慢速2000🐢绿色
2正常1000▶️蓝色
3快速500🐇橙色

1.6 滤镜类型定义

序号滤镜名称Emoji颜色
1原图🖼️蓝灰
2怀旧🎞️棕色
3黑白灰色
4暖色☀️橙色
5冷色❄️青色
6复古📷棕褐

1.7 技术栈

技术领域技术选型版本要求
开发框架Flutter>= 3.0.0
编程语言Dart>= 2.17.0
设计规范Material Design 3-
自定义绘制CustomPainter-
动画系统AnimationController-
目标平台鸿蒙OS / WebAPI 21+

1.8 项目结构

lib/
└── main_photo_animation.dart
    ├── PhotoAnimationApp              # 应用入口
    ├── AnimationType                  # 动画类型枚举
    ├── PhotoEra                       # 照片年代枚举
    ├── AnimationSpeed                 # 播放速度枚举
    ├── FilterType                     # 滤镜类型枚举
    ├── PhotoProject                   # 照片项目模型
    ├── AnimationPreset                # 动画预设模型
    ├── PhotoAnimationHomePage         # 主页面(底部导航)
    ├── _buildEditorPage               # 编辑页面
    ├── _buildProjectsPage             # 项目页面
    ├── _buildPresetsPage              # 预设页面
    ├── _buildSettingsPage             # 设置页面
    └── PhotoContentPainter            # 照片内容绘制器

二、系统架构

2.1 整体架构图

Data Layer

Business Layer

Presentation Layer

主页面
PhotoAnimationHomePage

编辑页

项目页

预设页

设置页

动画选择

参数调节

滤镜应用

预览播放

项目列表

项目详情

项目管理

预设列表

快速应用

动画引擎
AnimationEngine

滤镜处理器
FilterProcessor

项目管理器
ProjectManager

PhotoProject
照片项目

AnimationPreset
动画预设

2.2 类图设计

contains

belongs to

has

has

contains

PhotoAnimationApp

+Widget build()

«enumeration»

AnimationType

+String label

+IconData icon

+Color color

+String description

+blink()

+smile()

+nod()

+shake()

+breathe()

+wave()

+zoom()

+rotate()

«enumeration»

PhotoEra

+String label

+String period

+Color color

+modern()

+early2000()

+nineties()

+eighties()

+seventies()

+vintage()

«enumeration»

AnimationSpeed

+String label

+int duration

+IconData icon

+Color color

+slow()

+normal()

+fast()

«enumeration»

FilterType

+String label

+IconData icon

+Color color

+none()

+sepia()

+grayscale()

+warm()

+cool()

+vintage()

PhotoProject

+String id

+String name

+String imagePath

+PhotoEra era

+List<AnimationType> animations

+AnimationSpeed speed

+FilterType filter

+double intensity

+DateTime createdAt

+DateTime lastEditedAt

AnimationPreset

+String id

+String name

+String description

+List<AnimationType> animations

2.3 页面导航流程

编辑

项目

预设

设置

应用启动

编辑页

底部导航

选择动画效果

调节参数

预览播放

保存项目

浏览项目列表

选择项目

继续编辑

浏览预设模板

应用预设

应用设置

2.4 动画播放流程

绘制器 动画控制器 编辑页 用户 绘制器 动画控制器 编辑页 用户 选择动画效果 更新选中状态 点击播放 启动动画 触发重绘 绘制动画帧 显示动画效果 点击停止 停止动画 重置状态

三、核心模块设计

3.1 数据模型设计

3.1.1 动画类型枚举 (AnimationType)
enum AnimationType {
  blink('眨眼', Icons.visibility, Color(0xFF2196F3), '让眼睛自然眨动'),
  smile('微笑', Icons.sentiment_satisfied, Color(0xFF4CAF50), '嘴角微微上扬'),
  nod('点头', Icons.arrow_downward, Color(0xFFFF9800), '轻轻点头致意'),
  shake('摇头', Icons.swap_horiz, Color(0xFFE91E63), '左右轻轻摇头'),
  breathe('呼吸', Icons.air, Color(0xFF00BCD4), '自然的呼吸起伏'),
  wave('挥手', Icons.waving_hand, Color(0xFF9C27B0), '友好的挥手动作'),
  zoom('缩放', Icons.zoom_in, Color(0xFF607D8B), '镜头缓慢推进'),
  rotate('旋转', Icons.rotate_right, Color(0xFF795548), '照片轻微旋转');

  final String label;
  final IconData icon;
  final Color color;
  final String description;
}
3.1.2 照片年代枚举 (PhotoEra)
enum PhotoEra {
  modern('现代', '2010-至今', Color(0xFF2196F3)),
  early2000('千禧年代', '2000-2010', Color(0xFF4CAF50)),
  nineties('90年代', '1990-2000', Color(0xFFFF9800)),
  eighties('80年代', '1980-1990', Color(0xFFE91E63)),
  seventies('70年代', '1970-1980', Color(0xFF9C27B0)),
  vintage('复古', '1960年前', Color(0xFF795548));

  final String label;
  final String period;
  final Color color;
}
3.1.3 照片项目模型 (PhotoProject)
class PhotoProject {
  final String id;                        // 项目ID
  final String name;                      // 项目名称
  final String imagePath;                 // 图片路径
  final PhotoEra era;                     // 照片年代
  final List<AnimationType> animations;   // 动画列表
  final AnimationSpeed speed;             // 播放速度
  final FilterType filter;                // 滤镜类型
  final double intensity;                 // 动画强度
  final DateTime createdAt;               // 创建时间
  final DateTime? lastEditedAt;           // 最后编辑时间
}
3.1.4 动画预设模型 (AnimationPreset)
class AnimationPreset {
  final String id;                        // 预设ID
  final String name;                      // 预设名称
  final String description;               // 预设描述
  final List<AnimationType> animations;   // 包含的动画
}
3.1.5 动画类型使用分布
30% 25% 15% 12% 8% 5% 3% 2% 动画类型使用分布 眨眼 微笑 呼吸 点头 挥手 摇头 缩放 旋转

3.2 页面结构设计

3.2.1 主页面布局

PhotoAnimationHomePage

IndexedStack

编辑页

项目页

预设页

设置页

NavigationBar

编辑 Tab

项目 Tab

预设 Tab

设置 Tab

3.2.2 编辑页结构

编辑页

SliverAppBar

照片预览

播放控制

动画选择

参数调节

滤镜效果

年代标签

动画渲染

播放按钮

停止按钮

动画卡片

强度滑块

速度选择

3.2.3 项目页结构

项目页

SliverAppBar

新建入口

项目列表

项目卡片

预览图

项目信息

动画标签

编辑按钮

3.2.4 预设页结构

预设页

SliverAppBar

预设列表

预设卡片

预设名称

预设描述

动画标签

应用按钮

3.3 动画播放逻辑

点击播放

已选择动画?

提示选择动画

设置播放状态

重置动画控制器

启动动画

动画完成?

继续播放

仍在播放状态?

重复动画

停止动画

3.4 动画效果绘制逻辑

眨眼

微笑

点头

摇头

呼吸

挥手

缩放

旋转

开始绘制

检查动画类型

绘制眼睛闭合

调整嘴角弧度

垂直位移

水平位移

缩放变换

旋转手臂

整体缩放

整体旋转

应用强度参数

应用滤镜效果

完成绘制

3.5 预设应用逻辑

选择预设

获取预设动画列表

清空当前选择

添加预设动画

更新UI状态

显示成功提示

跳转编辑页


四、UI设计规范

4.1 配色方案

应用以棕色为主色调,象征怀旧与经典:

颜色类型色值用途
主色#795548导航、主题元素
辅助色#A1887F渐变、背景
复古色#8D6E63复古元素
怀旧色#D4A574怀旧滤镜
成功色#4CAF50微笑动画
信息色#2196F3眨眼动画

4.2 动画类型颜色

动画类型色值视觉效果
眨眼#2196F3清新蓝色
微笑#4CAF50温暖绿色
点头#FF9800活力橙色
摇头#E91E63柔美粉红
呼吸#00BCD4自然青色
挥手#9C27B0优雅紫色

4.3 字体规范

元素字号字重颜色
页面标题24pxBold白色
动画名称14pxMedium动画颜色
参数标签18pxBold#000000
项目名称16pxSemiBold#000000
描述文字12pxRegular#666666

4.4 组件规范

4.4.1 照片预览界面
┌─────────────────────────────────────┐
│         [照片预览区域]               │
│    ┌─────────────────────┐          │
│    │                     │          │
│    │    👤 人物肖像      │          │
│    │                     │          │
│    └─────────────────────┘          │
│                                     │
│    [🎞️ 怀旧] │ [70年代]             │
└─────────────────────────────────────┘
4.4.2 动画选择卡片
┌─────────────────────────────────────┐
│ [👁️ 眨眼]  [😊 微笑]  [👇 点头]     │
│ [↔️ 摇头]  [💨 呼吸]  [👋 挥手]     │
│ [🔍 缩放]  [🔄 旋转]                │
└─────────────────────────────────────┘
4.4.3 参数调节界面
┌─────────────────────────────────────┐
│ 动画强度                            │
│ 弱 ─────────────●─────────── 强     │
│                                     │
│ 播放速度                            │
│ [🐢慢速] [▶️正常] [🐇快速]          │
└─────────────────────────────────────┘
4.4.4 预设卡片
┌─────────────────────────────────────┐
│ [✨] 自然微笑                        │
│      眨眼+微笑+呼吸,自然生动        │
│                                     │
│  [👁️眨眼] [😊微笑] [💨呼吸]         │
│                                     │
│      [ 应用预设 ]                    │
└─────────────────────────────────────┘

五、核心功能实现

5.1 动画选择实现

void _toggleAnimation(AnimationType type) {
  setState(() {
    if (_selectedAnimations.contains(type)) {
      _selectedAnimations.remove(type);
    } else {
      _selectedAnimations.add(type);
    }
  });
}

5.2 动画播放实现

void _playAnimation() {
  if (_selectedAnimations.isEmpty) return;

  setState(() {
    _isPlaying = true;
  });

  _mainAnimationController.reset();
  _mainAnimationController.forward().then((_) {
    if (_isPlaying) {
      _mainAnimationController.repeat(reverse: true);
    }
  });
}

void _stopAnimation() {
  setState(() {
    _isPlaying = false;
  });
  _mainAnimationController.stop();
  _mainAnimationController.reset();
}

5.3 项目保存实现

void _saveProject() {
  if (_currentProject == null) {
    final newProject = PhotoProject(
      id: 'p${DateTime.now().millisecondsSinceEpoch}',
      name: '新项目 ${_projects.length + 1}',
      era: _selectedEra,
      animations: List.from(_selectedAnimations),
      speed: _selectedSpeed,
      filter: _selectedFilter,
      intensity: _intensity,
      createdAt: DateTime.now(),
    );
    setState(() {
      _projects.insert(0, newProject);
      _currentProject = newProject;
    });
  } else {
    // 更新现有项目
  }
}

5.4 预设应用实现

void _applyPreset(AnimationPreset preset) {
  setState(() {
    _selectedAnimations.clear();
    _selectedAnimations.addAll(preset.animations);
    _currentIndex = 0;
  });
}

5.5 照片内容绘制实现

class PhotoContentPainter extends CustomPainter {
  final Animation<double> animation;
  final List<AnimationType> animations;
  final double intensity;
  final FilterType filter;

  
  void paint(Canvas canvas, Size size) {
    // 绘制背景
    canvas.drawRect(Rect.fromLTWH(0, 0, size.width, size.height), bgPaint);

    // 绘制面部(支持点头动画)
    final faceOffset = animations.contains(AnimationType.nod)
        ? Offset(0, animation.value * 5 * intensity)
        : Offset.zero;
    canvas.drawOval(faceRect.shift(faceOffset), facePaint);

    // 绘制眼睛(支持眨眼动画)
    if (animations.contains(AnimationType.blink)) {
      // 眨眼效果
    }

    // 绘制嘴巴(支持微笑动画)
    final smileAmount = animations.contains(AnimationType.smile)
        ? animation.value * 10 * intensity
        : 0.0;
    // 微笑曲线

    // 呼吸动画
    if (animations.contains(AnimationType.breathe)) {
      final breatheScale = 1.0 + (animation.value - 0.5) * 0.02 * intensity;
      canvas.scale(breatheScale, breatheScale);
    }
  }
}

5.6 滤镜颜色获取

List<Color> _getFilterColors() {
  switch (_selectedFilter) {
    case FilterType.sepia:
      return [const Color(0xFFD4A574), const Color(0xFF8B7355)];
    case FilterType.grayscale:
      return [const Color(0xFF808080), const Color(0xFF404040)];
    case FilterType.warm:
      return [const Color(0xFFFFD700), const Color(0xFFFF8C00)];
    case FilterType.cool:
      return [const Color(0xFF87CEEB), const Color(0xFF4682B4)];
    case FilterType.vintage:
      return [const Color(0xFFDEB887), const Color(0xFF8B4513)];
    default:
      return [const Color(0xFFF5F5DC), const Color(0xFFD2B48C)];
  }
}

六、交互设计

6.1 编辑流程

绘制器 动画控制器 编辑页 用户 绘制器 动画控制器 编辑页 用户 选择动画效果 更新选中状态 调节强度 更新强度值 点击播放 启动动画 触发重绘 显示动画效果

6.2 项目管理流程

新建

选择项目

删除项目

打开项目页

显示项目列表

用户操作

创建新项目

跳转编辑页

显示项目详情

继续编辑

确认删除

更新列表

6.3 预设应用流程

点击预设卡片

点击应用

自动跳转

浏览预设

选择预设

应用动画

跳转编辑


七、扩展功能规划

7.1 后续版本规划

2024-01-07 2024-01-14 2024-01-21 2024-01-28 2024-02-04 2024-02-11 2024-02-18 2024-02-25 2024-03-03 2024-03-10 2024-03-17 2024-03-24 2024-03-31 2024-04-07 基础UI框架 动画效果 滤镜系统 真实照片识别 AI动画生成 视频导出 社交分享 云端存储 高级特效 V1.0 基础版本 V1.1 增强版本 V1.2 进阶版本 老照片动画化开发计划

7.2 功能扩展建议

7.2.1 AI动画生成

AI功能:

  • 人脸关键点检测
  • 自动动画生成
  • 表情迁移
  • 智能美化
7.2.2 视频导出

导出功能:

  • 多种视频格式
  • 分辨率选择
  • 帧率控制
  • 水印设置
7.2.3 社交分享

分享功能:

  • 一键分享到社交平台
  • 生成GIF动图
  • 制作电子相册
  • 家庭群分享

八、注意事项

8.1 开发注意事项

  1. 动画控制:正确管理AnimationController的生命周期

  2. 性能优化:避免频繁重绘,使用RepaintBoundary

  3. 状态管理:使用setState管理UI状态

  4. 资源释放:在dispose中释放动画控制器

  5. 滤镜效果:合理使用颜色渐变模拟滤镜

8.2 常见问题

问题原因解决方案
动画不播放未选择动画先选择动画效果
动画卡顿重绘过于频繁优化绘制逻辑
滤镜不生效滤镜未选择检查滤镜状态
项目不保存未点击保存调用保存方法

8.3 使用技巧

📸 照片动画化技巧 📸

动画选择

  • 眨眼+微笑:自然生动
  • 呼吸+缩放:安静回忆
  • 点头+微笑:亲切问候
  • 挥手+眨眼:活泼可爱

参数调节

  • 强度适中更自然
  • 慢速适合怀旧感
  • 快速适合活泼风格
  • 多种动画组合效果更佳

滤镜搭配

  • 怀旧滤镜配复古年代
  • 黑白滤镜配老照片
  • 暖色滤镜配温馨回忆
  • 冷色滤镜配清新风格

九、运行说明

9.1 环境要求

环境版本要求
Flutter SDK>= 3.0.0
Dart SDK>= 2.17.0
鸿蒙OSAPI 21+
Web浏览器Chrome 90+

9.2 运行命令

# 查看可用设备
flutter devices

# 运行到Web服务器
flutter run -d web-server -t lib/main_photo_animation.dart --web-port 8145

# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 lib/main_photo_animation.dart

# 代码分析
flutter analyze lib/main_photo_animation.dart

十、总结

老照片动画化应用通过动画编辑、项目管理、预设模板、设置管理四大模块,为用户提供了一个便捷的照片动画制作平台。应用支持8种动画效果、6种照片年代、3种播放速度、6种滤镜效果,让静止的回忆"活"过来。

核心功能涵盖动画选择、强度调节、速度控制、滤镜应用四大模块。动画效果包括眨眼、微笑、点头、摇头、呼吸、挥手、缩放、旋转等,覆盖常见人物动作;照片年代从现代到复古,帮助用户标记照片时代;滤镜效果支持原图、怀旧、黑白、暖色、冷色、复古等风格,满足不同审美需求。

应用采用 Material Design 3 设计规范,以棕色为主色调,象征怀旧与经典。通过本应用,希望能够帮助用户让珍贵的回忆更加生动,让老照片焕发新的生命力。

老照片动画化——让静止的回忆"活"过来


Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐