写点什么

滚动前行的轮子 — Flutter 交错动画应用实例

作者:岛上码农
  • 2023-02-06
    湖南
  • 本文字数:2179 字

    阅读完需:约 7 分钟

滚动前行的轮子 — Flutter 交错动画应用实例

前言

之前一篇我们讲了 Flutter 组合动画实现的方式 —— 交错动画,如需了解原理的可以查看下面这篇:组合多个动画效果 —— Flutter 交错动画(Staggered Animation)简介。借助 GIF 和绘图技巧是可以做到类似 GIF 那种效果的。本篇我们来一个应用实例,我们让轮子在草地滚动着前进,而且还能粘上“绿色的草”,运行效果如下动画所示。



动画解析

上面实现的效果实际上有三个动画组成:

  • 轮子前进的动画

  • 轮子滚动

  • 轮子的边缘颜色渐变(由黑色变成绿色)

这三个动画是同时进行的,因此需要使用到交错动画,即使用一个 AnimationController来控制三个 Tween 对象实现上述的动画组合。

编码实现

首先是轮子组件的定义,为了让轮子转动的效果能够看到,我们给轮子填充了线性的渐变色,然后轮子的尺寸、旋转速度(time)和边框颜色由上级组件来控制。整个实现很简单,就是一个加了装饰的 Container 而已。

class Wheel extends StatelessWidget {  final double size;  final Color color;  final double time;  const Wheel({    Key? key,    required this.size,    required this.time,    required this.color,  }) : super(key: key);
@override Widget build(BuildContext context) { return Container( width: size, height: size, transform: Matrix4.identity()..rotateZ(2 * pi * time), transformAlignment: Alignment.center, decoration: BoxDecoration( border: Border.all(color: color, width: 10.0), borderRadius: BorderRadius.circular(size / 2), gradient: LinearGradient( colors: [ Colors.white, Colors.orange[100]!, Colors.orange[400]!, ], ), ), ); }}
复制代码

然后是整个页面布局,整个页面布局其实就是一个 Stack,然后底部是绿色的 Container再加两个轮子,都是使用 Positioned 来确定各自的位置。然后就是通过受控的 Tween 对象控制轮子的旋转速度,轮子外边沿颜色和移动的距离,代码如下,其中轮子移动距离通过控制边距实现。

Widget build(BuildContext context) {  final bottomHeight = MediaQuery.of(context).size.height / 3;  return Scaffold(    appBar: AppBar(      title: const Text('交错动画'),    ),    body: Stack(children: [      Positioned(        child: Container(          width: double.infinity,          height: bottomHeight,          color: Colors.green[400],        ),        bottom: 0,        left: 0,        right: 0,      ),      Positioned(          child: Wheel(            size: wheelSize,            color: _color.value!,            time: _time.value,          ),          left: _offset.value * MediaQuery.of(context).size.width,          bottom: bottomHeight),      Positioned(          child: Wheel(            size: wheelSize,            color: _color.value!,            time: -_time.value,          ),          right: _offset.value * MediaQuery.of(context).size.width,          bottom: bottomHeight)    ]),    floatingActionButton: FloatingActionButton(      child: Icon(Icons.play_arrow),      onPressed: () {        if (_controller.isCompleted) {          _controller.reverse();        } else if (!_controller.isAnimating) {          _controller.forward();        }      },    ),  );}
复制代码

最后就是构建受 AnimationController 控制的 Tween 对象了,这个在组合多个动画效果 —— Flutter 交错动画(Staggered Animation)简介已经介绍过了,代码如下:

late AnimationController _controller;late Animation<double> _time;late Animation<double> _offset;late Animation<Color?> _color;
final wheelSize = 80.0;
@overridevoid initState() { _controller = AnimationController(duration: Duration(seconds: 4), vsync: this) ..addListener(() { setState(() {}); });
_time = Tween<double>(begin: 0, end: 8.0).animate( CurvedAnimation( parent: _controller, curve: Interval( 0.0, 1.0, curve: Curves.linear, ), ), ); _offset = Tween<double>(begin: 0, end: 1.0).animate( CurvedAnimation( parent: _controller, curve: Interval( 0.0, 1.0, curve: Curves.easeInCubic, ), ), ); _color = ColorTween(begin: Colors.black87, end: Colors.green).animate( CurvedAnimation( parent: _controller, curve: Interval( 0.0, 0.8, curve: Curves.easeIn, ), ), ); super.initState();}
复制代码

就这样,一对奔向对方的轮子动画效果就完成了!源码已上传至:动画相关源码

总结

交错动画实际上可以实现非常有创意的动效,只是这样会需要很高的绘图技巧,比如使用 CustomPaint 来做。接下来的几篇我们来介绍一下 CustomPaint相关的内容。

发布于: 16 小时前阅读数: 12
用户头像

岛上码农

关注

用代码连接孤岛,公众号@岛上码农 2022-03-03 加入

从南漂到北,从北漂到南的业余码农

评论

发布
暂无评论
滚动前行的轮子 — Flutter 交错动画应用实例_flutter_岛上码农_InfoQ写作社区