3个动画,组合成这样的,一个一个来.
- 首先是旋转动画
本身flutter就带一个旋转的动画组件RotationTransition
,使用的时候就是传入一个AnimationController就可以了,
repeat()就是循环播放的意思.
late AnimationController _rotationController;
@override
void initState() {
super.initState();
_rotationController = AnimationController(
duration: const Duration(seconds: 6),
vsync: this,
)..repeat();
}
//在build里
RotationTransition(
turns: _rotationController,
child: Container(),
),
- 波浪的动画
这个是在网上借鉴的,在网上找到的是波浪的动画,实际上我们需要的是一个圆线向外扩展,不是波浪,改一改就达到效果了.水波纹的被我注释掉了,想用的自己把注释解开,把我用的注释活删掉都行.
_linController 动画控制器
调用:
AnimatedBuilder(
animation: _linController,
builder: (context, child) {
return CustomPaint(
painter: WaterRipplePainter(
_linController.value,
count: 1,
),
);
},
),
class WaterRipplePainter extends CustomPainter {
final double progress;
final int count; //有几条线,如果是要用波纹的情况下,给2到3个显示效果最佳
final Color color;
WaterRipplePainter(this.progress,
{this.count = 1, this.color = const Color(0xFF0080ff)});
@override
void paint(Canvas canvas, Size size) {
double radius = min(size.width / 2, size.height / 2);
for (int i = count; i >= 0; i--) {
final double opacity = (1.0 - ((i + progress) / (count + 1)));
final Color _color = color.withOpacity(opacity);
double _radius = radius * ((i + progress) / (count + 1));
//水波纹
// Paint _paint = Paint()
// ..style = PaintingStyle.fill
// ..color = _color;
// canvas.drawCircle(
// Offset(size.width / 2, size.height / 2), _radius, _paint);
//画的是圆线的
Paint line = Paint()
..color = _color
..strokeCap = StrokeCap.round
..style = PaintingStyle.stroke
..strokeWidth = 2;
//画圆方法
canvas.drawCircle(Offset(size.width / 2, size.height / 2), _radius, line);
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
- 最后说说平移和放大或的动画,这个主要用到的是
LayoutBuilder
和补间动画RelativeRectTween
,还有PositionedTransition
自带的组件,这三个配合着使用,
- 平移动画首先要给一个开始的位置,还有一个结束的位置.
- 放大的动画,同理,要一个开始的大小和结束的大小.
- 在用补间动画把两个位置和大小结合起来.
- 传入一个动画控制器: rectAnimation.
LayoutBuilder(
builder: (context, constraints) {
final Size biggest = constraints.biggest;
/// 需要平移的Widget 宽高
childWidth = SAdapt.width(224.0);
/// 平移后Widget
targetChildWidth = SAdapt.width(50);
/// 根据自身大小,以及父布局大小获取相对位置
var beginRect = RelativeRect.fromSize(
Rect.fromLTWH(
(SAdapt.getScreenWidth() - childWidth) / 2,
(SAdapt.getScreenHeight() - childWidth) / 2 -
SAdapt.width(10) -
SAdapt.width(90),
childWidth,
childWidth),
biggest,
);
//结束时候的位置和大小,
var endRect = RelativeRect.fromSize(
Rect.fromLTWH(
SAdapt.width(20),
SAdapt.getTopBarHeight() + SAdapt.width(10),
targetChildWidth,
targetChildWidth,
),
biggest,
);
/// 补间动画
final rectAnimation =
RelativeRectTween(begin: beginRect, end: endRect)
.animate(_positionController);
return Stack(
children: [
PositionedTransition(
rect: rectAnimation,
child: Container(),
),
],
);
},
),
如果只需要平移,不需要改大小,把起始的大小设置成一样就可以了.如果只改大小,好像有个更简单的办法,后续会写!
如果有需要跟我一样效果的小伙伴,可以私聊或者留言,我会尽快回复!
今天就到这里了,如果帮助到了你,就请你给我点个赞哦!