Flutter粒子效果插件confetti的使用
Flutter粒子效果插件confetti的使用
Blast some confetti all over the screen and celebrate user achievements!
Demo
- 视频展示 Confetti 效果:Confetti in Action
- 在线 WEB Demo
- 一个旧的视频教程可以在这里找到:Video Walkthrough
Getting Started
要使用这个插件,你需要在 pubspec.yaml
文件中添加 confetti
作为依赖项。
你可以通过查看示例代码快速开始。为了生成平台文件夹,请在示例文件夹中运行:
flutter create .
使用步骤
首先,你需要实例化一个 ConfettiController
变量,并传入一个 Duration
参数。ConfettiController
可以在 initState
方法中实例化并在 dispose
方法中销毁。
在 build
方法中返回一个 ConfettiWidget
。唯一必需的属性是 ConfettiController
。
其他可设置的属性有:
blastDirectionality
-> 枚举值,用于指定粒子发射方向。BlastDirectionality.explosive
将随机发射,不需要设置blastDirection
。BlastDirectionality.directional
需要设置blastDirection
来指定发射方向。blastDirection
-> 径向值,用于确定粒子发射的方向,默认为PI
(180 度)。值为PI
将向左发射。emissionFrequency
-> 介于 0 和 1 之间的值,表示每帧发射粒子的概率,默认为 0.02 (2%)。numberOfParticles
-> 每次发射的粒子数量,默认为 10。shouldLoop
-> 确定动画是否循环。maxBlastForce
-> 粒子初始5帧内的最大爆发力,默认为 20。minBlastForce
-> 粒子初始5帧内的最小爆发力,默认为 5。displayTarget
-> 如果为true
,则显示发射点的十字准心。colors
-> 提供颜色列表来手动设置粒子颜色。如果省略,则使用随机颜色。strokeWidth
-> 给画笔设置描边宽度,需要大于 0 才可见,默认为 0。strokeColor
-> 设置描边颜色,默认为黑色。minimumSize
-> 控制粒子的最小可能尺寸,默认为Size(10,10)
。maximumSize
-> 控制粒子的最大可能尺寸,默认为Size(100,100)
。gravity
-> 改变粒子下落速度,值介于 0 和 1 之间,默认为 0.1。particleDrag
-> 配置应用于粒子的阻力,默认为 0.05。canvas
-> 设置显示粒子的区域大小,默认为全屏。createParticlePath
-> 返回自定义Path
的函数,默认返回矩形路径。
自定义 createParticlePath
示例
Path drawStar(Size size) {
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;
}
完整示例代码
import 'dart:math';
import 'package:confetti/confetti.dart';
import 'package:flutter/material.dart';
void main() => runApp(const ConfettiSample());
class ConfettiSample extends StatelessWidget {
const ConfettiSample({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => MaterialApp(
title: 'Confetti',
home: Scaffold(
backgroundColor: Colors.grey[900],
body: MyApp(),
),
);
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late ConfettiController _controllerCenter;
late ConfettiController _controllerCenterRight;
late ConfettiController _controllerCenterLeft;
late ConfettiController _controllerTopCenter;
late ConfettiController _controllerBottomCenter;
@override
void initState() {
super.initState();
_controllerCenter =
ConfettiController(duration: const Duration(seconds: 10));
_controllerCenterRight =
ConfettiController(duration: const Duration(seconds: 10));
_controllerCenterLeft =
ConfettiController(duration: const Duration(seconds: 10));
_controllerTopCenter =
ConfettiController(duration: const Duration(seconds: 10));
_controllerBottomCenter =
ConfettiController(duration: const Duration(seconds: 10));
}
@override
void dispose() {
_controllerCenter.dispose();
_controllerCenterRight.dispose();
_controllerCenterLeft.dispose();
_controllerTopCenter.dispose();
_controllerBottomCenter.dispose();
super.dispose();
}
Path drawStar(Size size) {
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: [
// CENTER -- Blast
Align(
alignment: Alignment.center,
child: ConfettiWidget(
confettiController: _controllerCenter,
blastDirectionality: BlastDirectionality.explosive,
shouldLoop: true,
colors: const [
Colors.green,
Colors.blue,
Colors.pink,
Colors.orange,
Colors.purple
],
createParticlePath: drawStar,
),
),
Align(
alignment: Alignment.center,
child: TextButton(
onPressed: () {
_controllerCenter.play();
},
child: _text('blast\nstars'),
),
),
// CENTER RIGHT -- Emit left
Align(
alignment: Alignment.centerRight,
child: ConfettiWidget(
confettiController: _controllerCenterRight,
blastDirection: pi,
particleDrag: 0.05,
emissionFrequency: 0.05,
numberOfParticles: 20,
gravity: 0.05,
shouldLoop: false,
colors: const [
Colors.green,
Colors.blue,
Colors.pink
],
strokeWidth: 1,
strokeColor: Colors.white,
),
),
Align(
alignment: Alignment.centerRight,
child: TextButton(
onPressed: () {
_controllerCenterRight.play();
},
child: _text('pump left'),
),
),
// CENTER LEFT - Emit right
Align(
alignment: Alignment.centerLeft,
child: ConfettiWidget(
confettiController: _controllerCenterLeft,
blastDirection: 0,
emissionFrequency: 0.6,
minimumSize: const Size(10, 10),
maximumSize: const Size(50, 50),
numberOfParticles: 1,
gravity: 0.1,
),
),
Align(
alignment: Alignment.centerLeft,
child: TextButton(
onPressed: () {
_controllerCenterLeft.play();
},
child: _text('singles'),
),
),
// TOP CENTER - shoot down
Align(
alignment: Alignment.topCenter,
child: ConfettiWidget(
confettiController: _controllerTopCenter,
blastDirection: pi / 2,
maxBlastForce: 5,
minBlastForce: 2,
emissionFrequency: 0.05,
numberOfParticles: 50,
gravity: 1,
),
),
Align(
alignment: Alignment.topCenter,
child: TextButton(
onPressed: () {
_controllerTopCenter.play();
},
child: _text('goliath')),
),
// BOTTOM CENTER - Shoot up
Align(
alignment: Alignment.bottomCenter,
child: ConfettiWidget(
confettiController: _controllerBottomCenter,
blastDirection: -pi / 2,
emissionFrequency: 0.01,
numberOfParticles: 20,
maxBlastForce: 100,
minBlastForce: 80,
gravity: 0.3,
),
),
Align(
alignment: Alignment.bottomCenter,
child: TextButton(
onPressed: () {
_controllerBottomCenter.play();
},
child: _text('hard and infrequent'),
),
),
],
),
);
}
Text _text(String text) => Text(
text,
style: const TextStyle(color: Colors.white, fontSize: 20),
);
}
Enjoy the confetti!
注意:不要过度使用粒子数量。屏幕上的粒子越多,需要进行的计算就越多。尽管性能有所改进,但过多的粒子仍可能导致性能问题。请谨慎使用。
更多关于Flutter粒子效果插件confetti的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter粒子效果插件confetti的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用confetti
插件来创建粒子效果的示例代码。
首先,你需要在你的pubspec.yaml
文件中添加confetti
依赖项:
dependencies:
flutter:
sdk: flutter
confetti: ^0.6.0 # 请检查最新版本号
然后运行flutter pub get
来获取依赖项。
接下来,你可以在你的Flutter应用中创建一个包含粒子效果的页面。以下是一个完整的示例代码,展示如何在点击按钮时触发粒子效果:
import 'package:flutter/material.dart';
import 'package:confetti/confetti.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Confetti Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ConfettiPage(),
);
}
}
class ConfettiPage extends StatefulWidget {
@override
_ConfettiPageState createState() => _ConfettiPageState();
}
class _ConfettiPageState extends State<ConfettiPage> {
final ConfettiController _confettiController = ConfettiController();
@override
void dispose() {
_confettiController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Confetti Example'),
),
body: Stack(
children: [
Center(
child: ConfettiWidget(
confettiController: _confettiController,
blastDirectionality: BlastDirectionality.explosive,
emissionFrequency: 0.02,
numberOfParticles: 50,
gravity: 0.1,
colors: [
Colors.redAccent,
Colors.greenAccent,
Colors.blueAccent,
Colors.yellowAccent,
],
shapes: [
ConfettiShape.circle,
ConfettiShape.square,
ConfettiShape.triangle,
],
blastCount: 1,
// 可以在这里添加更多自定义参数
),
),
Center(
child: ElevatedButton(
onPressed: () {
_confettiController.addBurst(
count: 100,
beginPosition: Offset.zero,
colors: [Colors.red, Colors.blue, Colors.green, Colors.yellow],
blastRadius: 10.0,
);
},
child: Text('Trigger Confetti'),
),
),
],
),
);
}
}
在这个示例中:
ConfettiController
用于控制粒子效果的播放。ConfettiWidget
是显示粒子效果的部件。你可以自定义它的许多属性,比如粒子的形状、颜色、数量、重力等。addBurst
方法用于在特定位置触发一次粒子爆发。在这个例子中,点击按钮时会触发一次爆发。
你可以根据需要调整这些参数来实现不同的粒子效果。希望这个示例对你有帮助!