skip to Main Content

I am trying to implement the animation in the video link below:

Animation Video

The Icon that is being animated is a single SVG file with three arrows. The arrows are not separate images or icon assets.

So, What I tried to accomplish that is, I used flutter_svg and flutter_animate packages.

First of all, I added the SVG file and gave it the greenish color, and then added shimmer effect (did not get the expected outcome). Here is the code snippet.

SvgPicture.asset(
            'assets/icons/down_arrows.svg',
            height: 32.h,
            width: 32.h,
            colorFilter: const ColorFilter.mode(
              AppColors.bottomNavIconGreen,
              BlendMode.srcIn,
            ),
          )
              .animate(
                  onPlay: (controller) => controller.repeat(period: 3000.ms))
              .shimmer(
                color: AppColors.mainGreen,
                angle: 1.5,
              ),

Kindly help me achieve the animation like the video with this approach or any other way. Thank you all in advance.

2

Answers


  1. Kindly review this video. I believe it will be beneficial.

    Login or Signup to reply.
  2. This kind of animation can be done in flutter but this needs few different components to work. I can think of an approach to draw canvas with arrows & animate the canvas.

    1. You need Animation tween to do this with loop.

    late Animation<double> animation;
    late AnimationController controller;
    Tween<double> _rotationTween = Tween(begin: 0, end: 2);
    
    @override
    void initState() {
      super.initState();
    
      controller = AnimationController(
        vsync: this,
        duration: Duration(milliseconds: 1000),
      );
    
      animation = _rotationTween.animate(controller)
        ..addListener(() {
          setState(() {});
        })
        ..addStatusListener((status) {
          if (status == AnimationStatus.completed) {
            controller.repeat();
          } else if (status == AnimationStatus.dismissed) {
            controller.forward();
          }
        });
    
      controller.forward();
    }
    

    2. Then we need own canvas to draw arrows. Then you need to pass

    class ArrowPainter extends CustomPainter {
    ArrowPainter();
    @override
    void paint(Canvas canvas, Size size) {
      final paint = Paint()
        ..color = Colors.grey[300]!
        ..style = PaintingStyle.stroke
        ..strokeWidth = 3;
    
      var halfWidth = size.width/2;
      var halfHeight = size.height/2;
    
      var path = Path();
      path.moveTo(halfWidth - 5, halfHeight-12);
      path.lineTo(halfWidth, halfHeight-7);
      path.lineTo(halfWidth + 5, halfHeight - 12);
      canvas.drawPath(path,paint);
    
      path = Path();
      path.moveTo(halfWidth - 7, halfHeight-7);
      path.lineTo(halfWidth, halfHeight);
      path.lineTo(halfWidth + 7, halfHeight - 7);
      canvas.drawPath(path,paint);
    
      path = Path();
      path.moveTo(halfWidth - 9, halfHeight - 2);
      path.lineTo(halfWidth, halfHeight+7);
      path.lineTo(halfWidth + 9, halfHeight - 2 );
      canvas.drawPath(path,paint);
    
    }
    
    @override
    bool shouldRepaint(ArrowPainter oldDelegate) => false;
    

    }

    3. Now we need to add the custom paint to draw this canvas

     @override
    Widget build(BuildContext context) {
      return CustomPaint(
        size: Size(40, 40),
        painter: ArrowPainter(),
      );
    }
    

    This will give you something like this

    canvas arrows

    4. Now we add the value param in our custom painter

    class ArrowPainter extends CustomPainter {
      final int value;
      ArrowPainter({required this.value});
    

    and use this value to change arrow colors

    var path = Path();
    path.moveTo(halfWidth - 5, halfHeight-12);
    path.lineTo(halfWidth, halfHeight-7);
    path.lineTo(halfWidth + 5, halfHeight - 12);
    canvas.drawPath(path,paint..color = (value< 33 ? Colors.green : Colors.green.shade100));
    
    path = Path();
    path.moveTo(halfWidth - 7, halfHeight-7);
    path.lineTo(halfWidth, halfHeight);
    path.lineTo(halfWidth + 7, halfHeight - 7);
    canvas.drawPath(path,paint..color = (value> 33 && value<66 ? Colors.green : Colors.green.shade100));
    
    path = Path();
    path.moveTo(halfWidth - 9, halfHeight - 2);
    path.lineTo(halfWidth, halfHeight+7);
    path.lineTo(halfWidth + 9, halfHeight - 2 );
    canvas.drawPath(path,paint..color = (value> 66 ? Colors.green : Colors.green.shade100));
    

    and setup out shouldRepaint to reload when value changed

    @override
    bool shouldRepaint(ArrowPainter oldDelegate) => oldDelegate.value != value;
    

    5. One last this is passing our animation value to our painter

    return CustomPaint(
      size: Size(40, 40),
      painter: ArrowPainter(value: (controller.value * 100).toInt()),
    );
    

    6. Lastly don’t forgot to dispose the controller on stateful widget

    @override
    void dispose() {
      controller.dispose();
      super.dispose();
    }
    

    Now running the app will give you animated arrows just like your video. Example images:

    animation 1
    animation 2
    animation 3

    Runnig dartpad example

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search