Skip to content

Commit

Permalink
Merge pull request #98 from funwithflutter/develop
Browse files Browse the repository at this point in the history
feat: release 0.8.0
  • Loading branch information
HayesGordon authored Sep 28, 2024
2 parents 63009ac + a917d06 commit 736dd34
Show file tree
Hide file tree
Showing 16 changed files with 710 additions and 217 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
## Upcomming
⛔️ Breaking!
- Added the concept of delta time, to allow for better simulation when the refresh rate is 120 (or more than 60). There should be no noticable change on a 60fps screen, however, there may be variance if Flutter drops frames. No changes needed from a widget level.
- `ParticleSystem.update` and `Pariticle.update` now contain a `deltaTime` argument. No changes needed from a widget level.
- Some visual difference, as now not all particles will rotate on the z-axis (50% chance). This change was maded to enhance visual fidelity.

⭐️ Added
- `clearAllParticles` added to stop method on controller: `_confettiController.stop(clearAllParticles: true);` default is false. If true particles will immediately be cleared/removed on stop. Calling `dispose` will also clear all particles immediately.
- `particleStatsCallback` added to `Confetti` widget to retrieve the `ParticleStats`. This provides info on the particle system, such as number of active and number of total particles in memory.
- `pauseEmissionOnLowFrameRate` to `Confetti` widget. Default is true. This will pause additional confetti emission if the frame rate is below 60fps, and will continue when resources are available. This can be disabled by setting to `false`, to force particle creation regardless of frame rate.

⚡️ Improved
- Various performance improvements!
- Confetti is now conditionally reused instead of recreated, big improvement
- 120hz refresh rate supported
- `pauseEmissionOnLowFrameRate` boolean added to `Confetti` widget to ensure smooth 60 FPS. This may however result in no confetti appearing if other complex operations are taking up resources. Set to `false` to disable.
- Temporary fix for issue [[#66](https://github.com/funwithflutter/flutter_confetti/issues/66)] with severe perf issues on Chrome macOS.

## [0.7.0]
⭐️ Added
- Stroke width and color can now optionally be set. `strokeWidth` (default 0) and `strokeColor` (default black). Requires a stroke width bigger than 0
Expand Down
1 change: 0 additions & 1 deletion example/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ fvm_config.json
/build/

# Web related
lib/generated_plugin_registrant.dart

# Exceptions to above rules.
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
41 changes: 38 additions & 3 deletions example/.metadata
Original file line number Diff line number Diff line change
@@ -1,10 +1,45 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
# This file should be version controlled.

version:
revision: ee032f67c734e607d8ea5c870ba744daf4bf56e7
channel: master
revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
channel: stable

project_type: app

# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
- platform: android
create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
- platform: ios
create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
- platform: linux
create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
- platform: macos
create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
- platform: web
create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
- platform: windows
create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849

# User provided section

# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
68 changes: 35 additions & 33 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ class ConfettiSample extends StatelessWidget {
const ConfettiSample({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return MaterialApp(
Widget build(BuildContext context) => MaterialApp(
title: 'Confetti',
home: Scaffold(
backgroundColor: Colors.grey[900],
body: MyApp(),
));
}
),
);
}

class MyApp extends StatefulWidget {
Expand Down Expand Up @@ -53,12 +52,13 @@ class _MyAppState extends State<MyApp> {
_controllerCenterLeft.dispose();
_controllerTopCenter.dispose();
_controllerBottomCenter.dispose();

super.dispose();
}

/// A custom Path to paint stars.
Path drawStar(Size size) {
// Method to convert degree to radians
// Method to convert degrees to radians
double degToRad(double deg) => deg * (pi / 180.0);

const numberOfPoints = 5;
Expand Down Expand Up @@ -108,10 +108,11 @@ class _MyAppState extends State<MyApp> {
Align(
alignment: Alignment.center,
child: TextButton(
onPressed: () {
_controllerCenter.play();
},
child: _display('blast\nstars')),
onPressed: () {
_controllerCenter.play();
},
child: _text('blast\nstars'),
),
),

//CENTER RIGHT -- Emit left
Expand All @@ -137,10 +138,11 @@ class _MyAppState extends State<MyApp> {
Align(
alignment: Alignment.centerRight,
child: TextButton(
onPressed: () {
_controllerCenterRight.play();
},
child: _display('pump left')),
onPressed: () {
_controllerCenterRight.play();
},
child: _text('pump left'),
),
),

//CENTER LEFT - Emit right
Expand All @@ -150,21 +152,22 @@ class _MyAppState extends State<MyApp> {
confettiController: _controllerCenterLeft,
blastDirection: 0, // radial value - RIGHT
emissionFrequency: 0.6,
minimumSize: const Size(10,
10), // set the minimum potential size for the confetti (width, height)
maximumSize: const Size(50,
50), // set the maximum potential size for the confetti (width, height)
// set the minimum potential size for the confetti (width, height)
minimumSize: const Size(10, 10),
// set the maximum potential size for the confetti (width, height)
maximumSize: const Size(50, 50),
numberOfParticles: 1,
gravity: 0.1,
),
),
Align(
alignment: Alignment.centerLeft,
child: TextButton(
onPressed: () {
_controllerCenterLeft.play();
},
child: _display('singles')),
onPressed: () {
_controllerCenterLeft.play();
},
child: _text('singles'),
),
),

//TOP CENTER - shoot down
Expand All @@ -186,9 +189,9 @@ class _MyAppState extends State<MyApp> {
onPressed: () {
_controllerTopCenter.play();
},
child: _display('goliath')),
child: _text('goliath')),
),
//BOTTOM CENTER
//BOTTOM CENTER - Shoot up
Align(
alignment: Alignment.bottomCenter,
child: ConfettiWidget(
Expand All @@ -204,20 +207,19 @@ class _MyAppState extends State<MyApp> {
Align(
alignment: Alignment.bottomCenter,
child: TextButton(
onPressed: () {
_controllerBottomCenter.play();
},
child: _display('hard and infrequent')),
onPressed: () {
_controllerBottomCenter.play();
},
child: _text('hard and infrequent'),
),
),
],
),
);
}

