Search code examples
flutterflutter-animation

Flutter Create animation like headspace app


Wanted to achieve the animation like Headspace app in flutter. enter image description here


Solution

  • Result

    enter image description here

    Code

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: Center(
              child: HeadspaceWidget(),
            ),
          ),
        );
      }
    }
    
    class HeadspaceWidget extends StatefulWidget {
      @override
      _HeadspaceWidgetState createState() => _HeadspaceWidgetState();
    }
    
    class _HeadspaceWidgetState extends State<HeadspaceWidget>
        with SingleTickerProviderStateMixin {
      late AnimationController _controller;
      late Animation<double> _circleSizeAnimation;
      late Animation<double> _circleMovementAnimation;
      late Animation<double> _textMovementAnimation;
      late Animation<double> _textOpacityAnimation;
    
      @override
      void initState() {
        super.initState();
        _controller = AnimationController(
          duration: const Duration(seconds: 1),
          vsync: this,
        );
    
        _circleSizeAnimation = Tween<double>(begin: 200.0, end: 50.0).animate(
          CurvedAnimation(
            parent: _controller,
            curve: Interval(
              0.0,
              0.5, // Halfway through the animation
              curve: Curves.easeOut,
            ),
          ),
        );
    
        _circleMovementAnimation = Tween<double>(begin: 0.0, end: -20.0).animate(
          CurvedAnimation(
            parent: _controller,
            curve: Interval(
              0.5,
              1.0,
              curve: Curves.easeInOut,
            ),
          ),
        );
    
        _textMovementAnimation = Tween<double>(begin: 15, end: 20.0).animate(
          CurvedAnimation(
            parent: _controller,
            curve: Interval(
              0.5,
              1.0,
              curve: Curves.easeInOut,
            ),
          ),
        );
    
        _textOpacityAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
          CurvedAnimation(
            parent: _controller,
            curve: Interval(
              0.5, // Start fading in the text after the circle finishes shrinking
              1.0,
              curve: Curves.easeIn,
            ),
          ),
        );
      }
    
      @override
      void dispose() {
        _controller.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return AnimatedBuilder(
          animation: _controller,
          builder: (context, child) {
            return Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Row(
                  children: [
                    ElevatedButton(
                      onPressed: () {
                        _controller.forward();
                      },
                      child: Text('Start Animation'),
                    ),
                    ElevatedButton(
                      onPressed: () {
                        _controller.reverse();
                      },
                      child: Text('Reverse Animation'),
                    ),
                  ],
                ),
                SizedBox(height: 20),
                Row(
                  mainAxisSize: MainAxisSize.min,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Center(
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        mainAxisSize: MainAxisSize.min,
                        children: <Widget>[
                          Transform.translate(
                            offset: Offset(_circleMovementAnimation.value + 20, 0),
                            child: Container(
                              width: _circleSizeAnimation.value,
                              height: _circleSizeAnimation.value,
                              decoration: BoxDecoration(
                                color: Colors.orange,
                                shape: BoxShape.circle,
                              ),
                            ),
                          ),
                          Transform.translate(
                            offset: Offset(_textMovementAnimation.value, 0),
                            child: AnimatedOpacity(
                              opacity: _textOpacityAnimation.value,
                              duration: Duration
                                  .zero,
                              child: Text(
                                'headspace',
                                style: TextStyle(
                                  fontSize: 24,
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ],
            );
          },
        );
      }
    }