JackJonson / flutter_styled_toast

A Styled Toast Flutter package.
Apache License 2.0
76 stars 43 forks source link

It is impossible to write independent reverse animation builder. #17

Open darkstarx opened 3 years ago

darkstarx commented 3 years ago

Now you apply both animation builders (forward and reverse) to show a toast and only reverse animation builder to dismiss a toast. What if I want to make on independent transition to show a toast and another independent transition to hide a toast?

I wonder why did you decide to mix animationBuilder and reverseAnimationBuilder for showing? And why don't you mix them on dismiss? It is very unusual behavior. And it is very uncomfortable to live with such behavior.

Here is my example. I want to animate scale and borderRadius of ClipRRect on showing, and fade out on dismissing. I have to use ClipRRect outside the toast widget and inside of animationBuilder because I use BackdropFilter which requires some clipping in a parent widget.

    toasts.showToast(text,
      context: context,
      animationBuilder: (context, controller, duration, child) {
        final scale = Tween<double>(begin: 1.3, end: 1.0).animate(
          CurvedAnimation(
            parent: controller,
            curve: Curves.easeInSine,
            reverseCurve: Curves.easeOutSine
          ),
        );
        final sigma = Tween<double>(begin: 0.0, end: 8.0).animate(
          CurvedAnimation(
            parent: controller,
            curve: Curves.easeInSine,
            reverseCurve: Curves.easeOutSine
          ),
        );
        final opacity = Tween<double>(begin: 0.0, end: 1.0).animate(
          CurvedAnimation(
            parent: controller,
            curve: Curves.easeInSine,
            reverseCurve: Curves.easeOutSine
          ),
        );
        return ScaleTransition(
          scale: scale,
          child: ClipRRect(
            borderRadius: borderRadius,
            child: BlurTransition(
              sigma: sigma,
              child: FadeTransition(
                opacity: opacity,
                child: child,
              ),
            )
          )
        );
      },
      reverseAnimBuilder: (context, controller, duration, child) {
        final sigma = Tween<double>(begin: 8.0, end: 0.0).animate(
          CurvedAnimation(
            parent: controller,
            curve: Curves.easeOutSine,
            reverseCurve: Curves.easeInSine
          ),
        );
        final opacity = Tween<double>(begin: 1.0, end: 0.0).animate(
          CurvedAnimation(
            parent: controller,
            curve: Curves.easeOutSine,
            reverseCurve: Curves.easeInSine
          ),
        );
        return ClipRRect(
          borderRadius: borderRadius,
          child: BlurTransition(
            sigma: sigma,
            child: FadeTransition(
              opacity: opacity,
              child: child,
            ),
          ),
        );
      },
      animDuration: animDuration,
      duration: totalDuration,
    );

So, while a toast is showing up, it contains inside of FadeTransition -> BlurTransition -> ClipRRect (scaled border radius) -> ScaleTransition -> FadeTransition -> BlurTransition -> ClipRRect (normal border radius crops the scaled!!!)

Well, why don't you simply apply the only forward animationBuilder on showing and the only reverseAnimationBuilder (if exists) on dismissing? It would be a rather better idea, you simply would have to add some flag, say _dismissing, in the StyledToastWidgetState and check this flag in the build method while deciding in which animation builder to put the widget - in animationBuilder or in reverseAnimationBuilder and that's all. Why did you choose so strange approach with mixing animations?