flutter有很多动画实现方式 我尝试的是其中比较常规的
即通过继承AnimatedWidget实现动画 至于画什么 就画博客首页里的那只鸟吧
class Bird extends AnimatedWidget {
const Bird({Key? key, required AnimationController controller})
: super(key: key, listenable: controller);
Animation<double> get _progress => listenable as Animation<double>;
AnimatedWidget的动画实现原理比较简单,通过传入 controller 然后用get方法拿到插值。 而controller 则需要一个实现了TickerProvider的类来提供。
class _AniBirdState extends State<AniBird> with TickerProviderStateMixin {
late final AnimationController _controller =
AnimationController(vsync: this, duration: const Duration(seconds: 3))
..repeat(reverse: true);
@override
Widget build(BuildContext context) {
return Bird(controller: _controller);
}
}
这里之所以要继承State是因为TickerProvider接口必须是StateWidget才行,
而你用到了StateWidget 那必然只能通过StatefulWidget来实现了。
剩下的就是烦琐的拼装,相对于web的css来说,写起来还是挺费功夫。
对于各个组件的动画,你可能需要不同的速度和曲线的插值,理论上一个基础插值是可以通过方法变换速率曲线和延迟反复等等,其实就是函数图像的各种改变。从而能够用一个controller实现不同部位的动画控制。
这里举个栗子,速率改变:
double boosts(double origin, double rate) {
var n = (origin * rate).ceil() % 2 == 1;
var b = origin * rate % 1;
return n ? 1 - b : b;
}
然后在Bird中你就可以如下改变动画速度:
double v = _progress.value;
double v1 = boosts(v, 10);
double v2 = boosts(v, 2);
Widget foot = Transform(
transform: Matrix4.rotationZ(-0.3 - v2 * 0.6),
origin: Offset(d * 0.075, 0),
child: BirdFoot(
height: d * 0.5,
),
);
最终效果如下:
这样写下来,感觉缺憾还是有的,我觉得自己需要一个更为清晰专注的动画表现方式,即如如何更加精准分离动画的配置。