import 'dart:math'; // import 'dart:ui' as ui; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; /// create by 张风捷特烈 on 2020/11/5 /// contact me by email 1981462002@qq.com /// 说明: class Paper extends StatelessWidget { const Paper({super.key}); @override Widget build(BuildContext context) { return Container( color: Colors.white, alignment: Alignment.center, child: const World(), ); } } class World extends StatefulWidget { const World({super.key}); @override _WorldState createState() => _WorldState(); } class _WorldState extends State with SingleTickerProviderStateMixin { late AnimationController _controller; ParticleManage pm = ParticleManage(); Random random = Random(); @override void initState() { super.initState(); initParticleManage(); _controller = AnimationController( duration: const Duration(seconds: 1), vsync: this, )..addListener(pm.tick) // ..repeat() ; } void initParticleManage() { pm.size = Size(300, 200); for (var i = 0; i < 30; i++) { pm.particles.add(Particle( color: randomRGB(), size: 5 + 4 * random.nextDouble(), vx: 3 * random.nextDouble() * pow(-1, random.nextInt(20)), vy: 3 * random.nextDouble() * pow(-1, random.nextInt(20)), ay: 0.1, x: 150, y: 100)); } } Color randomRGB({int limitR = 0, int limitG = 0, int limitB = 0,}) { var r = limitR + random.nextInt(256 - limitR); //红值 var g = limitG + random.nextInt(256 - limitG); //绿值 var b = limitB + random.nextInt(256 - limitB); //蓝值 return Color.fromARGB(255, r, g, b); //生成argb模式的颜色 } @override void dispose() { _controller.dispose(); super.dispose(); } theWorld() { if (_controller.isAnimating) { _controller.stop(); } else { _controller.repeat(); } } @override Widget build(BuildContext context) { return GestureDetector( onTap: theWorld, child: CustomPaint( size: pm.size, painter: WorldRender(manage: pm), ), ); } } class ParticleManage with ChangeNotifier { List particles = []; Size size; ParticleManage({this.size = Size.zero}); void setParticles(List particles) { this.particles = particles; } void addParticle(Particle particle) { particles.add(particle); notifyListeners(); } void tick() { particles.forEach(doUpdate); notifyListeners(); } void doUpdate(Particle p) { p.vy += p.ay; // y加速度变化 p.vx += p.ax; // x加速度变化 p.x += p.vx; p.y += p.vy; if (p.x > size.width) { p.x = size.width; p.vx = -p.vx; } if (p.x < 0) { p.x = 0; p.vx = -p.vx; } if (p.y > size.height) { p.y = size.height; p.vy = -p.vy; } if (p.y < 0) { p.y = 0; p.vy = -p.vy; } } void reset() { particles.forEach((p) { p.x = 0; }); notifyListeners(); } } class WorldRender extends CustomPainter { final ParticleManage manage; Paint fillPaint = Paint(); Paint stokePaint = Paint() ..strokeWidth = 0.5 ..style = PaintingStyle.stroke; WorldRender({required this.manage}) : super(repaint: manage); @override void paint(Canvas canvas, Size size) { canvas.drawRect(Offset.zero & size, stokePaint); manage.particles.forEach((particle) { drawParticle(canvas, particle); }); } void drawParticle(Canvas canvas, Particle particle) { fillPaint.color = particle.color; canvas.drawCircle(Offset(particle.x, particle.y), particle.size, fillPaint); } @override bool shouldRepaint(covariant WorldRender oldDelegate) => oldDelegate.manage != manage; } class Particle { /// x 位移. double x; /// y 位移. double y; /// 粒子水平速度. double vx; // 粒子水平加速度 double ax; // 粒子竖直加速度 double ay; ///粒子竖直速度. double vy; /// 粒子大小. double size; /// 粒子颜色. Color color; Particle({ this.x = 0, this.y = 0, this.ax = 0, this.ay = 0, this.vx = 0, this.vy = 0, this.size = 0, this.color = Colors.black, }); }