返回顶部
首页 > 资讯 > 移动开发 >基于Flutter制作一个吃豆人加载动画
  • 966
分享到

基于Flutter制作一个吃豆人加载动画

2024-04-02 19:04:59 966人浏览 八月长安
摘要

目录效果图绘制静态吃豆人、豆豆、眼睛加入动画属性总结效果图 国际惯例,先看效果图: 具体效果就是吃豆人会根据吃不同颜色的豆子改变身体的颜色。 绘制静态吃豆人、豆豆、眼睛 首先,我们

效果图

国际惯例,先看效果图:

具体效果就是吃豆人会根据吃不同颜色的豆子改变身体的颜色。

绘制静态吃豆人、豆豆、眼睛

首先,我们需要将这个静态的吃豆人绘制出来,我们可以把吃豆人看做是一个实心圆弧,豆豆和眼睛就是一个圆。

关键代码:

//画头
_paint
  ..color = color.value
  ..style = PaintingStyle.fill;
var rect = Rect.fromCenter(
    center: Offset(0, 0), width: size.width, height: size.height);
/// 起始角度
var a =  40 / 180 * pi;
// 绘制圆弧
canvas.drawArc(rect, 0, 2 * pi - a * 2, true, _paint);

// 画豆豆
canvas.drawOval(
    Rect.fromCenter(
        center: Offset(
            size.width / 2 +
                ddSize -
                angle2.value * (size.width / 2 + ddSize),
            0),
        width: ddSize,
        height: ddSize),
    _paint..color = color2.value);

//画眼睛
canvas.drawOval(
    Rect.fromCenter(
        center: Offset(0, -size.height / 3), width: 8, height: 8),
    _paint..color = Colors.black87);

动画属性: 嘴巴的张合:通过圆弧的角度不断改变实现,豆豆移动:从头的右侧源源不断的有豆子向左移动,改变豆豆x轴的坐标即可,接下来我们让吃豆人动起来吧。

加入动画属性

这里我们需要创建2个动画控制器,一个控制头,一个控制豆豆,我们看到因为头部一开一合属于动画正向执行一次然后再反向执行一次,相当于执行了两次,豆豆的从右边到嘴巴只执行了一次,所以头的执行时间是豆豆执行时间的两倍,嘴巴一张一合才能吃豆子嘛,吃豆完毕,将豆子颜色赋值给头改变颜色,豆子随机获取另一个颜色,不断的吃豆。 这里的绘制状态有多种情况,嘴巴的张合、豆子的平移、颜色的改变都需要进行重新绘制,这里我们可以使用 Listenable.merge方法来进行监听,接受一个Listenable数组,可以将我们需要改变的状态放到这个数组里,返回一个 Listenable赋值给CustomPainter构造函数repaint属性即可,然后在监听只需判断这个Listenable即可。

factory Listenable.merge(List<Listenable?> listenables) = _MergingListenable;

关键代码: 动画执行相关。

late Animation<double> animation; // 吃豆人
late Animation<double> animation2; // 豆豆
late AnimationController _controller = AnimationController(
    vsync: this, duration: Duration(milliseconds: 500)); //1s
late AnimationController _controller2 = AnimationController(
    vsync: this, duration: Duration(milliseconds: 1000)); //2s

//初始化吃豆人、豆豆颜色
ValueNotifier<Color> _color = ValueNotifier<Color>(Colors.yellow.shade800);
ValueNotifier<Color> _color2 =
    ValueNotifier<Color>(Colors.redAccent.shade400);

// 动画轨迹
late CurvedAnimation cure = CurvedAnimation(
    parent: _controller, curve: Curves.easeIn); // 动画运行的速度轨迹 速度的变化

@override
void initState() {
  super.initState();
  animation = Tween(begin: 0.2, end: 1.0).animate(_controller)
    ..addStatusListener((status) {
      // dismissed 动画在起始点停止
      // forward 动画正在正向执行
      // reverse 动画正在反向执行
      // completed 动画在终点停止
      if (status == AnimationStatus.completed) {
        _controller.reverse(); //反向执行 100-0
      } else if (status == AnimationStatus.dismissed) {
        _color.value = _color2.value;
        // 获取一个随机彩虹色
        _color2.value = getRandomColor();
        _controller.forward(); //正向执行 0-100
        // 豆子已经被吃了 从新加载豆子动画
        _controller2.forward(from: 0); //正向执行 0-100
      }
    });
animation2 = Tween(begin: 0.2, end: 1.0).animate(_controller2);
  // 启动动画 正向执行
  _controller.forward();
  // 启动动画 0-1循环执行
  _controller2.forward();
  // 这里这样重复调用会导致两次动画执行时间不一致 时间长了就不对应了
  // _controller2.repeat();
}

@override
void dispose() {
  _controller.dispose();
  _controller2.dispose();

  super.dispose();
}

