Android利用Flutter?path繪制粽子的示例代碼
前言
大家好,端午將至,首先提前祝小伙伴端午安康,端午作為中華民族的非常重要的傳統(tǒng)節(jié)日,粽子那是必不可少的,但是你真的知道粽子的歷史嗎? 今天跟隨本篇文章用Flutter path
畫一個(gè)會(huì)科普節(jié)日的的粽子吧~
繪制
基本輪廓
首先我們需要將粽子的基本輪廓繪制出來,通過圖片可以看到粽子的輪廓是一個(gè)圓圓的三角形狀,
本篇文章所有的圖形都是用純Path
路徑制作,這里我們可以將粽子的輪廓分為三個(gè)二級(jí)貝塞爾曲線來進(jìn)行繪制,頭、左右粽葉輪廓。
核心代碼:
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);
效果圖:
粽葉
有了基本輪廓,接下來我們需要繪制粽葉,可以看到粽葉的形狀是一個(gè)不規(guī)則的形狀,這里可以使用Path路徑聯(lián)合,兩個(gè)路徑生成一個(gè)新的路徑,這樣我們就可以得到左邊粽葉的區(qū)域, 核心代碼:
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));
效果圖:
然后使用路徑聯(lián)合取這兩個(gè)區(qū)域的交集,即可得到粽葉左邊的區(qū)域。
核心代碼:
Path pathStart = Path.combine(PathOperation.intersect, path, path2); pathStart.close(); canvas.drawPath( pathStart, paint ..color = Color(0xFF2A9200) ..style = PaintingStyle.fill);
效果圖:
有了區(qū)域以后,我們需要再來點(diǎn)紋路,看起來更像粽葉,這里繼續(xù)使用路徑聯(lián)合,我們只需要將上方我們合成的新路徑向左下方偏移多次即可。 核心代碼:
_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); } }
效果圖:
接下來右邊粽葉同理:核心代碼這里就不貼了,
效果圖:
粽葉基本就完成啦。
嘴巴
嘴巴我們就用一個(gè)三階貝塞爾曲線閉合繪制一個(gè)開心的表情。
核心代碼:
Path path4 = Path(); path4.moveTo(40, 20); path4.relativeCubicTo(2, 18, 18, 18, 20, 0); path4.close(); canvas.drawPath(path4, paint..color = Colors.black87);
效果圖:
眼睛
眼睛我們也用兩個(gè)三階貝塞爾曲線,開心的樣子。
/// 眼睛 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();
效果圖:
腮紅
接下來給面部設(shè)置下膚色,然后添加一點(diǎn)點(diǎn)細(xì)節(jié)。這里我們給path路徑添加一個(gè)橢圓點(diǎn)綴那么一下。 核心代碼:
/// 曬紅 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();
效果圖:
手&腳
看著光溜溜的沒有手腳怎么行,接下來我們繼續(xù)使用path路徑給粽子添加手腳,這里有一個(gè)知識(shí)點(diǎn)就是我們需要找到手腳的位置坐標(biāo)在哪,就需要使用到 path的路徑測(cè)量 ,根據(jù)路徑上的點(diǎn)找到我們合適的手腳位置。
通過path.computeMetrics()
我們可以得到一個(gè)路徑的迭代對(duì)象PathMetric()
,這個(gè)迭代對(duì)象里面包含這個(gè)路徑所有圖形的很多信息,我們都可以從這個(gè)對(duì)象得到,這里我們從粽葉路徑中得到我們的手腳的坐標(biāo)點(diǎn)。繪制手腳, 這里只貼了左手的代碼,其他同理。
核心代碼:
///粽葉路徑 ///左邊 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);
效果圖:
頭巾
粽子有了,接下來給粽子來個(gè)標(biāo)記,我是甜粽子還是咸粽子,畢竟有人愛吃咸粽子,有人愛吃甜粽子, 這里我們用路徑繪制一個(gè)頭繩,然后在頭繩中間對(duì)標(biāo)記粽子的咸甜。
這里知識(shí)點(diǎn)需要掌握繪制文字,核心代碼:
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));
效果圖:
咸甜是一家
有甜粽子那也得有咸粽子不是,我們只需將上面粽子的代碼復(fù)制,改下文字就可以制作一個(gè)咸粽子啦。 效果圖:
背景有點(diǎn)空,再加個(gè)背景圖:
OK,粽子的繪制工作到這里已經(jīng)結(jié)束了,接下來我們讓粽子說話可以給小朋友科普端午節(jié)的來歷吧。
發(fā)聲
粽子制作完成,接下來我們需要讓粽子會(huì)說話,這里我使用的訊飛的語音合成WebAPI流式傳輸數(shù)據(jù),將文本轉(zhuǎn)化為音頻文件實(shí)時(shí)播放,只需要調(diào)用接口即可將文本轉(zhuǎn)化為音頻文件播放,這里需要web_socket_channel
插件來和訊飛進(jìn)行webSocket連接,這樣做的好處是不需要集成任何sdk,只需要通過APi接口就可以實(shí)時(shí)轉(zhuǎn)換
web_socket_channel的簡(jiǎn)單使用:創(chuàng)建連接:
發(fā)送消息方法:_channel?.sink.add(data);
在listen監(jiān)聽接收信息。
這里簡(jiǎn)單的介紹下,具體訊飛 Flutter API版本的實(shí)現(xiàn)步驟以及WebSocket后面我會(huì)單獨(dú)整理進(jìn)行分享。
動(dòng)畫控制嘴巴開合
這里我們就讓甜粽子為我們講解,動(dòng)畫繪制之間的配合使用之前的文章介紹過多次,這里就不再過多介紹,直接看效果吧。
嘴巴張合運(yùn)動(dòng)曲線:
身體也加一個(gè)默認(rèn)的運(yùn)動(dòng)曲線。
效果圖:
加上科普文章,加上聲音。此處已經(jīng)有聲音科普了哦,想體驗(yàn)的小伙伴可以下載源碼自己體驗(yàn)一下,后續(xù)我會(huì)整理上傳。
這里我們使用童聲豆豆的聲音,
設(shè)置到這里即可。 示例代碼之后會(huì)整理上傳到github上。
用到的技術(shù)點(diǎn)
繪制:path路徑、貝塞爾曲線、路徑聯(lián)合、路徑測(cè)量、路徑添加圖形、繪制文字、繪制圖片域。
動(dòng)畫:多動(dòng)畫與繪制聯(lián)合使用。
通信:web_socket_channel 的使用。
文件操作:插件 path_provider 寫入文件。
播放音頻操作:插件 audioplayers 播放音頻。
總結(jié)
此靈感來源于科普中國(guó)傳統(tǒng)節(jié)日的視頻,然后就有了這篇文章,因?yàn)橹白鲋悄芗揖哂性诳蛻舳思蛇^訊飛語音,所以我又去了訊飛官方文檔看有沒有Flutter插件,但是很顯然沒有,但是看到有通過WebSocket
流形式來進(jìn)行傳輸?shù)臅r(shí)候,我覺得嗯,就是你了,但是找demo的時(shí)候,又沒有dart
語言的版本,跟著文檔一步一步也最終實(shí)現(xiàn)了需求,WebSocket
方式非常適合跨平臺(tái)應(yīng)用的使用,無需集成任何SDK,只通過流的傳輸即可完成轉(zhuǎn)換。如果使用SDK集成在某一端確實(shí)很方便,但是對(duì)于跨平臺(tái)應(yīng)用就顯得比較笨重。之后有時(shí)間在研究下訊飛的語音識(shí)別,應(yīng)該大同小異。
以上就是Android利用Flutter path繪制粽子的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于Android Flutter繪制粽子的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Flutter應(yīng)用框架運(yùn)行微信小程序方法
這篇文章主要介紹了在Flutter?App內(nèi)運(yùn)行微信小程序的過程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-02-02Android RecyclerView詳解及簡(jiǎn)單實(shí)例
這篇文章主要介紹了Android RecyclerView詳解及簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-01-01Android?模擬地圖定位功能的實(shí)現(xiàn)
這篇文章主要介紹了Android?模擬地圖定位功能的實(shí)現(xiàn),本工程利用手機(jī)自帶的"模擬位置"功能實(shí)現(xiàn)運(yùn)行時(shí)修改LocationManager結(jié)果,需要的朋友可以參考一下2022-02-02Android中的Selector的用法詳解及實(shí)例
這篇文章主要介紹了Android中的Selector的用法詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-05-05Android實(shí)現(xiàn)獲取驗(yàn)證碼倒計(jì)時(shí)功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)獲取驗(yàn)證碼倒計(jì)時(shí)功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12深入Android Handler,MessageQueue與Looper關(guān)系
這篇文章主要介紹了深入Android Handler,MessageQueue與Looper關(guān)系,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08Android實(shí)現(xiàn)一個(gè)完美的倒計(jì)時(shí)功能
在Adroid應(yīng)用中,倒計(jì)時(shí)的功能使用的很多,例如點(diǎn)擊獲取短信驗(yàn)證碼之后的倒計(jì)時(shí)等等,這篇文章主要給大家介紹了關(guān)于利用Android如何實(shí)現(xiàn)一個(gè)完美的倒計(jì)時(shí)功能的相關(guān)資料,需要的朋友可以參考下2021-11-11Android Selector 按下修改背景和文本顏色的實(shí)現(xiàn)代碼
這篇文章主要介紹了Android Selector 按下修改背景和文本顏色的實(shí)現(xiàn)代碼,本文通過實(shí)例代碼和demo展示給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-11-11