【端午】会说话的粽子你见过吗?
我正在参加「初夏创意投稿大赛」详情请看:初夏创意投稿大赛。
前言
大家好,端午将至,首先提前祝掘金的小伙伴端午安康,端午作为中华民族的非常重要的传统节日,粽子那是必不可少的,但是你真的知道粽子的历史吗? 今天跟随本篇文章用Flutter path
画一个会科普节日的的粽子吧~
绘制
1、基本轮廓
首先我们需要将粽子的基本轮廓绘制出来,通过图片可以看到粽子的轮廓是一个圆圆的三角形状,
本篇文章所有的图形都是用纯Path
路径制作,这里我们可以将粽子的轮廓分为三个二级贝塞尔曲线来进行绘制,头、左右粽叶轮廓。 核心代码:
```dart
canvas.translate(size.width / 2, size.height / 2); canvas.translate(-50, -50); Paint paint = Paint() ..style = PaintingStyle.stroke ..strokeWidth = 2 ..color = Colors.black ..isAntiAlias = true;
Path path = Path();
path.relativeQuadraticBezierTo(50, -80, 100, 0);
path.relativeQuadraticBezierTo(90, 130, -50, 130);
path.relativeQuadraticBezierTo(-140, 0, -50, -130);
path.close();
canvas.drawPath(path, paint);
```
效果图:
### 2、粽叶
有了基本轮廓,接下来我们需要绘制粽叶,可以看到粽叶的形状是一个不规则的形状,这里可以使用Path路径联合,两个路径生成一个新的路径,这样我们就可以得到左边粽叶的区域, 核心代码:
```dart
Path path2 = Path();
path2.relativeQuadraticBezierTo(60, 100, 190, 130);
path2.relativeLineTo(0, 40);
path2.relativeLineTo(-260, 0);
path2.relativeLineTo(0, -200);
path2.close();
canvas.drawPath(
path2,
paint
..color = Color(0xFF2A9200));
```
效果图:
然后使用路径联合取这两个区域的交集,即可得到粽叶左边的区域。
核心代码:
```dart
Path pathStart = Path.combine(PathOperation.intersect, path, path2);
pathStart.close();
canvas.drawPath(
pathStart,
paint
..color = Color(0xFF2A9200)
..style = PaintingStyle.fill);
```
效果图:
有了区域以后,我们需要再来点纹路,看起来更像粽叶,这里继续使用路径联合,我们只需要将上方我们合成的新路径向左下方偏移多次即可。
核心代码:
dart
_canvasStartLines(Canvas canvas, Path pathStart, Paint paint) {
for (int i = 1; i < 10; i++) {
Path path = Path();
path.moveTo(-8 * i.toDouble(), 8 * i.toDouble());
path.relativeQuadraticBezierTo(60, 100, 190, 130);
path.relativeLineTo(0, 60);
path.relativeLineTo(-300, 0);
path.relativeLineTo(0, -200);
path.close();
canvas.drawPath(
Path.combine(PathOperation.intersect, pathStart, path),
paint
..color = Colors.black
..style = PaintingStyle.stroke);
}
}
效果图:
接下来右边粽叶同理:核心代码
这里就不贴了,想看的小伙伴参考demo,地址在最下方,已上传github。
效果图:
粽叶基本就完成啦。
### 嘴巴
嘴巴我们就用一个三阶贝塞尔曲线闭合绘制一个开心的表情。
核心代码:
dart
Path path4 = Path();
path4.moveTo(40, 20);
path4.relativeCubicTo(2, 18, 18, 18, 20, 0);
path4.close();
canvas.drawPath(path4, paint..color = Colors.black87);
效果图:
### 眼睛
眼睛我们也用两个三阶贝塞尔曲线,开心的样子。
/// 眼睛
Path path5 = Path();
path5.moveTo(20, 5);
path5.relativeCubicTo(5, -10, 15, -10, 20, 0);
canvas.drawPath(
path5,
paint
..color = Colors.black87
..style = PaintingStyle.stroke);
canvas.save();
canvas.translate(40, 0);
canvas.drawPath(
path5,
paint
..color = Colors.black87
..style = PaintingStyle.stroke);
canvas.restore();
效果图:
腮红
接下来给面部设置下肤色,然后添加一点点细节。这里我们给path路径添加一个椭圆点缀那么一下。
核心代码:
dart
/// 晒红
Path path9 = Path();
path9.addArc(Rect.fromCenter(center: Offset(30,30), width: 4, height: 6),0,pi*2);
canvas.drawPath(path9, paint..color = Color(0xFFFFA2AE)..style = PaintingStyle.fill);
canvas.save();
canvas.translate(6, 0);
canvas.drawPath(path9, paint..color = Color(0xFFFFA2AE)..style = PaintingStyle.fill);
canvas.restore();
canvas.save();
canvas.translate(34, 0);
canvas.drawPath(path9, paint..color = Color(0xFFFFA2AE)..style = PaintingStyle.fill);
canvas.restore();
canvas.save();
canvas.translate(40, 0);
canvas.drawPath(path9, paint..color = Color(0xFFFFA2AE)..style = PaintingStyle.fill);
canvas.restore();
效果图:
### 手&脚
看着光溜溜的没有手脚怎么行,接下来我们继续使用path路径给粽子添加手脚,这里有一个知识点就是我们需要找到手脚的位置坐标在哪,就需要使用到
path的路径测量
,根据路径上的点找到我们合适的手脚位置。
通过path.computeMetrics()
我们可以得到一个路径的迭代对象PathMetric()
,这个迭代对象里面包含这个路径所有图形的很多信息,我们都可以从这个对象得到,这里我们从粽叶路径中得到我们的手脚的坐标点。绘制手脚, 这里只贴了左手的代码,其他同理。
核心代码:
dart
///粽叶路径
///左边
var pms = pathStart.computeMetrics();
var first = pms.first;
var offsetStart = first.getTangentForOffset(first.length * 0.55)!;
/// 手
Path path7 = Path();
path7.moveTo(offsetStart.position.dx, offsetStart.position.dy);
path7.relativeLineTo(-30, 20);
path7.relativeLineTo(-5, -30);
/// 左手
canvas.drawPath(
path7,
paint
..color = Colors.black
..style = PaintingStyle.stroke
..strokeWidth = 3);
效果图:
### 头巾
粽子有了,接下来给粽子来个标记,我是甜粽子还是咸粽子,毕竟有人爱吃咸粽子,有人爱吃甜粽子,
这里我们用路径绘制一个头绳,然后在头绳中间对标记粽子的咸甜。
这里知识点需要掌握绘制文字,核心代码:
```dart
Path path6 = Path();
path6.moveTo(0, -50);
path6.quadraticBezierTo(50, 10, 100, -50);
canvas.drawPath(
Path.combine(PathOperation.intersect, path, path6),
paint
..color = Colors.pink
..style = PaintingStyle.stroke);
var textPainter = TextPainter( text: TextSpan( text: "甜", style: TextStyle(fontSize: 16, color: Colors.white)), textDirection: TextDirection.ltr); textPainter.layout(); var size2 = textPainter.size;
canvas.drawCircle(
Offset(50, -20),
size2.width,
paint
..color = Colors.pink
..style = PaintingStyle.fill);
textPainter.paint(
canvas, Offset(-size2.width / 2, -size2.height / 2).translate(50, -20));
```
效果图:
### 咸甜是一家
有甜粽子那也得有咸粽子不是,我们只需将上面粽子的代码复制,改下文字就可以制作一个咸粽子啦。
效果图:
背景有点空,再加个背景图:
OK,粽子的绘制工作到这里已经结束了,接下来我们让粽子说话可以给小朋友科普端午节的来历吧。
## 发声
粽子制作完成,接下来我们需要让粽子会说话,这里我使用的讯飞的语音合成WebAPI流式传输数据,将文本转化为音频文件实时播放,只需要调用接口即可将文本转化为音频文件播放,这里需要web_socket_channel
插件来和讯飞进行webSocket连接,这样做的好处是不需要集成任何sdk,只需要通过APi接口就可以实时转换,
web_socket_channel的简单使用:
创建连接:
发送消息方法:_channel?.sink.add(data);
在listen监听接收信息。
具体实现步骤已经整理文章分享: Flutter实现讯飞在线语音合成(WebSocket流式版)。
### 动画控制嘴巴开合
这里我们就让甜粽子为我们讲解,动画绘制之间的配合使用之前的文章介绍过多次,这里就不再过多介绍,直接看效果吧。
- 嘴巴张合运动曲线:
身体也加一个默认的运动曲线。
效果图:
科普文字
加上科普文章,加上声音,此处已经有声音科普了哦,想体验的小伙伴可以下载源码自己体验一下,传送门 demo地址。
这里我们使用童声豆豆的声音,
设置到这里即可。 示例代码demo地址。
用到的技术点
绘制: path路径
、贝塞尔曲线
、路径联合
、路径测量
、路径添加图形
、绘制文字
、绘制图片域
。
动画: 多动画与绘制联合使用。
通信: web_socket_channel
的使用。
文件操作: 插件 path_provider
写入文件。
播放音频操作: 插件 audioplayers
播放音频。
总个结
此灵感来源于科普中国传统节日的视频,然后就有了这篇文章,因为之前做智能家具有在客户端集成过讯飞语音,所以我又去了讯飞官方文档看有没有Flutter插件,但是很显然没有,但是看到有通过WebSocket
流形式来进行传输的时候,我觉得嗯,就是你了,但是找demo的时候,又没有dart
语言的版本,跟着文档一步一步也最终实现了需求,WebSocket
方式非常适合跨平台应用的使用,无需集成任何SDK,只通过流的传输即可完成转换。如果使用SDK集成在某一端确实很方便,但是对于跨平台应用就显得比较笨重。之后有时间在研究下讯飞的语音识别,应该大同小异。OK,那本篇文章就到这里了。最后提前祝掘金的小伙伴端午安康,生活粽
香满园。
- Flutter3.7版本新增组件-Menu菜单系列介绍
- Flutter【绘制】制作一个掘金Logo组件
- Flutter【手势&绘制】模拟纸质书籍翻页
- Flutter【绘制&手势】模拟纸质书翻页2--插件化
- Flutter【手势&绘制】围棋棋盘
- Flutter【手势&绘制】手游操纵杆移动解析
- Flutter实现讯飞在线语音合成(WebSocket流式版)
- 2022年中总结--时间过的好快
- Flutter实现讯飞在线语音听写(WebSocket流式版)
- Flutter更改输入框内容,onChanged接受不到回调?
- 【端午】会说话的粽子你见过吗?
- Flutter入口中的runApp方法解析
- Flutter实现手势密码加密、解锁
- Flutter 获取状态栏高度等于0,为啥?
- Flutter仿网易App广告卡片3D翻转
- Flutter实现心碎的感觉
- Flutter实现一个牛顿摆
- Flutter实现掘金App点赞效果
- Flutter制作一个吃豆人加载Loading
- Flutter绘制之贝塞尔曲线画一个小海豚