flutter 动画系列 旋转动画,波浪动画,向外扩散的圆动画,

2022-09-27  本文已影响0人  司徒新新
动画效果.gif

3个动画,组合成这样的,一个一个来.

  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;
  }
}

  1. 平移动画首先要给一个开始的位置,还有一个结束的位置.
  2. 放大的动画,同理,要一个开始的大小和结束的大小.
  3. 在用补间动画把两个位置和大小结合起来.
  4. 传入一个动画控制器: 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(),
              ),
            ],
          );
        },
      ),
   

如果只需要平移,不需要改大小,把起始的大小设置成一样就可以了.如果只改大小,好像有个更简单的办法,后续会写!

如果有需要跟我一样效果的小伙伴,可以私聊或者留言,我会尽快回复!

今天就到这里了,如果帮助到了你,就请你给我点个赞哦!

上一篇 下一篇

猜你喜欢

热点阅读