@override
Widget build(BuildContext context) {
  return Center(
      child: CustomPaint(
    size: Size(50, 50),
    painter: Pain2Painter(
        _color,
        _color2,
        animation,
        animation2,
        Listenable.merge([
          animation,
          animation2,
          _color,
        ]),
        ddSize: 8),
  ));
}

// 获取一个随机颜色
Color getRandomColor() {
  Random random = Random.secure();
  int randomInt = random.nextInt(6);
  var colors = <Color>[
    Colors.red,
    Colors.orange,
    Colors.yellow,
    Colors.green,
    Colors.blue,
    Colors.indiGo,
    Colors.purple,
  ];
  Color color = colors[randomInt];
  while (color == _color2.value) {
    // 重复再选一个
    color = colors[random.nextInt(6)];
  }
  return color;
}

绘制吃豆人源码:

class Pain2Painter extends CustomPainter {
  final ValueNotifier<Color> color; // 吃豆人的颜色
  final ValueNotifier<Color> color2; // 豆子的的颜色
  final Animation<double> angle; // 吃豆人
  final Animation<double> angle2; // 豆
  final double ddSize; // 豆豆大小
  final Listenable listenable;

  Pain2Painter(
      this.color, this.color2, this.angle, this.angle2, this.listenable,
      {this.ddSize = 6})
      : super(repaint: listenable);
  Paint _paint = Paint();

  @override
  void paint(Canvas canvas, Size size) {
    canvas.clipRect(Offset.zero & size);
    canvas.translate(size.width / 2, size.height / 2);
    // 画豆豆
    canvas.drawOval(
        Rect.fromCenter(
            center: Offset(
                size.width / 2 +
                    ddSize -
                    angle2.value * (size.width / 2 + ddSize),
                0),
            width: ddSize,
            height: ddSize),
        _paint..color = color2.value);
    //画头
    _paint
      ..color = color.value
      ..style = PaintingStyle.fill;

    var rect = Rect.fromCenter(
        center: Offset(0, 0), width: size.width, height: size.height);

    /// 起始角度
    /// angle.value 动画控制器的值 0.2~1 0是完全闭合就是 起始0~360° 1是完全张开 起始 40°~ 280° 顺时针
    var a = angle.value * 40 / 180 * pi;
    // 绘制圆弧
    canvas.drawArc(rect, a, 2 * pi - a * 2, true, _paint);
    //画眼睛
    canvas.drawOval(
        Rect.fromCenter(
            center: Offset(0, -size.height / 3), width: 8, height: 8),
        _paint..color = Colors.black87);
canvas.drawOval(
    Rect.fromCenter(
        center: Offset(-1.5, -size.height / 3 - 1.5), width: 3, height: 3),
    _paint..color = Colors.white);
  }

  @override
  bool shouldRepaint(covariant Pain2Painter oldDelegate) {
    return oldDelegate.listenable != listenable;
  }
}

至此,一个简单的吃豆人加载Loading就完成啦。再也不要到处都是菊花转的样式了。。。

总结

通过这个加载Loading动画可以重新复习下Flutter中绘制、动画的使用的联动使用、还有多状态重绘机制,通过动画还可以改变吃豆的速度和吃豆的时间运动轨迹,有兴趣可以试试哦。

以上就是基于Flutter制作一个吃豆人加载动画的详细内容,更多关于Flutter加载动画的资料请关注编程网其它相关文章!

--结束END--

本文标题: 基于Flutter制作一个吃豆人加载动画