Text _display(String text) {
return Text(
text,
style: const TextStyle(color: Colors.white, fontSize: 20),
);
}
Text _text(String text) => Text(
text,
style: const TextStyle(color: Colors.white, fontSize: 20),
);
}
158 changes: 158 additions & 0 deletions example/lib/performance_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import 'dart:math';

import 'package:flutter/material.dart';

import 'package:confetti/confetti.dart';

void main() => runApp(const ConfettiPerformanceTestSample());

class ConfettiPerformanceTestSample extends StatelessWidget {
const ConfettiPerformanceTestSample({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) => MaterialApp(
title: 'Confetti Performance Test',
showPerformanceOverlay: true,
home: Scaffold(
backgroundColor: Colors.grey[900],
body: MyApp(),
),
);
}

class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
late ConfettiController _confettiController;

final ConfettiStats stats = ConfettiStats();

@override
void initState() {
super.initState();
_confettiController = ConfettiController(
duration: const Duration(seconds: 10),

/// The following can be used to retrieve stats on the particles.
particleStatsCallback: (pStats) => stats.setStats(pStats),
);
}

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

/// A custom Path to paint stars.
Path drawStar(Size size) {
// Method to convert degrees to radians
double degToRad(double deg) => deg * (pi / 180.0);

const numberOfPoints = 5;
final halfWidth = size.width / 2;
final externalRadius = halfWidth;
final internalRadius = halfWidth / 2.5;
final degreesPerStep = degToRad(360 / numberOfPoints);
final halfDegreesPerStep = degreesPerStep / 2;
final path = Path();
final fullAngle = degToRad(360);
path.moveTo(size.width, halfWidth);

for (double step = 0; step < fullAngle; step += degreesPerStep) {
path.lineTo(halfWidth + externalRadius * cos(step),
halfWidth + externalRadius * sin(step));
path.lineTo(halfWidth + internalRadius * cos(step + halfDegreesPerStep),
halfWidth + internalRadius * sin(step + halfDegreesPerStep));
}
path.close();
return path;
}

@override
Widget build(BuildContext context) {
return SafeArea(
child: Stack(
children: <Widget>[
Align(
alignment: Alignment.center,
child: ConfettiWidget(
emissionFrequency: 1,
numberOfParticles: 100,
confettiController: _confettiController,
blastDirectionality: BlastDirectionality.explosive,
shouldLoop: true,
createParticlePath: drawStar,
),
),
Align(
alignment: Alignment.center,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
TextButton(
onPressed: () {
_confettiController.play();
},
child: _text('start'),
),
TextButton(
onPressed: () {
_confettiController.stop();
},
child: _text('stop'),
),
TextButton(
onPressed: () {
_confettiController.dispose();
},
child: _text('dispose'),
),
],
),
),

/// Display stats of confetti
Align(
alignment: Alignment.topCenter,
child: AnimatedBuilder(
animation: stats,
builder: (context, _) => Column(
children: [
Text(
'Particles: ${stats.stats.numberOfParticles}',
style: TextStyle(color: Colors.white, fontSize: 22),
),
Text(
'Active Particles: ${stats.stats.activeNumberOfParticles}',
style: TextStyle(color: Colors.white, fontSize: 22),
),
],
),
),
),
],
),
);
}

Text _text(String text) => Text(
text,
style: const TextStyle(color: Colors.white, fontSize: 20),
);
}

/// Demonstration showing how to use the `particleStatsCallback` to retrieve
/// [ParticleStats].
class ConfettiStats extends ChangeNotifier {
ParticleStats stats;
ConfettiStats() : stats = ParticleStats.empty();

void setStats(ParticleStats value) {
stats = value;
notifyListeners();
}
}
Loading

0 comments on commit 736dd34

Please sign in to comment.