在 Flutter 开发中,粒子动画能为应用增添生动的视觉效果,比如节日庆祝、完成任务后的反馈等场景。confetti
库是实现纸屑爆炸动画的优质选择,它轻量、易用且支持高度自定义。下面我会详细介绍并添加实战案例。

1. 安装
首先需要在项目中集成 confetti
库,步骤如下:
1.1. 添加依赖
打开 pubspec.yaml
文件,在 dependencies
节点下添加最新版本的依赖:
yaml
dependencies:
flutter:
sdk: flutter
confetti: ^0.8.0 # 最新版本
1.2. 安装依赖
在终端执行命令安装依赖,或点击 Android Studio 中的Pub get
按钮:
bash
flutter pub get
1.3. 导入库
在需要使用动画的 Dart 文件中导入库:
dart
import 'package:confetti/confetti.dart';
2. 核心 API 与参数解析
confetti
库的核心是 ConfettiWidget
组件和 ConfettiController
控制器,前者负责渲染动画,后者负责控制动画的播放、暂停、重置等。
2.1. 核心控制器:ConfettiController
ConfettiController
是动画的"大脑",通过它可以控制动画的生命周期。创建时需指定动画的持续时间、延迟时间等参数。
构造函数与关键参数
dart
ConfettiController({
required Duration duration, // 动画持续时间(必填)
Duration delay = Duration.zero, // 动画延迟启动时间(默认0)
double minInitialVelocity = 20, // 粒子初始最小速度(默认20)
double maxInitialVelocity = 80, // 粒子初始最大速度(默认80)
bool shouldLoop = false, // 动画是否循环(默认false)
double gravity = 0.2, // 粒子下落的重力系数(默认0.2,值越大下落越快)
})
常用方法
方法名 | 作用 |
---|---|
play() |
启动动画(若已播放,会先重置再启动) |
pause() |
暂停动画 |
resume() |
恢复暂停的动画 |
reset() |
重置动画(粒子回到初始状态,停止播放) |
dispose() |
释放控制器资源(必须在页面销毁时调用) |
2.2. 动画渲染:ConfettiWidget
ConfettiWidget
是渲染纸屑粒子的组件,需与 ConfettiController
绑定,同时支持自定义粒子的样式、方向、数量等。
构造函数与关键参数
dart
ConfettiWidget({
required ConfettiController confettiController, // 绑定控制器(必填)
double blastDirection = pi, // 粒子爆炸方向(单位:弧度,默认向下,pi=180°)
List<double> blastDirectionality = const [1], // 方向随机性([1]表示固定方向,[0.2, 0.8]表示20%-80%随机)
double emissionFrequency = 0.05, // 粒子发射频率(值越小,每秒发射粒子越多,默认0.05=20个/秒)
int numberOfParticles = 10, // 每次发射的粒子数量(默认10)
double maxBlastForce = 20, // 粒子爆炸的最大力度(值越大,粒子扩散越远,默认20)
double minBlastForce = 5, // 粒子爆炸的最小力度(默认5)
bool shouldLoop = false, // 是否循环发射粒子(优先级低于控制器的shouldLoop)
Widget? child, // 动画下方的子组件(如按钮、文本,动画会覆盖在子组件上方)
Color color = Colors.white, // 粒子默认颜色(若设置particleColor则失效)
List<Color>? particleColor, // 粒子颜色列表(随机使用列表中的颜色)
double particleSize = 10, // 粒子默认大小(若设置particleWidget则失效)
Widget? particleWidget, // 自定义粒子样式(如图片、图标,优先级最高)
bool blastDirectionHasRandom = false, // 是否完全随机方向(覆盖blastDirectionality)
})
方向参数说明
blastDirection
使用弧度表示方向,常见方向对应值如下:
- 向上:
3 * pi / 2
(或-pi / 2
) - 向下:
pi
- 向左:
pi
(水平向左需结合blastDirectionality
调整) - 向右:
0
(或2 * pi
) - 右上:
7 * pi / 4
- 右下:
pi / 4
3. 实战案例
下面通过一个简单案例,实现点击按钮后,从按钮位置向上发射彩色纸屑的效果:
完整代码
dart
import 'package:confetti/confetti.dart';
import 'package:flutter/material.dart';
import 'dart:math' as math;
class ConfettiBasicDemo extends StatefulWidget {
const ConfettiBasicDemo({super.key});
@override
State<ConfettiBasicDemo> createState() => _ConfettiBasicDemoState();
}
class _ConfettiBasicDemoState extends State<ConfettiBasicDemo> {
// 1. 创建控制器:持续2秒,向上发射,重力0.1(下落慢)
late final ConfettiController _confettiController;
@override
void initState() {
super.initState();
_confettiController = ConfettiController(
duration: const Duration(seconds: 2),
gravity: 0.1,
minInitialVelocity: 30,
maxInitialVelocity: 60,
);
}
// 2. 页面销毁时释放控制器
@override
void dispose() {
_confettiController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("基础纸屑动画")),
body: Center(
// 3. 用Stack包裹:让纸屑覆盖在按钮上方
child: Stack(
alignment: Alignment.center,
children: [
// 4. 纸屑动画组件
ConfettiWidget(
confettiController: _confettiController,
blastDirection: math.pi * 3 / 2, // 向上发射(270°)
emissionFrequency: 0.02, // 每秒50个粒子(1/0.02)
numberOfParticles: 15, // 每次发射15个
maxBlastForce: 30, // 最大爆炸力度
minBlastForce: 10, // 最小爆炸力度
particleColor: const [ // 随机彩色纸屑
Colors.red,
Colors.yellow,
Colors.blue,
Colors.green,
Colors.pink,
],
particleSize: 12, // 粒子大小
),
// 5. 触发按钮
ElevatedButton(
onPressed: () {
// 点击时启动动画(若已播放,先重置)
_confettiController.play();
},
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16),
textStyle: const TextStyle(fontSize: 18),
),
child: const Text("点击触发纸屑爆炸"),
),
],
),
),
);
}
}
效果说明
- 点击按钮后,会从按钮位置向上发射彩色纸屑,持续2秒。
- 粒子下落速度较慢(
gravity: 0.1
),且有随机的发射力度(10-30),呈现自然的扩散效果。
4. 常见问题与优化建议
下面是可能的一些问题与优化的建议,可以参考:
4.1. 动画卡顿
- 减少粒子数量:降低
numberOfParticles
(建议单次不超过30)。 - 降低发射频率:增大
emissionFrequency
(如从0.01改为0.03)。 - 简化粒子样式:避免使用复杂的
particleWidget
(如多层嵌套组件),优先用纯色或简单图标。
4.2. 让动画在指定位置触发
通过 Stack
的 alignment
或 Positioned
组件控制 ConfettiWidget
的位置。例如,让纸屑从顶部导航栏触发:
dart
Stack(
children: [
// 其他页面内容
Positioned(
top: 0,
left: 0,
right: 0,
child: ConfettiWidget(
confettiController: _controller,
blastDirection: math.pi / 2, // 向下发射
// 其他参数...
),
),
],
)
4.3. 实现动画的循环
在创建 ConfettiController
时设置 shouldLoop: true
,并将 duration
设为较大值(如 Duration(minutes: 1)
),即可实现持续循环的纸屑效果(适合节日活动页面)。
5. 总结
confetti
库为 Flutter 开发者提供了低门槛、高自定义的粒子动画解决方案,核心是通过 ConfettiController
控制动画生命周期,通过 ConfettiWidget
自定义粒子样式与发射规则。无论是简单的点击反馈,还是复杂的节日氛围营造,都能通过它快速实现。
下面是官方的地址以及预览Demo:
本次分享就到这儿啦,我是鹏多多,如果看了觉得有帮助的,欢迎 点赞 关注 评论,在此谢过道友;
往期文章