buildBidirectionalTransition method

Widget buildBidirectionalTransition(
  1. Widget childScreen
)

Builds a bidirectional parent-child transition.

If transitionWidget isn't null the transition will start from 0.0 on the timeline with the transitionWidget. As the animation plays the transitionWidget is scaled up before it fades into the childScreen that ends up at full-size.

Implementation

Widget buildBidirectionalTransition(Widget childScreen) {
  // Controls the opacity of the [childScreen] in a transition where there is
  // no transition widget.
  final fadeInAnimation = CurvedAnimation(
    parent: animation,
    curve: Interval(
      0.5,
      1.0,
      curve: Curves.fastOutSlowIn,
    ),
  );

  // The animation that controls the scale of the parent widget.
  final Animation<double> scaleParentAnimation = Tween<double>(
    begin: 1.0,
    end: MediaQuery.of(transitionContext).size.width / renderBoxSize!.width,
  ).animate(positionAnimationCurve);

  // The animation that controls the scale of the child screen.
  final Animation<double> scaleChildAnimation = Tween<double>(
    begin: renderBoxSize!.width / MediaQuery.of(transitionContext).size.width,
    end: 1.0,
  ).animate(positionAnimationCurve);

  // If transitionWidget is null the parent widget will be an empty
  // [Container], otherwise the parent widget will be scaled up controlled by
  // [scaleParentAnimation].
  final parentWidget = transitionWidget != null
      ? ScaleTransition(
          alignment: Alignment.center,
          scale: scaleParentAnimation,
          child: transitionWidget,
        )
      : Container();

  // This transition is used in case there is no transition widget.
  if (transitionWidget == null)
    return FadeTransition(
      opacity: fadeInAnimation,
      child: ScaleTransition(
        alignment: Alignment.topCenter,
        scale: settings.scaleChild
            ? scaleChildAnimation
            : ConstantTween(1.0).animate(positionAnimationCurve),
        child: childScreen,
      ),
    );

  return FadeTransition(
    opacity: PageTransitionOpacityTween(
      begin: 0.0,
      end: 1.0,
    ).animate(positionAnimationCurve),
    child: PageTransitionChildTween(
      begin: parentWidget,
      end: ScaleTransition(
        alignment: Alignment.topCenter,

        // Scale the child screen if [settings.scaleChild] is true.
        scale: settings.scaleChild
            ? scaleChildAnimation
            : ConstantTween<double>(1.0).animate(animation),
        child: childScreen,
      ),
    ).animate(positionAnimationCurve).value,
  );
}