效果GIF
ani.gif
其他都是單一的動畫,主要拆解下Staggered Animation
分析
動畫需要根據一個時間軸執行,下圖是官方demo的一個分析圖,本文實現和此圖基本差不多,只是多了1個翻轉動畫
image.png
實現
- 透明度漸變
Animation<double> opacity = Tween<double>(
begin: 0.0,
end: 1.0,
).animate(
CurvedAnimation(
parent: _controller,
curve: Interval(
0.0,
0.1,
curve: Curves.easeIn,
),
),
);
- 翻轉
Animation<double> rotate = Tween<double>(
begin: 0.0,
end: math.pi * 2,
).animate(
CurvedAnimation(
parent: _controller,
curve: Interval(
0.0,
0.2,
curve: Curves.ease,
),
),
);
- 位移
Animation<EdgeInsets> movement = EdgeInsetsTween(
begin: EdgeInsets.only(top: 0.0),
end: EdgeInsets.only(top: 100.0),
).animate(
CurvedAnimation(
parent: _controller,
curve: Interval(
0.2,
0.375,
curve: Curves.fastOutSlowIn,
),
),
);
- 方形變圓
Animation<BorderRadius> radius = BorderRadiusTween(
begin: BorderRadius.circular(0.0),
end: BorderRadius.circular(100.0),
).animate(
CurvedAnimation(
parent: _controller,
curve: Interval(
0.5,
0.75,
curve: Curves.ease,
),
),
);
- 顏色漸變
Animation<Color> color = ColorTween(
begin: Colors.blue[300],
end: Colors.blue[900],
).animate(
CurvedAnimation(
parent: _controller,
curve: Interval(
0.5,
0.75,
curve: Curves.linear,
),
),
);
- 高寬漸變
Animation<double> height = Tween<double>(
begin: 100.0,
end: 200.0,
).animate(
CurvedAnimation(
parent: _controller,
curve: Interval(
0.375,
0.6,
curve: Curves.fastOutSlowIn,
),
),
);
Animation<double> width = Tween<double>(
begin: 100.0,
end: 200.0,
).animate(
CurvedAnimation(
parent: _controller,
curve: Interval(
0.375,
0.6,
curve: Curves.fastOutSlowIn,
),
),
);
- 組合
Widget _buildAni(BuildContext context, Widget child) {
return new Container(
padding: movement.value,
transform: Matrix4.identity()..rotateZ(rotate.value),
child: new Opacity(
opacity: opacity.value,
child: new Container(
width: width.value,
height: height.value,
decoration: new BoxDecoration(
color: color.value,
border: new Border.all(
color: Colors.black,
width: 3.0,
),
borderRadius: radius.value,
),
child: new Center(
child: new Text(
'staggered',
style: new TextStyle(color: Colors.white, fontSize: 16.0),
),
),
),
),
);
}
@override
Widget build(BuildContext context) {
return new Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new Padding(
padding:
const EdgeInsets.only(left: 10.0, top: 10.0, right: 10.0),
child: new FlatButton(
textColor: Colors.black,
child: new Text('replay staggered'),
onPressed: () {
_startAnimation();
}),
),
new AnimatedBuilder(animation: _controller, builder: _buildAni)
],
);
}