基于Flutter制作一个心碎动画特效

目录
  • 前言
  • 实现步骤
    • 1、绘制一个心
    • 2、绘制心的裂痕
    • 3、加入动画
  • 完整代码
  • 小结

前言

继续动画探索,今天用Flutter制作一个心碎的感觉,灵感来源于今天的股市,哎,心哇凉哇凉的。废话不多说,开始。

效果图先上:

实现步骤

1、绘制一个心

首先我们使用两段三阶贝塞尔曲线制作一个心型,这里因为需要实现心碎的效果,所以我们需要将心的两段用两段路径path进行绘制出来,效果:

绘制代码:

canvas.translate(size.width / 2, size.height / 2);
Paint paint = Paint();
paint
  ..style = PaintingStyle.stroke
  ..strokeWidth = 2
  ..color = Colors.black87;
Path path = Path();
path.moveTo(0, 0);
path.cubicTo(-200, -80, -60, -240, 0, -140);
path.close();
Path path2 = Path();
canvas.save();
canvas.drawPath(
    path,
    paint
    ..color = Colors.red
      ..style = PaintingStyle.stroke);
canvas.restore();
path2.cubicTo(200, -80, 60, -240, 0, -140);
path2.close();
canvas.drawPath(
    path2,
    paint..color = Colors.black87);

2、绘制心的裂痕

我们看到心确实分成两半了,但是中间还缺少裂痕,接下来我们就绘制心碎的裂痕,也很简单,在两段路径path闭合前进行绘制线,效果:

绘制代码:

path.relativeLineTo(-10, 30);
path.relativeLineTo(20, 5);
path.relativeLineTo(-20, 30);
path.relativeLineTo(20, 20);
path.relativeLineTo(-10, 20);
path.relativeLineTo(10, 10);

path2.relativeLineTo(-10, 30);
path2.relativeLineTo(20, 5);
path2.relativeLineTo(-20, 30);
path2.relativeLineTo(20, 20);
path2.relativeLineTo(-10, 20);
path2.relativeLineTo(10, 10);

OK,我们已经看到心已经有了裂痕,如何心碎,只需将画布进行翻转一定角度即可,这里我们将画布翻转45°,看下效果:

左边:

右边:

3、加入动画

已经有心碎的感觉了,接下来加入动画元素让心碎的过程动起来。

思路: 我们可以想一下,心碎的过程是什么样子,心的颜色慢慢变灰,心然后慢慢裂开,下方的动画运动曲线看起来更符合心碎的过程,里面有不舍,不甘,但最后心还是慢慢的碎了。

我们把画笔进行填充将这个动画加入进来看下最终效果。

是不是心碎了一地。

知识点: 这里我们需要找到红色和灰色的RGB色值,通过Color.fromRGBO(r, g, b, opacity)方法赋值颜色的色值。然后通过动画值改变RGB的值即可。 这里我使用的色值是:

红色:Color.fromRGBO(255, 0, 0, 1)灰色:Color.fromRGBO(169, 169, 169, 1)

完整代码

class XinSui extends StatefulWidget {
  const XinSui({Key? key}) : super(key: key);

  @override
  _XinSuiState createState() => _XinSuiState();
}

class _XinSuiState extends State<XinSui> with SingleTickerProviderStateMixin {
  late AnimationController _controller =
      AnimationController(vsync: this, duration: Duration(milliseconds: 4000))
        ..repeat();
  late CurvedAnimation cure =
      CurvedAnimation(parent: _controller, curve: Curves.bounceInOut);

  late Animation<double> animation =
      Tween<double>(begin: 0.0, end: 1.0).animate(cure);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: CustomPaint(
        size: Size(double.infinity, double.infinity),
        painter: _XinSuiPainter(animation),
      ),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

class _XinSuiPainter extends CustomPainter {
  Animation<double> animation;

  _XinSuiPainter(this.animation) : super(repaint: animation);

  @override
  void paint(Canvas canvas, Size size) {
    canvas.translate(size.width / 2, size.height / 2);
    Paint paint = Paint();
    paint
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2
      ..color = Colors.black87;
    Path path = Path();
    path.moveTo(0, 0);
    path.cubicTo(-200, -80, -60, -240, 0, -140);
    path.relativeLineTo(-10, 30);
    path.relativeLineTo(20, 5);
    path.relativeLineTo(-20, 30);
    path.relativeLineTo(20, 20);
    path.relativeLineTo(-10, 20);
    path.relativeLineTo(10, 10);
    path.close();
    Path path2 = Path();
    canvas.save();
    canvas.rotate(-pi / 4 * animation.value);
    canvas.drawPath(
        path,
        paint
        ..color = Colors.red
          ..color = Color.fromRGBO(
              255 - (86 * animation.value).toInt(),
              (animation.value * 169).toInt(),
              (animation.value * 169).toInt(),
              1)

          ..style = PaintingStyle.fill);
    canvas.restore();
    path2.cubicTo(200, -80, 60, -240, 0, -140);
    path2.relativeLineTo(-10, 30);
    path2.relativeLineTo(20, 5);
    path2.relativeLineTo(-20, 30);
    path2.relativeLineTo(20, 20);
    path2.relativeLineTo(-10, 20);
    path2.relativeLineTo(10, 10);
    path2.close();
    canvas.rotate(pi / 4 * animation.value);
    canvas.drawPath(
        path2,paint);
  }
  @override
  bool shouldRepaint(covariant _XinSuiPainter oldDelegate) {
    return oldDelegate.animation != animation;
  }
}

小结

动画曲线Curves配合绘制可以实现很多好玩的东西,这个需要勤加练习方能掌握,仅将此心碎献给今天受伤的股民朋友们

到此这篇关于基于Flutter制作一个心碎动画特效的文章就介绍到这了,更多相关Flutter心碎动画内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android Flutter实现3D动画效果示例详解

    目录 前言 AnimatedWidget 简介 3D 旋转动画的实现 总结 前言 上一篇我们介绍了 Animation 和 AnimationController 的使用,这是最基本的动画构建类.但是,如果我们想构建一个可复用的动画组件,通过外部参数来控制其动画效果的时候,上一篇的方法就不太合适了.在 Flutter 中提供了 AnimatedWidget 组件用于构建可复用的动画组件.本篇我们用 AnimatedWidget 来实现组件的3D 旋转效果,如下图所示. AnimatedWidge

  • Flutter实现牛顿摆动画效果的示例代码

    目录 前言 实现步骤 1.绘制静态效果 2.加入动画 两个关键点 完整源码 总结 前言 牛顿摆大家应该都不陌生,也叫碰碰球.永动球(理论情况下),那么今天我们用Flutter实现这么一个理论中的永动球,可以作为加载Loading使用. - 知识点:绘制.动画曲线.多动画状态更新 效果图: 实现步骤 1.绘制静态效果 首先我们需要把线和小圆球绘制出来,对于看过我之前文章的小伙伴来说这个就很简单了,效果图: 关键代码: // 小圆球半径 double radius = 6; /// 小球圆心和直线终

  • 基于Flutter实现爱心三连动画效果

    目录 前言 Animation 简介 AnimationController 简介 应用 - 爱心三连 总结 前言 我们开始 Flutter 动画相关篇章之旅,在应用中通过动效能够给用户带来更愉悦的体验,比较典型的例子就是一些直播平台的动效了,比如送火箭能做出来那种火箭发射的动效——感觉倍有面子,当然这是土豪的享受,我等码农只在视频里看过.本篇我们来介绍基于 Animation 类实现的基本动画构建. Animation 简介 Animation 是一个抽象类,它并不参与屏幕的绘制,而是在设定的

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

    目录 效果图 绘制静态吃豆人.豆豆.眼睛 加入动画属性 总结 效果图 国际惯例,先看效果图: 具体效果就是吃豆人会根据吃不同颜色的豆子改变身体的颜色. 绘制静态吃豆人.豆豆.眼睛 首先,我们需要将这个静态的吃豆人绘制出来,我们可以把吃豆人看做是一个实心圆弧,豆豆和眼睛就是一个圆. 关键代码: //画头 _paint ..color = color.value ..style = PaintingStyle.fill; var rect = Rect.fromCenter( center: Off

  • Flutter实现心动的动画特效

    目录 实现动画 混入 SingleTickerProviderStateMixin 创建动画 抽离成小组件 完整代码 为了追求更好的用户体验,有时候我们需要一个类似心跳一样跳动着的控件来吸引用户的注意力,这是一个小小的优化需求,但是在 Flutter 里动画两件套就像裹脚布一样臭长,所以需要像封装一个 AnimatedWidget,解放生产力. 实现动画 混入 SingleTickerProviderStateMixin 当创建一个 AnimationController 时,需要传递一个vsy

  • Android Flutter实现五种酷炫文字动画效果详解

