Farmers in yards world, beautiful application experience, from the programmer for the processing of detail, and self requirements state, agriculture in the yard a member of the young people is busy, every day, every week, can leave some footprints, is the creation of content, there is a persistent, is I don’t know why, if you lost, might as well to Chou Chou code track of farmers.
- Beautiful musical beats take you through the coding process of this effect
- Insist on every day, is the pursuit of every ideal youth
- Follow in the footsteps of young people, and maybe your answer is right here
The effect achieved in this article is shown in the figure below:
/// program entry
void main(a) {
runApp(
MaterialApp(
// Do not display the debug tag
debugShowCheckedModeBanner: false.// The first page is displayed by default
home: TestPage(),
),
);
}
Copy the code
Let’s start with a global method to get random transparency of the white color, which is used to generate different white colors for snowflakes:
// Globally define the method to get the color
Color getRandomWhiteColor(Random random) {
// Transparency 0 to 200 255 is opaque
int a = random.nextInt(200);
return Color.fromARGB(a, 255.255.255);
}
Copy the code
Define the snowflake model to store the basic attribute information of snowflakes:
/// Define a snowflake model to store basic information about snowflakes
class BobbleBean {
/ / position
Offset postion;
// The initial position
Offset origin;
/ / color
Color color;
// The speed of movement
double speed;
/ / radius
double radius;
}
Copy the code
/// snowflake background
class TestPage extends StatefulWidget {
@override
_TestPageState createState(a) => _TestPageState();
}
class _TestPageState extends State<TestPage> with TickerProviderStateMixin {
// Create a collection to hold bubbles
List<BobbleBean> _list = [];
/ / random number
Random _random = new Random(DateTime.now().microsecondsSinceEpoch);
// Create an animation controller
AnimationController _animationController;
// Create bubbles in the initializer function
@override
void initState(a) {
super.initState();
Future.delayed(Duration.zero, () {
initData();
});
// Create the animation controller for 1 second
_animationController = new AnimationController(
vsync: this, duration: Duration(milliseconds: 10000));
// Perform refresh listening
_animationController.addListener(() {
setState(() {});
});
// Turn on the bubble movement
_animationController.repeat();
// Status bar hidden
SystemChrome.setEnabledSystemUIOverlays([]);
}
void initData(a) {
for (int i = 0; i < 2000; i++) {
BobbleBean bean = new BobbleBean();
// Get random transparency white
bean.color = getRandomWhiteColor(_random);
// Set the position to the default drawing position and then change it
double x = _random.nextDouble() * MediaQuery.of(context).size.width;
double y = _random.nextDouble() * MediaQuery.of(context).size.height;
double z = _random.nextDouble() + 0.5;
bean.speed = _random.nextDouble() + 0.01 / z;
bean.postion = Offset(x, y);
bean.origin = Offset(x, 0);
// Set the radius
bean.radius = 2.0/ z; _list.add(bean); }}... . }Copy the code
The page UI is constructed as follows:
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
/// Fill the layout
body: Container(
width: double.infinity,
height: double.infinity,
// Cascading layout
child: Stack(
children: [
// Part 1 background
Positioned.fill(
child: Image.asset(
"assets/images/bg_snow.png",
fit: BoxFit.fill,
),
),
// Part 2 Snowflakes
CustomPaint(
size: MediaQuery.of(context).size,
/ / the canvas
painter: SnowCustomMyPainter(list: _list, random: _random),
),
],
),
),
);
}
Copy the code
The custom canvas is as follows:
/// Create canvas
class SnowCustomMyPainter extends CustomPainter {
List<BobbleBean> list;
Random random;
SnowCustomMyPainter({this.list, this.random});
// Start with a brush
Paint _paint = newPaint().. isAntiAlias =true;
// Specify the drawing function
@override
void paint(Canvas canvas, Size size) {
// Recalculate the position of each point before drawing
list.forEach((element) {
// Left and right slightly jitter
double dx = random.nextDouble() * 2.0 - 1.0;
// The vertical position is offset
double dy = element.speed;
// Calculate the position offset
element.postion += Offset(dx, dy);
// Reset the position
if(element.postion.dy > size.height) { element.postion = element.origin; }});//
/ / / / map
list.forEach((element) {
// Change the color of the brush
_paint.color = element.color;
/ / draw circle
canvas.drawCircle(element.postion, element.radius, _paint);
});
}
// Refresh control
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
// Return false not to refresh
return true; }}Copy the code
[X1] Daily reminder of wechat public account at any time, daily accumulation, free to follow the bottom of the article scan code attention
【 X2 】 Various series of free open source video tutorials focus on you won’t get lost
【 X3 】 series article millions of Demo copy and paste use at any time
[X4] Short video is not the same experience
[x5] must have source code
Not limited to thinking, not limited to language restrictions, is the highest realm of programming.
With xiaobian character, must be to record a set of video, and then upload
If you are interested, you can check out the watermelon video – early risers