logo
cd ..

Implementing Flutter Nike Animation

Comments
2 min

Implementing Flutter Nike Animation

Animations can significantly enhance the user experience by providing visual feedback and creating a more interactive interface. Flutter, with its robust animation framework, makes it easy to create smooth and engaging animations. In this post, I'll walk you through the steps to implement this UI animation in Flutter.

Animation Gif

Animations are an essential part of modern app development, bringing life and interactivity to user interfaces. In this blog post, we'll explore a fascinating example of an animation created with Flutter: the Nike Slider. This animation demonstrates how to use Flutter's powerful animation capabilities to create a smooth, engaging, and interactive user experience.

Understanding the Basics

The Nike Slider is a Flutter widget that animates between three different "slides," each representing a different color and image associated with the Nike brand. It uses an AnimationController to handle the animation and several Tween objects to define the animation's behavior.

Setting Up the Animation

First, let's look at the initialization process. The AnimationController is set up in the initState method of the _HomeScreenState class. This controller manages the duration and the state of the animation.

main.dart

  int activeIndex = 5;
  final duration = const Duration(milliseconds: 400);
  AnimationController? _controller;
  Animation<double>? _widthAnimation;
  Animation<double>? _textTranslationAnimation;
  Animation<double>? _widthReduceAnimation;
  Animation<double>? _rotationAnimation;
  bool hasReversed = false;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this, duration: duration);
    Timer(Duration(seconds: 2), () {
      setAnimatedValues(5, context);
    });
  }

Defining the Animation Values

The setAnimatedValues method sets up the various animations that will be used. These include animations for the width, text translation, width reduction, and rotation.

main.dart


  curve(ctrl) => CurvedAnimation(parent: ctrl, curve: Curves.linear);

  setAnimatedValues(int index, BuildContext? context) {
    if (context != null) {
      _widthAnimation = Tween<double>(
        begin: Sizing.width(context) / 3,
        end: Sizing.width(context),
      ).animate(curve(_controller!));

      _textTranslationAnimation = Tween<double>(
        begin: 1.8,
        end: 2.5,
      ).animate(curve(_controller!));

      _widthReduceAnimation = Tween<double>(
        begin: Sizing.width(context) / 3,
        end: 0,
      ).animate(curve(_controller!));

      _rotationAnimation = Tween<double>(
        begin: -0.7,
        end: -0.1,
      ).animate(curve(_controller!));
    }
  }

Building the Widget Tree

The main widget tree for the Nike Slider is built in the build method. It consists of three primary components: the sliding containers, a follow button, and a navigation bar.

main.dart

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          Positioned(
            top: 0,
            left: 0,
            right: 0,
            child: Row(
              children: [
                ...[0, 1, 2].map(
                  (index) {
                    return AnimatedBuilder(
                      animation: _controller!,
                      builder: (context, _) {
                        return nikeSlide(context, index);
                      },
                    );
                  },
                ).toList()
              ],
            ),
          ),
          Positioned(
            bottom: 20,
            left: 0,
            right: 0,
            child: Follow(activeIndex: activeIndex),
          ),
          Positioned(
            top: 0,
            left: 0,
            right: 0,
            child: NavBar(),
          ),
        ],
      ),
    );
  }

Creating the Sliding Containers

Each sliding container is created using the nikeSlide method, which builds a container with the appropriate color, size, and content based on the current animation values.

main.dart

Container nikeSlide(BuildContext context, int index) {
  // Animated width
  final a_w = _widthAnimation?.value??Sizing.width(context)/3;
  // Reduced animated width
  final r_w = _widthReduceAnimation?.value??Sizing.width(context)/3;
    return Container(
      clipBehavior: Clip.hardEdge,
      decoration: BoxDecoration(
        color: index == 0
            ? AppColors.blue
            : index == 1
                ? AppColors.red
                : AppColors.yellow,
      ),
      width: index == activeIndex ? a_w:  r_w,
      height: Sizing.height(context),
      child: Stack(
        clipBehavior: Clip.hardEdge,
        children: [
          Positioned(
            top: 0,
            bottom: 0,
            left: 0,
            right: 0,
            child: Center(
              child: Transform.scale(
                scale: _textTranslationAnimation?.value ?? 1.8,
                child: Text(
                  overflow: TextOverflow.ellipsis,
                  index == 0
                      ? "BLUE"
                      : index == 1
                          ? "RED"
                          : "YELLOW",
                  style: GoogleFonts.montserrat(
                    fontSize: 100,
                    fontWeight: FontWeight.w800,
                    color: AppColors.white,
                    fontStyle: FontStyle.italic,
                  ),
                ),
              ),
            ),
          ),
          Positioned(
            top: 0,
            bottom: 0,
            left: 0,
            right: 0,
            child: InkWell(
              onTap: () => _toggleAnimation(index),
              child: Transform.rotate(
                angle: _rotationAnimation?.value ?? -0.7,
                child: Image.asset("assets/images/nike_${index}.png"),
              ),
            ),
          ),
        ],
      ),
    );
  }

Toggling the Animation

The _toggleAnimation method handles the animation state when a container is tapped. It toggles between the forward and reverse states of the animation, providing a smooth transition effect.

main.dart

void _toggleAnimation(int index) async {
    if (index == activeIndex) {
      if (hasReversed) {
        _controller?.forward();
        setState(() => hasReversed = !hasReversed);
      } else {
        _controller?.reverse();
        setState(() => hasReversed = !hasReversed);
      }
    } else {
      _controller?.forward();
    }
    setState(() => activeIndex = index);
  }

Complete Code

You can find the complete source code of this tutorial on here! . If you enjoy it, please leave a star on the repo and comment below!

Conclusion

The Nike Slider example showcases the power and flexibility of Flutter's animation framework. By combining various animations and leveraging Flutter's widget tree, you can create highly interactive and visually appealing user interfaces. Whether you're building a simple app or a complex user experience, mastering Flutter animations will undoubtedly enhance the quality and engagement of your applications.

Comments

Support

Do you feel like supporting my work? 🙂Buymeacoffee button