Search code examples
flutter-layoutflutter-animationflutter-widgetflutter-packagesflutter-showmodalbottomsheet

How to make flutter animation play full-screen when modal bottom sheet has been raised?


I am trying to add a confetti animation to modal bottom sheet using confetti package when it is raised. But it is not working as intended - animation is being cut in the middle of the screen. It works as intended when I call the animation from button press. Desired result is like on button press, but should be when modal bottom sheet is raised.

I have tried wrapping ConfettiWidget inside Expanded, Positioned.fill, also Flexible, but these don't work.

EDIT: Did some testing and it seems that the problem is present only on iOS devices. Also, it probably is worth mentioning that the animation is way slower on Android device (both physical and virtual) than it is on an iPhone.

See gifs below:

On Build:

On button press:

(How it should look on the build)

On button press

Code:

@override
  void initState() {
    confController = ConfettiController(duration: Duration(seconds: 5));

    WidgetsBinding.instance!.addPostFrameCallback((_) {
      confController.play();
    });

    super.initState();
  }

  @override
  void dispose() {
    confController.dispose();
    super.dispose();
  }


Widget build(BuildContext context) {
      return Container(
        color: Colors.black,
        child: Stack(
          children: [
            Align(
              alignment: Alignment.topCenter,
              child: ConfettiWidget(
                confettiController: confController,
                blastDirectionality: BlastDirectionality.explosive,
                particleDrag: 0.05,
                emissionFrequency: 0.1,
                gravity: 0.3,
                colors: [
                  Colors.red,
                ], // manually specify the colors to be used
              ),
            ),
            Container(
              width: 500,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  RawMaterialButton(
                    onPressed: () {
                      confController.play();
                    },
                    fillColor: Colors.white,
                  )
                ],
              ),
            )
          ],
        ),
    );
  }

Solution

  • Needed to set the ConfettiWidget parameter canvas to MediaQuery.of(context).size * 2. Works as intended now (tested on both smaller and bigger devices (biggest was iPad 12.9-inch)). Code looks like this now:

    ConfettiWidget(
          confettiController: confController,
          blastDirectionality: BlastDirectionality.explosive,
          particleDrag: 0.05,
          emissionFrequency: 0.1,
          gravity: 0.3,
          canvas: MediaQuery.of(context).size * 2,
          colors: [
            Colors.red,
          ],
    )