Flutter 框架跨平台鸿蒙开发 - 手写字体生成器
手写字体生成器应用
欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
一、项目概述
运行效果图




1.1 应用简介
手写字体生成器是一款创意工具应用,让用户通过手写样本生成专属字体。用户可以在画布上书写字符样本,应用自动将其转换为可用的字体文件,支持在线安装到手机电脑,让每条消息都有独特的个人风格。
应用以温暖的橙色为主色调,象征手写的温度与个性。涵盖字体书写、字体管理、字体预览、关于信息四大模块。用户可以创建字体项目、书写样本字符、调整字体样式、导出字体文件。
1.2 核心功能
| 功能模块 | 功能描述 | 实现方式 |
|---|---|---|
| 手写画布 | 书写字符样本 | 手势绘制 |
| 字体样式 | 多种字体风格选择 | 枚举定义 |
| 笔画设置 | 调整笔画粗细和颜色 | 参数配置 |
| 字体管理 | 管理多个字体项目 | 列表存储 |
| 字体预览 | 实时预览字体效果 | 文本展示 |
| 字体导出 | 导出多种格式字体 | 格式转换 |
1.3 字体风格定义
| 序号 | 风格名称 | Emoji | 描述 |
|---|---|---|---|
| 1 | 常规 | ✏️ | 标准手写风格 |
| 2 | 粗体 | 🖊️ | 加粗有力风格 |
| 3 | 斜体 | ✍️ | 倾斜流畅风格 |
| 4 | 草书 | 📜 | 连笔艺术风格 |
| 5 | 可爱 | 🎀 | 圆润可爱风格 |
| 6 | 优雅 | 💎 | 精致优雅风格 |
1.4 笔画粗细定义
| 序号 | 粗细名称 | Emoji | 宽度值 |
|---|---|---|---|
| 1 | 细 | 〰️ | 1.5px |
| 2 | 中 | ➖ | 2.5px |
| 3 | 粗 | ➖ | 4.0px |
| 4 | 特粗 | ▬ | 6.0px |
1.5 字体颜色定义
| 序号 | 颜色名称 | Emoji | 色值 |
|---|---|---|---|
| 1 | 黑色 | ⚫ | #000000 |
| 2 | 蓝色 | 🔵 | #2196F3 |
| 3 | 红色 | 🔴 | #F44336 |
| 4 | 绿色 | 🟢 | #4CAF50 |
| 5 | 紫色 | 🟣 | #9C27B0 |
| 6 | 棕色 | 🟤 | #795548 |
1.6 导出格式定义
| 序号 | 格式名称 | Emoji | 描述 |
|---|---|---|---|
| 1 | TTF | 🔤 | TrueType字体 |
| 2 | OTF | 🔤 | OpenType字体 |
| 3 | WOFF | 🌐 | Web字体格式 |
| 4 | WOFF2 | 🌐 | Web字体压缩格式 |
1.7 技术栈
| 技术领域 | 技术选型 | 版本要求 |
|---|---|---|
| 开发框架 | Flutter | >= 3.0.0 |
| 编程语言 | Dart | >= 2.17.0 |
| 设计规范 | Material Design 3 | - |
| 手势识别 | GestureDetector | - |
| 自定义绘制 | CustomPainter | - |
| 目标平台 | 鸿蒙OS / Web | API 21+ |
1.8 项目结构
lib/
└── main_handwriting_font_generator.dart
├── HandwritingFontGeneratorApp # 应用入口
├── FontStyle # 字体风格枚举
├── StrokeWidth # 笔画粗细枚举
├── FontColor # 字体颜色枚举
├── ExportFormat # 导出格式枚举
├── CharacterSample # 字符样本模型
├── CustomFont # 自定义字体模型
├── HandwritingFontGeneratorHomePage # 主页面(底部导航)
├── _buildWritePage # 书写页面
├── _buildFontsPage # 字体页面
├── _buildPreviewPage # 预览页面
├── _buildProfilePage # 关于页面
├── GuideLinesPainter # 辅助线绘制器
└── StrokePainter # 笔画绘制器
二、系统架构
2.1 整体架构图
2.2 类图设计
2.3 页面导航流程
2.4 字符书写流程
三、核心模块设计
3.1 数据模型设计
3.1.1 字体风格枚举 (FontStyle)
enum FontStyle {
regular(label: '常规', emoji: '✏️', description: '标准手写风格'),
bold(label: '粗体', emoji: '🖊️', description: '加粗有力风格'),
italic(label: '斜体', emoji: '✍️', description: '倾斜流畅风格'),
cursive(label: '草书', emoji: '📜', description: '连笔艺术风格'),
cute(label: '可爱', emoji: '🎀', description: '圆润可爱风格'),
elegant(label: '优雅', emoji: '💎', description: '精致优雅风格');
final String label;
final String emoji;
final String description;
}
3.1.2 笔画粗细枚举 (StrokeWidth)
enum StrokeWidth {
thin(label: '细', emoji: '〰️', width: 1.5),
medium(label: '中', emoji: '➖', width: 2.5),
thick(label: '粗', emoji: '➖', width: 4.0),
extraThick(label: '特粗', emoji: '▬', width: 6.0);
final String label;
final String emoji;
final double width;
}
3.1.3 字符样本模型 (CharacterSample)
class CharacterSample {
final String character; // 字符
final List<Offset> strokes; // 笔画轨迹点
final bool isCompleted; // 是否完成
final DateTime createdAt; // 创建时间
}
3.1.4 自定义字体模型 (CustomFont)
class CustomFont {
final String id; // 字体ID
final String name; // 字体名称
final FontStyle style; // 字体风格
final StrokeWidth strokeWidth; // 笔画粗细
final FontColor color; // 字体颜色
final List<CharacterSample> samples;// 字符样本列表
final int totalCharacters; // 总字符数
final int completedCharacters; // 已完成字符数
final DateTime createdAt; // 创建时间
double get progress; // 完成进度
}
3.1.5 字体风格分布
3.2 页面结构设计
3.2.1 主页面布局
3.2.2 书写页结构
3.2.3 书写画布结构
3.2.4 字体页结构
3.3 笔画采集逻辑
3.4 字体生成逻辑
四、UI设计规范
4.1 配色方案
应用以温暖的橙色为主色调,象征手写的温度与个性:
| 颜色类型 | 色值 | 用途 |
|---|---|---|
| 主色 | #FF7043 (Deep Orange) | 导航、主题元素 |
| 辅助色 | #FF8A65 | 字体页面 |
| 第三色 | #FFAB91 | 预览页面 |
| 强调色 | #FFCCBC | 关于页面 |
| 背景色 | #FAFAFA | 页面背景 |
| 卡片背景 | #FFFFFF | 字体卡片 |
4.2 笔画颜色
| 颜色名称 | 色值 | 视觉效果 |
|---|---|---|
| 黑色 | #000000 | 经典墨水 |
| 蓝色 | #2196F3 | 清新蓝墨 |
| 红色 | #F44336 | 热情红墨 |
| 绿色 | #4CAF50 | 自然绿墨 |
| 紫色 | #9C27B0 | 优雅紫墨 |
| 棕色 | #795548 | 复古棕墨 |
4.3 字体规范
| 元素 | 字号 | 字重 | 颜色 |
|---|---|---|---|
| 页面标题 | 24px | Bold | 主色 |
| 字体名称 | 16px | Bold | #000000 |
| 当前字符 | 16px | Bold | 主色 |
| 进度文字 | 12px | Regular | 灰色 |
| 统计数字 | 20px | Bold | 白色 |
4.4 组件规范
4.4.1 样式选择器
┌─────────────────────────────────────┐
│ 字体样式设置 │
│ │
│ 字体风格 笔画粗细 字体颜色 │
│ ┌──────────┐ ┌────────┐ ┌────────┐│
│ │✏️ 常规 ▼│ │➖ 中 ▼│ │⚫ 黑色▼││
│ └──────────┘ └────────┘ └────────┘│
└─────────────────────────────────────┘
4.4.2 书写画布
┌─────────────────────────────────────┐
│ 当前字符: 你 进度: 1/20 │
├─────────────────────────────────────┤
│ │ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │ │
│──┼────┼────┼────┼────┼────┼────┼── │
│ │ │ │ │ │ │ │ │
│ │ │ │ 你 │ │ │ │ 🗑️│
│ │ │ │ │ │ │ │ │
│──┼────┼────┼────┼────┼────┼────┼── │
│ │ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │ │
└─────────────────────────────────────┘
4.4.3 操作按钮
┌─────────────────────────────────────┐
│ [跳过] [ 保存并继续 ] │
└─────────────────────────────────────┘
4.4.4 字体卡片
┌─────────────────────────────────────┐
│ 我的手写体 ✏️ 常规 │
│ │
│ ████████░░░░░░░░░░░░░░░░░░░ 1.9% │
│ 128/6763 字符 │
│ │
│ [继续书写] [导出字体] │
└─────────────────────────────────────┘
4.4.5 导出格式选择
┌─────────────────────────────────────┐
│ 选择导出格式 │
│ │
│ ┌─────────┐ ┌─────────┐ │
│ │ 🔤 │ │ 🔤 │ │
│ │ TTF │ │ OTF │ │
│ │TrueType │ │OpenType │ │
│ └─────────┘ └─────────┘ │
│ │
│ ┌─────────┐ ┌─────────┐ │
│ │ 🌐 │ │ 🌐 │ │
│ │ WOFF │ │ WOFF2 │ │
│ │Web字体 │ │Web压缩 │ │
│ └─────────┘ └─────────┘ │
└─────────────────────────────────────┘
五、核心功能实现
5.1 笔画采集实现
void _onPanStart(DragStartDetails details) {
setState(() {
_currentStrokes.add(details.localPosition);
});
}
void _onPanUpdate(DragUpdateDetails details) {
setState(() {
_currentStrokes.add(details.localPosition);
});
}
void _onPanEnd(DragEndDetails details) {
// Stroke completed
}
5.2 笔画绘制实现
class StrokePainter extends CustomPainter {
final List<Offset> strokes;
final Color color;
final double strokeWidth;
void paint(Canvas canvas, Size size) {
if (strokes.isEmpty) return;
final paint = Paint()
..color = color
..strokeWidth = strokeWidth
..strokeCap = StrokeCap.round
..strokeJoin = StrokeJoin.round
..style = PaintingStyle.stroke;
final path = Path();
path.moveTo(strokes.first.dx, strokes.first.dy);
for (int i = 1; i < strokes.length; i++) {
path.lineTo(strokes[i].dx, strokes[i].dy);
}
canvas.drawPath(path, paint);
}
}
5.3 辅助线绘制实现
class GuideLinesPainter extends CustomPainter {
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.grey.withValues(alpha: 0.2)
..strokeWidth = 0.5;
final centerLine = Paint()
..color = Colors.grey.withValues(alpha: 0.3)
..strokeWidth = 1;
// 绘制中心线
canvas.drawLine(Offset(0, size.height / 2), Offset(size.width, size.height / 2), centerLine);
canvas.drawLine(Offset(size.width / 2, 0), Offset(size.width / 2, size.height), centerLine);
// 绘制网格线
for (double y = 0; y < size.height; y += 30) {
canvas.drawLine(Offset(0, y), Offset(size.width, y), paint);
}
for (double x = 0; x < size.width; x += 30) {
canvas.drawLine(Offset(x, 0), Offset(x, size.height), paint);
}
}
}
5.4 字符保存实现
void _saveCharacter() {
if (_currentStrokes.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('请先书写字符'),
backgroundColor: Colors.orange,
),
);
return;
}
setState(() {
_characterIndex++;
if (_characterIndex < _sampleCharacters.length) {
_currentCharacter = _sampleCharacters[_characterIndex];
} else {
_characterIndex = 0;
_currentCharacter = _sampleCharacters[0];
}
_currentStrokes.clear();
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('字符 " $_currentCharacter " 已保存'),
backgroundColor: const Color(0xFFFF7043),
),
);
}
5.5 字体创建实现
void _createNewFont() {
final font = CustomFont(
id: 'font_${DateTime.now().millisecondsSinceEpoch}',
name: '新字体 ${_myFonts.length + 1}',
style: _selectedStyle,
strokeWidth: _selectedWidth,
color: _selectedColor,
);
setState(() {
_myFonts.insert(0, font);
_currentFont = font;
_characterIndex = 0;
_currentCharacter = _sampleCharacters[0];
_currentStrokes.clear();
});
}
六、交互设计
6.1 书写流程
6.2 字体管理流程
6.3 字体预览流程
七、扩展功能规划
7.1 后续版本规划
7.2 功能扩展建议
7.2.1 真实字体生成
生成功能:
- 字符轮廓提取
- 贝塞尔曲线拟合
- 字体文件生成
- 字体元数据设置
7.2.2 AI字体优化
AI功能:
- 笔画平滑处理
- 字形规范化
- 风格迁移
- 自动补全
7.2.3 字体市场
市场功能:
- 字体分享社区
- 热门字体排行
- 字体评价系统
- 创作者认证
八、注意事项
8.1 开发注意事项
-
笔画数据:大量笔画数据需考虑存储优化
-
手势冲突:书写手势与滚动手势需正确处理
-
性能优化:实时绘制需优化渲染性能
-
字体生成:真实字体生成需要专业字体库支持
-
文件导出:Web版本文件导出需使用下载API
8.2 常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 笔画不连续 | 采样频率低 | 增加采样点 |
| 绘制卡顿 | 重绘范围大 | 局部重绘优化 |
| 字体无法导出 | 格式不支持 | 检查导出格式 |
| 样式不生效 | 状态未更新 | 检查setState |
| 进度显示错误 | 计数逻辑错误 | 检查计数器 |
8.3 字体安装说明
📱 字体安装指南 📱
iOS设备
- 下载字体文件
- 通过字体管理APP安装
- 在设置中启用字体
Android设备
- 下载字体文件
- 复制到系统字体目录
- 或使用字体管理APP
Windows电脑
- 右键字体文件
- 选择"安装"
- 或拖入字体文件夹
Mac电脑
- 双击字体文件
- 点击"安装字体"
- 在字体册中管理
九、运行说明
9.1 环境要求
| 环境 | 版本要求 |
|---|---|
| Flutter SDK | >= 3.0.0 |
| Dart SDK | >= 2.17.0 |
| 鸿蒙OS | API 21+ |
| Web浏览器 | Chrome 90+ |
9.2 运行命令
# 查看可用设备
flutter devices
# 运行到Web服务器
flutter run -d web-server -t lib/main_handwriting_font_generator.dart --web-port 8138
# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 lib/main_handwriting_font_generator.dart
# 代码分析
flutter analyze lib/main_handwriting_font_generator.dart
十、总结
手写字体生成器应用通过字体书写、字体管理、字体预览、关于信息四大模块,为用户提供了一个个性化的字体创作平台。用户可以通过手写样本生成专属字体,支持多种字体风格和笔画设置,导出多种格式字体文件。
核心功能涵盖笔画采集、样式设置、字体管理、字体导出四大模块。笔画采集通过手势识别实现实时绘制;样式设置支持6种字体风格、4种笔画粗细、6种字体颜色;字体管理支持创建多个字体项目并跟踪进度;字体导出支持TTF、OTF、WOFF、WOFF2四种格式。
应用采用 Material Design 3 设计规范,以温暖的橙色为主色调,象征手写的温度与个性。通过本应用,希望能够帮助用户创造独特的个人字体,让每条消息都有独特的个人风格。
手写字体生成器——让每条消息都有你的风格
更多推荐


所有评论(0)