import 'dart:math';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
final List<SnowSlake> _snowflakes =
List.generate(1000, (index) => SnowSlake());
@override
void initState() {
_controller =
AnimationController(vsync: this, duration: const Duration(seconds: 1))
..repeat();
super.initState();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
height: double.infinity,
decoration: const BoxDecoration(
color: Colors.blue,
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Colors.blue, Colors.lightBlue, Colors.white],
stops: [0, 0.7, 1]),
),
child: AnimatedBuilder(
animation: _controller,
builder: (_, __) {
_snowflakes.forEach((snow) => snow.fall());
return CustomPaint(
painter: MyPainter(_snowflakes),
child: const Text('demo'),
);
},
),
);
}
}
class MyPainter extends CustomPainter {
final List<SnowSlake> snowfakes;
MyPainter(this.snowfakes);
@override
void paint(Canvas canvas, Size size) {
final whitePaint = Paint()..color = Colors.white;
canvas.drawCircle(size.center(const Offset(0, 130)), 50, whitePaint);
canvas.drawOval(
Rect.fromCenter(
center: size.center(const Offset(0, 280)), width: 200, height: 250),
whitePaint);
for (var snowSlake in snowfakes) {
canvas.drawCircle(
Offset(snowSlake.x, snowSlake.y), snowSlake.radius, whitePaint);
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
class SnowSlake {
double x = Random().nextDouble() * 400;
double y = Random().nextDouble() * 800;
double radius = Random().nextDouble() * 2 + 2;
double velocity = Random().nextDouble() * 4 + 2;
fall() {
y += velocity;
if (y > 800) {
y = 0;
x = Random().nextDouble() * 400;
radius = Random().nextDouble() * 2 + 2;
velocity = Random().nextDouble() * 4 + 2;
}
}
}
视频网址:Flutter 动画教程 3-3 直接操作底层的CustomPainter_哔哩哔哩_bilibili