本文链接: https://lsjlt.com/news/146570.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 基于Flutter制作一个吃豆人加载动画
    目录效果图绘制静态吃豆人、豆豆、眼睛加入动画属性总结效果图 国际惯例,先看效果图: 具体效果就是吃豆人会根据吃不同颜色的豆子改变身体的颜色。 绘制静态吃豆人、豆豆、眼睛 首先,我们...
    99+
    2024-04-02
  • css如何制作超萌吃豆豆加载动画效果
    这篇文章给大家分享的是有关css如何制作超萌吃豆豆加载动画效果的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。豆豆加载效果 point_down:html代码:<div class=&qu...
    99+
    2023-06-08
  • 基于Flutter制作一个火箭发射动画
    目录前言效果说明AnimatedPositioned介绍火箭发射动画实现总结前言 北京时间10月16日0时23分,神舟十三号飞船成功发射,目前三名航天员已经顺利进驻空间站,开始为期6...
    99+
    2024-04-02
  • 基于Flutter制作一个心碎动画特效
    目录前言实现步骤1、绘制一个心2、绘制心的裂痕3、加入动画完整代码小结前言 继续动画探索,今天用Flutter制作一个心碎的感觉,灵感来源于今天的股市,哎,心哇凉哇凉的。废话不多说,...
    99+
    2024-04-02
  • 基于Flutter怎么制作一个火箭发射动画
    本文小编为大家详细介绍“基于Flutter怎么制作一个火箭发射动画”,内容详细,步骤清晰,细节处理妥当,希望这篇“基于Flutter怎么制作一个火箭发射动画”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。Anima...
    99+
    2023-06-29
  • 基于Flutter怎么制作一个心碎动画特效
    这篇文章主要介绍了基于Flutter怎么制作一个心碎动画特效的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇基于Flutter怎么制作一个心碎动画特效文章都会有所收获,下面我们一起来看看吧。效果图先上:实现步骤1...
    99+
    2023-06-30
  • 如何使用CSS实现一个吃豆人的Loading加载效果
    小编给大家分享一下如何使用CSS实现一个吃豆人的Loading加载效果,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!实现吃豆人的大嘴巴先来实现左边的大嘴巴,我是用了两个这种形状的东西,完后...
    99+
    2024-04-02
  • 基于Flutter实现风车加载组件的制作
    目录前言接口定义实现思路风车绘制旋转效果代码实现WindmillIndicator定义旋转速度设定风车叶片绘制风车组件运行效果总结前言 Flutter 官方提供了诸如 Circula...
    99+
    2024-04-02
  • 基于WPF制作一个可编程画板
    目录先上一张效果动图本次扩展的主要内容可编程模块的实现原理代码编辑模块的实现代码编辑模块的编译与测试WPF打印控制台数据动态编译模块的输入输出自动生成先上一张效果动图 同样老规矩,...
    99+
    2023-05-18
    WPF制作可编程画板 WPF可编程画板 WPF 画板
  • Android Flutter制作一个修改组件属性的动画
    目录简介flutter中的动画widgetAnimatedContainers使用举例总结简介 什么是动画呢?动画实际上就是不同的图片连续起来形成的。flutter为我们提供了一个A...
    99+
    2023-05-19
    Android Flutter修改组件属性动画 Android Flutter动画 Flutter 动画
  • 基于WPF绘制一个点赞大拇指动画
    目录效果图实现思路完整代码效果图 好久没有写wpf了。 最近看到飞书的点赞动画非常有意思,决定试试,虽然不及飞书那样的绚丽,但是练手还是可以的,希望自己的手艺还在! 实现思路 那么...
    99+
    2023-02-13
    WPF绘制点赞动画 WPF点赞动画 WPF 动画
  • 基于PyQt5制作一个表情包下载器
    每次和朋友聊天苦于没有表情包,而别人的表情包似乎是取之不尽、用之不竭。作为一个程序员哪能甘愿认输,于是做了一个表情包下载器供大家斗图。 首先,还是介绍一下设计思路吧,和我们之前做的百...
    99+
    2024-04-02
  • 基于小程序制作一个ChatGPT聊天机器人
    在AI技术日新月异的浪潮中,将ChatGPT与实战开发相结合,制作一个随身携带的聊天机器人,紧贴前沿的同时稳固基础。 一、前言 1.1、什么是ChatGPT 1.2、什么是文本完成 ...
    99+
    2023-08-30
    chatgpt 机器人 微信小程序 原力计划
  • 基于PyQt5制作一个动态指针时钟
    想实现这样一个功能,然后pyqt5中又没有现成的组件可以使用,于是就想着只能通过绘图的方式来实现。说到绘图的话,turtle框架无疑是最常见的选择,但其实通过pyqt5的QPain...
    99+
    2024-04-02
  • 基于Python制作一个动物识别小程序
    目录 引言研究背景目的与意义 动物识别技术概述基本原理图像处理与特征提取机器学习与深度学习方法 数据集与数据预处理数据收集与构建数据预处理步骤数据增强技术 特征提取与选择基...
    99+
    2023-10-25
    python 开发语言 图像处理
  • 基于PyQt5如何制作一个动态指针时钟
    这篇文章主要介绍基于PyQt5如何制作一个动态指针时钟,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!想实现这样一个功能,然后pyqt5中又没有现成的组件可以使用,于是就想着只能通过绘图的方式来实现。说到绘图的话,tu...
    99+
    2023-06-29
  • 基于PyQt5制作一个gif动态图片生成器
    这个小工具制作的目的是为了将多张图片组合后生成一张动态的GIF图片。设置界面化的操作,只需要将选中的图片导入最后直接生成动态图片。 导入界面相关的第三方库 from PyQt5.Q...
    99+
    2024-04-02
  • 10个基于CSS3/jQuery的加载动画设计方案分别是怎样的
    10个基于CSS3/jQuery的加载动画设计方案分别是怎样的,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。过去,由于加载图片的格式限制(只能...
    99+
    2024-04-02
  • 基于PyQt5如何制作一个gif动态图片生成器
    这篇文章的内容主要围绕基于PyQt5如何制作一个gif动态图片生成器进行讲述,文章内容清晰易懂,条理清晰,非常适合新手学习,值得大家去阅读。感兴趣的朋友可以跟随小编一起阅读吧。希望大家通过这篇文章有所收获!这个小工具制作的目的是为了将多张图...
    99+
    2023-06-28
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作