import 'package:flutter/material.dart';

class FadeRoute extends PageRouteBuilder {
  final Widget page;

  FadeRoute(this.page)
    : super(
    pageBuilder: (
      context,
      animation,
      secondaryAnimation,
      ) {
      return page;
    },
    transitionsBuilder: (
      context,
      animation,
      secondaryAnimation,
      child,
      ) {
      return FadeTransition(
        opacity: animation,
        child: child,
      );
    },
  );
}

class EnterExitRoute extends PageRouteBuilder {
  final Widget enterPage;
  final Widget exitPage;

  EnterExitRoute(this.enterPage, this.exitPage, bool rightDir)
    : super(
    pageBuilder: (
      context,
      animation,
      secondaryAnimation,
      ) {
      return exitPage;
    },
    transitionsBuilder: (
      context,
      animation,
      secondaryAnimation,
      child,
      ) =>
      Stack(
        children: [
          SlideTransition(
            position: rightDir ? Tween<Offset>(
              begin: Offset(0.0, 0.0),
              end: Offset(-1.0, 0.0),
            ).animate(
              CurvedAnimation(parent: animation, curve: Curves.easeIn),
            ) : Tween<Offset>(
              begin: Offset(0.0, 0.0),
              end: Offset(1.0, 0.0),
            ).animate(
              CurvedAnimation(parent: animation, curve: Curves.easeIn),
            ),
            child: enterPage,
          ),
          SlideTransition(
            position: rightDir ? Tween<Offset>(
              begin: Offset(1.0, 0.0),
              end: Offset.zero,
            ).animate(
              CurvedAnimation(parent: animation, curve: Curves.easeInOut),
            ) : Tween<Offset>(
              begin: Offset(-1.0, 0.0),
              end: Offset.zero,
            ).animate(
              CurvedAnimation(parent: animation, curve: Curves.easeInOut),
            ),
            child: exitPage,
          )
        ],
      ),
  );
}

class DownUpRoute extends PageRouteBuilder {
  final Widget enterPage;
  final Widget exitPage;

  DownUpRoute(this.enterPage, this.exitPage, bool rightDir)
      : super(
    pageBuilder: (
        context,
        animation,
        secondaryAnimation,
        ) {
      return exitPage;
    },
    transitionsBuilder: (
        context,
        animation,
        secondaryAnimation,
        child,
        ) =>
        Stack(
          children: [
            SlideTransition(
              position: rightDir ? Tween<Offset>(
                begin: Offset(0.0, 0.0),
                end: Offset(0.0, -1.0),
              ).animate(
                CurvedAnimation(parent: animation, curve: Curves.easeIn),
              ) : Tween<Offset>(
                begin: Offset(0.0, 0.0),
                end: Offset(0.0, 1.0),
              ).animate(
                CurvedAnimation(parent: animation, curve: Curves.easeIn),
              ),
              child: enterPage,
            ),
            SlideTransition(
              position: rightDir ? Tween<Offset>(
                begin: Offset(0.0, 1.0),
                end: Offset.zero,
              ).animate(
                CurvedAnimation(parent: animation, curve: Curves.easeInOut),
              ) : Tween<Offset>(
                begin: Offset(0.0, -1.0),
                end: Offset.zero,
              ).animate(
                CurvedAnimation(parent: animation, curve: Curves.easeInOut),
              ),
              child: exitPage,
            )
          ],
        ),
  );
}