Flutter wheels snow animation, also Android snow animation at the bottom, please give it a thumbs up

  • A circle
  • Create 200 random circles and draw
  • Set the animation

Again, let’s take a look at what we’re going to accomplish today:



The QR code on the home page is my official account, and I will upload it to the official account

Today is the final snow animation

Let’s start with a wave:

  • Random size snowflakes (circles)
  • The snowflake (circle) can be offset left and right
  • The snowflake (circle) moves vertically towards the lower right corner
  • Snowflakes (circles) are created repeatedly when they disappear

A circle

Let me show you how to draw a circle, okay


 @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.black,
      child: CustomPaint(
        painter: MyCustomPainter(),
        // Fill up the screen
        size: MediaQuery.of(context).size,
      ),
    );
  }


class MyCustomPainter extends CustomPainter {
// Create a brush
  Paint _paint = newPaint() .. isAntiAlias =true
    ..color = Colors.white;

  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawCircle(Offset(100.100), 50, _paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
  / / refresh
    return true; }}Copy the code

Refer to the bubble landing page of the Flutter Wheels documentation for this section of code

Rendering (1.1):



Let’s write it in class form:

Create the snowflake Bean class

class SnowBean {
  / / position
  Offset postion = Offset(100.100);

  / / radius
  double radius = 50;
}


class MyCustomPainter extends CustomPainter {
  // Create a brush
   Paint _paint = newPaint() .. isAntiAlias =true
    ..color = Colors.white;
  @override
  void paint(Canvas canvas, Size size) {
   SnowBean snowBean = new SnowBean();
    canvas.drawCircle(snowBean.postion, snowBean.radius, _paint);
  }
  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {... }}Copy the code

Rendering (1.2):



This part of the code is very simple, not to mention.

Create 200 random circles and draw

List<SnowBean> _list = [];

  @override
  void initState(a) {
    // TODO: implement initState
    super.initState();
    Future.delayed(Duration(seconds: 0), () {
      initData();
    });
  }

  void initData(a) {
    for (int i = 0; i <= 200; i++) {
      SnowBean snowBean = new SnowBean();
	// mediaQuery.of (context).sie.width is the width of the screen
	// mediaQuery.of (context).size. Height is the height of the screen
      double dx = _random.nextDouble() * MediaQuery.of(context).size.width;
      double dy = _random.nextDouble() * MediaQuery.of(context).size.height;
       snowBean.postion = Offset(dx, dy);
      snowBean.radius = _random.nextDouble() + 1; _list.add(snowBean); }}class MyCustomPainter extends CustomPainter {
  // Create a brush. List<SnowBean> list; MyCustomPainter(this.list);
  @override
  void paint(Canvas canvas, Size size) {
    list.forEach((element) {
      canvas.drawCircle(element.postion, element.radius, _paint);
    });
  }
  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {... }}Copy the code

This code is very simple. When initState() is initialized, create 200 circles of random size and position asynchronously and pass the list to MyCustomPainter(), who draws each circle

Check out the results:



Now is not very feeling ~

Set the animation

AnimationController _animationController;

  @override
  void initState(a) {
    // TODO: implement initState
    super.initState();
    // Create an animation for 1 second
    _animationController =
        new AnimationController(vsync: this, duration: Duration(seconds: 10));

    // Animation listener
    _animationController.addListener(() {
      setState(() {});
    });

    // Repeat the bubble animation
    _animationController.repeat();
  }
Copy the code

This code reference Flutter AnimatedWidget, AnimatedBuilder animation (2.4)

So let’s rewrite the MyCustomPainter () method

class MyCustomPainter extends CustomPainter {
  List<SnowBean> list;
  Random _random;

  MyCustomPainter(this.list, this._random);

  Paint _paint = newPaint() .. isAntiAlias =true
    ..color = Colors.white;

  @override
  void paint(Canvas canvas, Size size) {

    list.forEach((element) {
      double dy = element.postion.dy;
      double dx = element.postion.dx;

      /** * Return the snowflake to its starting position */ if it moves off screen
      if (dy >= size.height) {
        dy = 0;
      }
      /** * If the X-axis snowflake moves off the screen, return it to its starting position */
      if (dx >= size.width) {
        dx = 0;
      }

      element.postion =
          Offset(dx + _random.nextDouble(), dy + _random.nextDouble() + element.speed + 3);
    });

    list.forEach((element) {
      canvas.drawCircle(element.postion, element.radius, _paint);
    });
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true; }} SnowBean adds the speed of movement:class SnowBean {
  / / position
  Offset postion = Offset(100.100);

  / / radius
  double radius = 50;

  // Move speed
  doublespeed; } reinitialize:void initData(a) {
    for (int i = 0; i <= 200; i++) {
      SnowBean snowBean = new SnowBean();

	  // _random.nextdouble () is a random decimal from 0 to 1
      double dx = _random.nextDouble() * MediaQuery.of(context).size.width;
      double dy = _random.nextDouble() * MediaQuery.of(context).size.height;
      snowBean.postion = Offset(dx, dy);
      snowBean.radius = _random.nextDouble() + 1;
      snowBean.speed = _random.nextDouble() + 5; _list.add(snowBean); }}Copy the code

I’m sure most of this code is fairly legible as you see it;

To explain this code:

  /** * Return the snowflake to its starting position */ if it moves off screen
      if (dy >= size.height) {
        dy = 0;
      }
      /** * If the X-axis snowflake moves off the screen, return it to its starting position */
      if (dx >= size.width) {
        dx = 0;
      }
Copy the code

What this code is saying is, when dx or dy moves off the screen, let him redraw it

 element.postion =
         Offset(dx + _random.nextDouble(),
          dy +  element.speed );
Copy the code
  • Parameter 1 :dx plus _random.nextdouble () represents the current longitude plus a random number of 0-1, with a left/right offset animation
  • Parameter two :dy plus a reduced running speed for the current value of dy

Take a look at the results:



Maybe some students will still be confused, let the animation repeated execution, but why the snow will move?

Notice the setState(){} method



The setState(){} method is always executing sholdRepaint ().



In paint(), we simply move dx left and right,dy down, and when we move it out of the screen, we return it to the starting position, so it always’ snows’. If false is returned, we only do it once

The complete code

What do you like?

The Bubble login page of the Flutter Wheel (1)

Snow effect on Android wheels

Original is not easy, your thumbs up is my biggest support, leave your thumbs up ~