confetti animation

This commit is contained in:
2026-03-03 12:15:50 +01:00
parent 77fa21b572
commit 88275c4ae6
16 changed files with 401 additions and 298 deletions

View File

@@ -15,3 +15,4 @@ export 'src/containers/section_container.dart';
export 'src/containers/footer_container.dart';
export 'src/rows/editable_row.dart';
export 'src/loading/app_loading_indicator.dart';
export 'src/confetti/confetti_overlay.dart';

View File

@@ -0,0 +1,91 @@
import 'dart:math';
import 'package:confetti/confetti.dart';
import 'package:flutter/material.dart';
class ConfettiOverlay extends StatefulWidget {
final bool play;
final Widget child;
final VoidCallback? onPlayed;
final Duration duration;
final List<Color> colors;
const ConfettiOverlay({
super.key,
required this.play,
required this.child,
this.onPlayed,
this.duration = const Duration(seconds: 3),
this.colors = const [
Color(0xFFFF69B4),
Color(0xFF4169E1),
Color(0xFFFF8C00),
Color(0xFF8A2BE2),
Color(0xFFFFD700),
],
});
@override
State<ConfettiOverlay> createState() => _ConfettiOverlayState();
}
class _ConfettiOverlayState extends State<ConfettiOverlay> {
late final ConfettiController _controller;
@override
void initState() {
super.initState();
_controller = ConfettiController(duration: widget.duration);
if (widget.play) {
WidgetsBinding.instance.addPostFrameCallback((_) {
_controller.play();
widget.onPlayed?.call();
});
}
}
@override
void didUpdateWidget(covariant ConfettiOverlay oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.play && !oldWidget.play) {
_controller.play();
if (widget.onPlayed != null) {
WidgetsBinding.instance.addPostFrameCallback((_) {
widget.onPlayed!();
});
}
}
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
widget.child,
Align(
alignment: Alignment.topCenter,
child: ConfettiWidget(
confettiController: _controller,
blastDirectionality: BlastDirectionality.explosive,
gravity: 0.1,
numberOfParticles: 10,
emissionFrequency: 0.2,
colors: widget.colors,
createParticlePath: (size) {
final random = Random();
final w = 10.0 + random.nextDouble() * 5.0;
final h = 5.0 + random.nextDouble() * 2.5;
return Path()..addRect(Rect.fromLTWH(0, 0, w, h));
},
),
),
],
);
}
}

View File

@@ -21,6 +21,7 @@ dependencies:
path: ../../packages/fonts
top_snackbar_flutter: ^3.3.0
lottie: ^3.3.1
confetti: ^0.7.0
dev_dependencies:
flutter_test:

View File

@@ -7,6 +7,6 @@
<versions>
<version>2.6.4</version>
</versions>
<lastUpdated>20260301000000</lastUpdated>
<lastUpdated>20260302000000</lastUpdated>
</versioning>
</metadata>

View File

@@ -1 +1 @@
ab3c3fa378ac166364ea7cfd739ddb6f
9728121fa548f85a30f9c665eaf069c7

View File

@@ -1 +1 @@
8a764ee335f810b5ecc8b687de8da58391118e7d
995b4bcedd19cee87123779a9acc8835b2eac2c6

View File

@@ -145,6 +145,12 @@
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "confetti",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/confetti-0.7.0",
"packageUri": "lib/",
"languageVersion": "2.17"
},
{
"name": "convert",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/convert-3.1.2",

View File

@@ -80,6 +80,7 @@
"name": "design_system",
"version": "0.0.1",
"dependencies": [
"confetti",
"country_code_picker",
"flutter",
"flutter_riverpod",
@@ -349,6 +350,14 @@
"dio"
]
},
{
"name": "confetti",
"version": "0.7.0",
"dependencies": [
"flutter",
"vector_math"
]
},
{
"name": "lottie",
"version": "3.3.2",

View File

@@ -193,6 +193,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.19.1"
confetti:
dependency: transitive
description:
name: confetti
sha256: "979aafde2428c53947892c95eb244466c109c129b7eee9011f0a66caaca52267"
url: "https://pub.dev"
source: hosted
version: "0.7.0"
convert:
dependency: transitive
description: