Fluent uses custom fluro routing transition animation to realize personalized page switching

fluro transition animation source code

Before using custom transition animation, first pick the source code of fluro. Through the source code, you can find such a standard transition method:

RouteTransitionsBuilder _standardTransitionsBuilder(
      TransitionType? transitionType) {
    return (BuildContext context, Animation<double> animation,
        Animation<double> secondaryAnimation, Widget child) {
      if (transitionType == TransitionType.fadeIn) {
        return FadeTransition(opacity: animation, child: child);
      } else {
        const Offset topLeft = const Offset(0.0, 0.0);
        const Offset topRight = const Offset(1.0, 0.0);
        const Offset bottomLeft = const Offset(0.0, 1.0);

        Offset startOffset = bottomLeft;
        Offset endOffset = topLeft;
        if (transitionType == TransitionType.inFromLeft) {
          startOffset = const Offset(-1.0, 0.0);
          endOffset = topLeft;
        } else if (transitionType == TransitionType.inFromRight) {
          startOffset = topRight;
          endOffset = topLeft;
        } else if (transitionType == TransitionType.inFromBottom) {
          startOffset = bottomLeft;
          endOffset = topLeft;
        } else if (transitionType == TransitionType.inFromTop) {
          startOffset = Offset(0.0, -1.0);
          endOffset = topLeft;
        }

        return SlideTransition(
          position: Tween<Offset>(
            begin: startOffset,
            end: endOffset,
          ).animate(animation),
          child: child,
        );
      }
    };
  }

It can be seen from the source code that different animations are returned according to different enumerations (i.e. transitionBuilder). TransitionType.fadeIn uses the FadeTransition provided by fluent to complete the animation by changing the transparency. The other left slide in, right slide in, slide in and up slide in slide in from the initial offset position to the end position, using SlideTransition. In addition to FadeTransition and SlideTransition mentioned above, Flutter also has the following common transition forms:

  • RotationTransition: rotation transition
  • ScaleTransition: scale transition

Since this is the case, we can follow the rules and make a custom transition with other transition effects of the system.

Rotate transition animation

Let's take a look at the rotation transition. The construction method of RotationTransition is defined as follows:

const RotationTransition({
    Key? key,
    required Animation<double> turns,
    this.alignment = Alignment.center,
    this.child,
  })  : assert(turns != null),
        super(key: key, listenable: turns);

Where turns is the animation control, indicating the number of radians of rotation, which is equal to the animation control value multiplied by 2 π. alignment indicates the center position of the rotation. It is centered by default. The arc of rotation should not be too large, otherwise the animation is too fast, resulting in poor appearance. After verification, the recommended starting value is between 0.2 and 0.3, and the end value is 0, indicating that it returns to the normal position. If the starting value is negative, it is clockwise; If regular is counterclockwise, the example code is as follows:

//Rotate counterclockwise around the center
RouterManager.router.navigateTo(
  context,
  RouterManager.transitionPath,
  transition: TransitionType.custom,
  transitionBuilder:
      (context, animation, secondaryAnimation, child) {
    return RotationTransition(
      turns: Tween<double>(
        begin: 0.25,
        end: 0.0,
      ).animate(animation),
      child: child,
    );
  },
);

//...
//Rotate clockwise around the lower left corner
RouterManager.router.navigateTo(
  context,
  RouterManager.transitionPath,
  transition: TransitionType.custom,
  transitionBuilder:
      (context, animation, secondaryAnimation, child) {
    return RotationTransition(
      alignment: Alignment.bottomLeft,
      turns: Tween<double>(
        begin: -0.25,
        end: 0.0,
      ).animate(animation),
      child: child,
    );
  },
);

Tween is the linear interpolation method of the system.

Scale transition animation

Scaling and transition are common in picture preview, usually from a smaller scale to a 1:1 scale. The use method is similar to that of rotary transition. The example code is as follows:

RouterManager.router.navigateTo(
  context,
  RouterManager.transitionPath,
  transition: TransitionType.custom,
  transitionBuilder:
      (context, animation, secondaryAnimation, child) {
    return ScaleTransition(
      scale: Tween<double>(
        begin: 0.5,
        end: 1.0,
      ).animate(animation),
      child: child,
    );
  },
);

Custom transition animation

By reading the source code, we can actually find that RotationTransition and ScaleTransition are inherited from AnimatedWidget. Therefore, we can write a custom Transition to inherit from AnimatedWidget and return a Transform object in the build method. In this way, you can make custom Transition animation effects. Taking deformation as an example, we can use Matrix4's skew method to deform on the x and y axes, and we can get the effect of Transition similar to card deformation. You can also deform only in the x or y axis (skewX and skewY methods). Here, a Transition animation is defined by simultaneous deformation of x and y axes:

class SkewTransition extends AnimatedWidget {
  const SkewTransition({
    Key key,
    Animation<double> turns,
    this.alignment = Alignment.center,
    this.child,
  })  : assert(turns != null),
        super(key: key, listenable: turns);

  Animation<double> get turns => listenable as Animation<double>;

  final Alignment alignment;

  final Widget child;

  @override
  Widget build(BuildContext context) {
    final double turnsValue = turns.value;
    final Matrix4 transform =
        Matrix4.skew(turnsValue * pi * 2.0, turnsValue * pi * 2.0);
    return Transform(
      transform: transform,
      alignment: alignment,
      child: child,
    );
  }
}

The usage is similar to RotationTransition:

RouterManager.router.navigateTo(
  context,
  RouterManager.transitionPath,
  transition: TransitionType.custom,
  transitionBuilder:
      (context, animation, secondaryAnimation, child) {
    return SkewTransition(
      turns: Tween<double>(
        begin: -0.05,
        end: 0.0,
      ).animate(animation),
      child: child,
    );
  },
);

In practice, you can also try to use rotation around the X axis, rotation around the Y axis, and changing the alignment of the center point to achieve different animation transition effects. If you need more complex animation effects, you can study the implementation of animation, and the corresponding animation will be introduced in subsequent chapters.

Operation effect

The operation effect is shown in the figure below:

summary

This article introduces the implementation of user-defined transition animation for fluro navigation to other pages. Flutter itself provides many predefined transition animations. You can design a variety of transition animations through the transition builder parameters, or realize personalized transition animation effects through the user-defined AnimatedWidget.

Tags: iOS Android Design Pattern Flutter

Posted on Tue, 30 Nov 2021 15:30:53 -0500 by soulmasta