flutter how can I create circle animation like this?

I'd like to implement circle animation for profile picture like instagram story something like this.
How can I achieve this?

1 answer

  • answered 2018-11-08 13:28 Niklas

    You can try using the dashed_circle package to create instagram story like circle (look at the image below). To create a simple spinning version you can add two rotation using the Transform.rotate constructor.

    The first rotation has to be the parent widget of the dashed circle. The second rotation should surround the child widget of the dashed circle with the opposite angle of the first rotation.

    To create the effect of the dashes slowling merging to a single line, you can slowly decrease the gap property of the dashed_circle.

    I gave it a go and tried myself at a quick demo, to show you an example implementation:

    Bill Gates Story

    import 'package:flutter/material.dart';
    import 'package:dashed_circle/dashed_circle.dart';
    
    void main() => runApp(new MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Flutter Demo',
          theme: new ThemeData(),
          home: Scaffold(
            body: Center(
              child: RotateAnimationDemo(),
            ),
          ),
        );
      }
    }
    
    class RotateAnimationDemo extends StatefulWidget {
      @override
      State<StatefulWidget> createState() => RotateAnimationDemoState();
    }
    
    class RotateAnimationDemoState extends State<RotateAnimationDemo>
        with SingleTickerProviderStateMixin {
      AnimationController controller;
    
      Animation base;
      Animation inverted;
      Animation gap;
    
      @override
      void initState() {
        super.initState();
    
        controller =
            AnimationController(vsync: this, duration: Duration(seconds: 3));
    
        base = CurvedAnimation(parent: controller, curve: Curves.easeOut);
    
        inverted = Tween<double>(begin: 0.0, end: -1.0).animate(base);
    
        gap = Tween<double>(begin: 3.0, end: 0.0).animate(base)
          ..addListener(() {
            setState(() {});
          });
      }
    
      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: () => controller.forward(),
          child: RotationTransition(
            turns: base,
            child: DashedCircle(
              gapSize: gap.value,
              dashes: 20,
              color: Colors.deepOrange,
              child: RotationTransition(
                turns: inverted,
                child: Padding(
                  padding: const EdgeInsets.all(7.0),
                  child: CircleAvatar(
                    radius: 60.0,
                    backgroundImage: NetworkImage(
                        'https://upload.wikimedia.org/wikipedia/commons/thumb/7/71/Bill_Gates_Buys_Skype_%285707954468%29.jpg/2560px-Bill_Gates_Buys_Skype_%285707954468%29.jpg'),
                  ),
                ),
              ),
            ),
          ),
        );
      }
    }