前言

大家好,端午将至,首先提前祝小伙伴端午安康,端午作为中华民族的非常重要的传统节日,粽子那是必不可少的,但是你真的知道粽子的历史吗? 今天跟随本篇文章用flutter path画一个会科普节日的的粽子吧~

绘制

基本轮廓

首先我们需要将粽子的基本轮廓绘制出来,通过图片可以看到粽子的轮廓是一个圆圆的三角形状,

本篇文章所有的图形都是用纯path路径制作,这里我们可以将粽子的轮廓分为三个二级贝塞尔曲线来进行绘制,头、左右粽叶轮廓。

核心代码:

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);

效果图:

粽叶

有了基本轮廓,接下来我们需要绘制粽叶,可以看到粽叶的形状是一个不规则的形状,这里可以使用path路径联合,两个路径生成一个新的路径,这样我们就可以得到左边粽叶的区域, 核心代码:

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));

效果图:

然后使用路径联合取这两个区域的交集,即可得到粽叶左边的区域。

核心代码:

path pathstart = path.combine(pathoperation.intersect, path, path2);
pathstart.close();

canvas.drawpath(
   pathstart,
   paint
     ..color = color(0xff2a9200)
     ..style = paintingstyle.fill);

效果图:

有了区域以后,我们需要再来点纹路,看起来更像粽叶,这里继续使用路径联合,我们只需要将上方我们合成的新路径向左下方偏移多次即可。 核心代码:

_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);
  }
}

效果图:

接下来右边粽叶同理:核心代码这里就不贴了,

效果图:

粽叶基本就完成啦。

嘴巴

嘴巴我们就用一个三阶贝塞尔曲线闭合绘制一个开心的表情。

核心代码:

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路径添加一个椭圆点缀那么一下。 核心代码:

/// 晒红
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() ,这个迭代对象里面包含这个路径所有图形的很多信息,我们都可以从这个对象得到,这里我们从粽叶路径中得到我们的手脚的坐标点。绘制手脚, 这里只贴了左手的代码,其他同理。

核心代码:

///粽叶路径
///左边
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);

效果图:

头巾

粽子有了,接下来给粽子来个标记,我是甜粽子还是咸粽子,毕竟有人爱吃咸粽子,有人爱吃甜粽子, 这里我们用路径绘制一个头绳,然后在头绳中间对标记粽子的咸甜。

这里知识点需要掌握绘制文字,核心代码:

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 api版本的实现步骤以及websocket后面我会单独整理进行分享。

动画控制嘴巴开合

这里我们就让甜粽子为我们讲解,动画绘制之间的配合使用之前的文章介绍过多次,这里就不再过多介绍,直接看效果吧。

嘴巴张合运动曲线:

身体也加一个默认的运动曲线。

效果图:

加上科普文章,加上声音。此处已经有声音科普了哦,想体验的小伙伴可以下载源码自己体验一下,后续我会整理上传

这里我们使用童声豆豆的声音,

设置到这里即可。 示例代码之后会整理上传到github上。

用到的技术点

绘制:path路径、贝塞尔曲线、路径联合、路径测量、路径添加图形、绘制文字、绘制图片域。

动画:多动画与绘制联合使用。

通信:web_socket_channel 的使用。

文件操作:插件 path_provider 写入文件。

播放音频操作:插件 audioplayers 播放音频。

总结

此灵感来源于科普中国传统节日的视频,然后就有了这篇文章,因为之前做智能家具有在客户端集成过讯飞语音,所以我又去了讯飞官方文档看有没有flutter插件,但是很显然没有,但是看到有通过websocket流形式来进行传输的时候,我觉得嗯,就是你了,但是找demo的时候,又没有dart语言的版本,跟着文档一步一步也最终实现了需求,websocket方式非常适合跨平台应用的使用,无需集成任何sdk,只通过流的传输即可完成转换。如果使用sdk集成在某一端确实很方便,但是对于跨平台应用就显得比较笨重。之后有时间在研究下讯飞的语音识别,应该大同小异。

以上就是android利用flutter path绘制粽子的示例代码的详细内容,更多关于android flutter绘制粽子的资料请关注其它相关文章!