【端午】會說話的粽子你見過嗎?
我正在參加「初夏創意投稿大賽」詳情請看:初夏創意投稿大賽。
前言
大家好,端午將至,首先提前祝掘金的小夥伴端午安康,端午作為中華民族的非常重要的傳統節日,粽子那是必不可少的,但是你真的知道粽子的歷史嗎? 今天跟隨本篇文章用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繪製之貝塞爾曲線畫一個小海豚