This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

preface

There are a lot of helpless in the island, such as programmers belong to the more partial door occupation. Especially in the early years, after jumping a few slots in the industry, you probably already know your entire circle 😂😂😂. Then, another move could mean “bumping into” a former colleague again, which Pan says is “very awkward”. So, if you ask me what I do, I usually answer that I work in computers. The result can be even more awkward, as the person who asked may look at you with a smile, looking at you as if you were a monster, and then suddenly blurt out a soul-searching question: “My computer is broken. Can you fix it?” Not surprisingly, it cost $100 to reinstall Windows XP on the island back then. Alas, had regretted not in zhongguancun tripod a lot of learning machine technology……

This is so impressive that we will use animation to reproduce this expression, as shown in the picture below.

AnimatedContainer introduction

Before we implement it, we introduce a new component, AnimatedContainer. The name refers to Container. In fact, AnimatedContainer is an animation Container in a Flutter. Container has almost all of the properties of a Flutter.

AnimatedContainer({
    Key? key,
    this.alignment,
    this.padding,
    Color? color,
    Decoration? decoration,
    this.foregroundDecoration,
    double? width,
    double? height,
    BoxConstraints? constraints,
    this.margin,
    this.transform,
    this.transformAlignment,
    this.child,
    this.clipBehavior = Clip.none,
    Curve curve = Curves.linear,
    required Duration duration,
    VoidCallback? onEnd,
  });

Container({
    Key? key,
    this.alignment,
    this.padding,
    this.color,
    this.decoration,
    this.foregroundDecoration,
    double? width,
    double? height,
    BoxConstraints? constraints,
    this.margin,
    this.transform,
    this.transformAlignment,
    this.child,
    this.clipBehavior = Clip.none,
  });
Copy the code

As you can see, there are only three different attributes between AnimatedContainer and Container, and these are the parameters that control the animation:

  • curve: Animation curve, default is linear;
  • duration: dynamic effect duration parameter;
  • onEnd: Callback method after dynamic effect ends.

The feature of AnimatedContainer is that all attributes related to the appearance will generate a transition effect. When these attributes change, the generated animation effect will be used to complete the transition, thus displaying the animation effect. A smiley expression like the one we want to implement is actually implemented using the AnimatedContainer. The use of AnimatedContainer can be found in the official documentation: Using AnimatedContainer.

Component structure

The bottom of our smile is a round head with two eyes and a mouth. The eyes and mouth have movement effect, and the eyes have direction effect. All of these kinetic effects can be usedAnimatedContainerTo implement. The large page structure is as follows:

Details of the implementation

Head this is easy, directly with the prototype cut, set the size and background can be:

/ / head
ClipOval(
  child: Container(
    width: 120,
    height: 120,
    color: Colors.blue,
  ),
),
Copy the code

Eye The left eye is a little different from the right. The eye is actually the AnimatedContainer trimmed to a circle using the borderRadius, and the eye is a child of the AnimatedContainer — a black circle. Looking left or right is controlled by a variable called seeLeft, and the transitions from left to right are controlled by AnimatedContainer.

  • seeLeft = true, look left: eye alignment isbottomLeft, the left eye moves down a little in the longitudinal direction; Move your right eye to the left so that it looks left.
  • seeLeft = false, to the right: eye alignment isbottomRightMove the right eye down slightly in the longitudinal direction; Move your left eye to the right so that it looks right;

The implementation code is as follows:

/ / the left eyePositioned( top: marginTop, left: marginLR, child: AnimatedContainer( alignment: seeLeft ? Alignment.bottomLeft : Alignment.bottomRight, padding: EdgeInsets.all(eyePadding), transform: Matrix4.identity() .. translate( seeLeft ?0.0 : sideOffset, seeLeft ? eyeOffset : 0.0.0),
    duration: Duration(seconds: 1),
    curve: Curves.fastOutSlowIn,
    width: eyeSize,
    height: eyeSize,
    decoration: BoxDecoration(
      color: Colors.white,
      borderRadius: BorderRadius.circular(eyeSize / 2),
    ),
    child: ClipOval(
      child: Container(
        color: Colors.black,
        width: eyeBallSize,
        height: eyeBallSize,
      ),
    ),
  ),
),
/ / in the right eyePositioned( top: marginTop, right: marginLR, child: AnimatedContainer( alignment: seeLeft ? Alignment.bottomLeft : Alignment.bottomRight, padding: EdgeInsets.all(eyePadding), transform: Matrix4.identity() .. translate(seeLeft ? -sideOffset :0.0,
          seeLeft ? 0.0 : eyeOffset, 0),
    duration: Duration(seconds: 1),
    curve: Curves.fastOutSlowIn,
    width: eyeSize,
    height: eyeSize,
    decoration: BoxDecoration(
      color: Colors.white,
      borderRadius: BorderRadius.circular(eyeSize / 2),
    ),
    child: ClipOval(
      child: Container(
        color: Colors.black,
        width: eyeBallSize,
        height: eyeBallSize,
      ),
    ),
  ),
),
Copy the code

Eye alignment is controlled using the AnimatedContainer alignment parameter, and eye alignment is implemented using the pan Matrix4 alignment parameter:

Matrix4.identity() .. translate(seeLeft ? -sideOffset :0.0, seeLeft ? 0.0 : eyeOffset, 0),
Copy the code

To create the smiley face, use ClipPath, draw two arcs, and then move it to the same size as your eyes. The AnimatedContainer code is as follows:

// A grinning mouth
Positioned(
  bottom: 10,
  height: 40,
  left: 0,
  child: AnimatedContainer(
    alignment:
        seeLeft ? Alignment.bottomLeft : Alignment.bottomRight,
    padding: EdgeInsets.all(4.0), transform: Matrix4.identity() .. translate(seeLeft ?25.0 : 35.0.0.0),
    duration: Duration(seconds: 1),
    curve: Curves.fastOutSlowIn,
    child: ClipPath(
      clipper: SmileClipPath(),
      child: Container(
        width: 60,
        height: 40,
        color: Colors.yellow,
      ),
    ),
  ),
),
Copy the code

SmileClipPath clipping class SmileClipPath code is as follows:

class SmileClipPath extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    returnPath() .. moveTo(0.0)
      ..arcToPoint(
        Offset(size.width, 0),
        radius: Radius.circular(size.width * 0.55),
        clockwise: false,).. arcToPoint( Offset(0.0),
        radius: Radius.circular(size.width),
        clockwise: true,); }@override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
    return false; }}Copy the code

Finally, the control state variable seeLeft is triggered by a button click.

floatingActionButton: FloatingActionButton(
  child: Icon(Icons.play_arrow, color: Colors.white),
  onPressed: () {
    setState(() {
      seeLeft = !seeLeft;
    });
  },
),
Copy the code

The final running effect is as follows, the complete code has been submitted to: animation related code.

conclusion

This article introduces the use of AnimatedContainer. If you want to implement dynamic effects on a Container, you can directly use AnimatedContainer to replace it. Then, you can change the properties of the AnimatedContainer to implement transition dynamic effects. For example, the official website has a random shape, radian and color dynamic effect, which is also fun to watch.

So, guys, can you fix a computer?

I am dao Code Farmer with the same name as my wechat official account. This is a column about the introduction and practice of Flutter, providing systematic learning articles about Flutter. See the corresponding source code here: The source code of Flutter Introduction and Practical column. If you have any questions, please add me to the wechat account: island-coder. If you feel you have something to gain, please give three pairs of love as follows:

👍🏻 : a praise to encourage!

🌟 : Collect articles, easy to look back!

💬 : Comment exchange, mutual progress!