Created
June 20, 2024 21:54
-
-
Save stevenosse/5c1b93e95f7face0ec16e954b868519c to your computer and use it in GitHub Desktop.
Confetti V2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:math'; | |
import 'package:flutter/material.dart'; | |
void main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
home: Scaffold( | |
body: Center( | |
child: ConfettiWidget( | |
numberOfParticles: 500, | |
particleTemplates: [ | |
Icon(Icons.star, color: Colors.red, size: 10), | |
Icon(Icons.favorite, color: Colors.pink, size: 10), | |
Icon(Icons.circle, color: Colors.blue, size: 10), | |
Icon(Icons.square, color: Colors.green, size: 10), | |
], | |
minSize: 5.0, | |
maxSize: 15.0, | |
duration: Duration(seconds: 5), | |
gravity: 0.05, | |
loop: false, | |
), | |
), | |
), | |
); | |
} | |
} | |
class ConfettiWidget extends StatefulWidget { | |
final int numberOfParticles; | |
final List<Widget> particleTemplates; | |
final double minSize; | |
final double maxSize; | |
final Duration duration; | |
final double gravity; | |
final bool loop; | |
const ConfettiWidget({ | |
Key? key, | |
this.numberOfParticles = 300, | |
required this.particleTemplates, | |
this.minSize = 5.0, | |
this.maxSize = 15.0, | |
this.duration = const Duration(seconds: 5), | |
this.gravity = 0.05, | |
this.loop = false, | |
}) : super(key: key); | |
@override | |
_ConfettiWidgetState createState() => _ConfettiWidgetState(); | |
} | |
class _ConfettiWidgetState extends State<ConfettiWidget> with SingleTickerProviderStateMixin { | |
late AnimationController _controller; | |
late List<Particle> _particles; | |
final Random _random = Random(); | |
@override | |
void initState() { | |
super.initState(); | |
_controller = AnimationController( | |
vsync: this, | |
duration: widget.duration, | |
); | |
if (widget.loop) { | |
_controller.addStatusListener((status) { | |
if (status == AnimationStatus.completed) { | |
_controller.reset(); | |
_initializeParticles(); | |
_controller.forward(); | |
} | |
}); | |
} | |
_controller.addListener(() => setState(() {})); | |
_initializeParticles(); | |
_controller.forward(); | |
} | |
void _initializeParticles() { | |
_particles = List.generate(widget.numberOfParticles, (_) => Particle( | |
_random, | |
widget.particleTemplates[_random.nextInt(widget.particleTemplates.length)], | |
widget.minSize, | |
widget.maxSize, | |
widget.gravity, | |
)); | |
} | |
@override | |
void dispose() { | |
_controller.dispose(); | |
super.dispose(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return LayoutBuilder( | |
builder: (context, constraints) { | |
return Stack( | |
children: _particles.map((particle) { | |
particle.update(_controller.value); | |
return Positioned( | |
left: particle.x * constraints.maxWidth, | |
top: particle.y * constraints.maxHeight, | |
child: Transform.scale( | |
scale: particle.size / 10, // Assuming original template size is 10 | |
child: particle.template, | |
), | |
); | |
}).toList(), | |
); | |
}, | |
); | |
} | |
} | |
class Particle { | |
double x; | |
double y; | |
Widget template; | |
double size; | |
double velocity; | |
double radians; | |
double gravity; | |
Particle(Random random, this.template, double minSize, double maxSize, this.gravity) | |
: x = random.nextBool() ? random.nextDouble() * 0.1 : 1 - random.nextDouble() * 0.1, | |
y = 1.0, | |
size = random.nextDouble() * (maxSize - minSize) + minSize, | |
velocity = random.nextDouble() * 0.5 + 0.1, | |
radians = random.nextDouble() * (pi / 2) + (pi / 4); | |
void update(double progress) { | |
x += cos(radians) * velocity * progress; | |
y -= sin(radians) * velocity * progress; | |
y += gravity * progress; | |
velocity *= 0.98; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment