文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2023-06-30 10:33

关注

这篇文章主要介绍了基于Flutter怎么制作一个心碎动画特效的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇基于Flutter怎么制作一个心碎动画特效文章都会有所收获,下面我们一起来看看吧。

效果图先上:

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

实现步骤

1、绘制一个心

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

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

绘制代码:

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 path3 = Path();canvas.save();canvas.drawPath(    path,    paint    ..color = Colors.red      ..style = PaintingStyle.stroke);canvas.restore();path3.cubicTo(200, -80, 60, -240, 0, -140);path3.close();canvas.drawPath(    path3,    paint..color = Colors.black87);

2、绘制心的裂痕

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

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

绘制代码:

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

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

左边:

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

右边:

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

3、加入动画

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

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

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

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

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

是不是心碎了一地。

知识点: 这里我们需要找到红色和灰色的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 path3 = 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();    path3.cubicTo(200, -80, 60, -240, 0, -140);    path3.relativeLineTo(-10, 30);    path3.relativeLineTo(20, 5);    path3.relativeLineTo(-20, 30);    path3.relativeLineTo(20, 20);    path3.relativeLineTo(-10, 20);    path3.relativeLineTo(10, 10);    path3.close();    canvas.rotate(pi / 4 * animation.value);    canvas.drawPath(        path3,paint);  }  @override  bool shouldRepaint(covariant _XinSuiPainter oldDelegate) {    return oldDelegate.animation != animation;  }}

关于“基于Flutter怎么制作一个心碎动画特效”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“基于Flutter怎么制作一个心碎动画特效”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