    目录 前言 波浪涌动效果 波浪线跳动文字组 彩虹动效 滚动广告牌效果 打字效果 其他效果 自定义效果 总结 前言 偶然逛国外博客,看到了一个介绍文字动画的库,进入 pub 一看,立马就爱上这个动画库了,几乎你能想到的文字动画效果它都有!现在正式给大家安利一下这个库:animated_text_kit.本篇我们介绍几个酷炫的效果,其他的效果大家可以自行查看官网文档使用. 波浪涌动效果 波浪涌动 上面的动画效果只需要下面几行代码,其中loadUntil用于控制波浪最终停留的高度,取值是0-1.0,如

  • 基于Flutter制作一个心碎动画特效

    目录 前言 实现步骤 1.绘制一个心 2.绘制心的裂痕 3.加入动画 完整代码 小结 前言 继续动画探索,今天用Flutter制作一个心碎的感觉,灵感来源于今天的股市,哎,心哇凉哇凉的.废话不多说,开始. 效果图先上: 实现步骤 1.绘制一个心 首先我们使用两段三阶贝塞尔曲线制作一个心型,这里因为需要实现心碎的效果,所以我们需要将心的两段用两段路径path进行绘制出来,效果: 绘制代码: canvas.translate(size.width / 2, size.height / 2); Pai

  • 基于Flutter制作一个火箭发射动画

    目录 总结 前言 北京时间10月16日0时23分,神舟十三号飞船成功发射,目前三名航天员已经顺利进驻空间站,开始为期6个月的“太空差旅”生活. 国家的航天技术的突飞猛进也让岛上码农很自豪,今天看 Flutter 的动画知识,看到了 AnimatedPositioned 这个组件,可以用于控制组件的相对位置移动.结合这个神舟十三号的发射,灵机一动,正好可以使用AnimatedPositioned 这个组件实现火箭发射动画.话不多说,先上效果! 效果说明 这里其实是两张图片叠加,一张是背景地球星空的

  • 利用Flutter制作一个摸鱼桌面版App

    目录 准备工作 开始敲代码 找到资源 思考布局 实现布局 思考动画 实现动画 结语 Win10商店上架了一款名为<摸鱼>的App,在下载打开之后,这个App会让你的电脑进入一个假更新的画面,让别人以为你的电脑正在升级,这时候你就可以休息一下,优雅地喝一杯咖啡.  顿时这个念头划过了我的脑海:好东西,但是我用的是 MacBook,不能用这个应用.但是貌似我可以自己写一个? 准备工作 年轻最需要的就是行动力,想到就干,尽管我此刻正在理顺 DevFest 的讲稿,但丝毫不妨碍我用 10 分钟写一个

  • 基于replaceChild制作简单的吞噬特效

    效果演示图: 源   码   查   看 [HTML代码说明] <ul class="list" id="list"> <li class="in">1</li> <li class="in">2</li> <li class="in">3</li> <li class="in">4</

  • 使用html+css制作一个发光立方体特效

    目录 一.话不多,看效果 二.实现(附完整代码) 1.定义标签: 2.定义外层盒子css: 3.定义盒子6个面分别的样式: 一.话不多,看效果 二.实现(附完整代码) 1.定义标签: <div class="container"> <div class="q1"></div> <div class="h2"></div> <div class="z3">&

  • 详解基于electron制作一个node压缩图片的桌面应用

    基于electron制作一个node压缩图片的桌面应用 下载地址:https://github.com/zenoslin/imagemin-electron/releases 项目源码Github:https://github.com/zenoslin/imagemin-electron 准备工作 我们来整理一下我们需要做什么: 压缩图片模块 获取文件路径 桌面应用生成 压缩图片 我们需要使用imagemin这个库来压缩图片,这里我们把这个库封装成压缩模块. const imagemin = r

  • 基于QT制作一个简易的传输文件小工具

    最近因为一个事情很恼火,因为办公需要用到企业微信,但是企业微信只能在一个电脑上登陆,所以当别人发文件给你的时候,你只能一个电脑接收,创建共享文件夹也很麻烦,每次都需要去访问,很麻烦.所以准备自己写一个文件传输小工具. 功能就是能实现文件的双向传输,即客户端能传给服务端,服务端可以传给客户端. 使用的tcp通信,其实就是发消息,但是组合数据我是借鉴了IT1995大神写的代码. 先看下效果图 可以看到既可以接受文件也可进行发送文件,只要2台电脑在统一局域网内,就可发送和接受数据. 本地文件下出现了一

随机推荐