• Make 3D Flip animation in Flutter
  • Author: Hung HD
  • The Nuggets translation Project
  • Permanent link to this article: github.com/xitu/gold-m…
  • Translator: ALVINYEH
  • Proofreader: GeniusQ1981

Learn Flutter from UI challenges

As a follow-up to my first article, I’m going to start a new challenge. This will be a little more complicated than the previous one (shimmer). I call this flip animation:

That’s a challenge enough, isn’t it? Yes, we’re going to make an animation that looks a bit like 3D.

How to do?

At first glance, the idea is simple: We have a bunch of panels, each split in half, and each half can rotate around the X-axis to display the next panel.

How do you do that in code? I broke it down into two small tasks:

  • Split the panel in half
  • Rotate the panel halfway around the X-axis

So how does Flutter help us? Looking at the Flutter documentation, I found two components that were perfect for the task: ClipRect and Transform.

implementation

  • Split the panel in half:

The ClipRect component has a clipper parameter that defines the size and position of the clipping rectangle, but the documentation suggests another way to use ClipRect: use it with Align:

class FlipWidget extends StatelessWidget {
  Widget child;

  FlipWidget({Key key, this.child}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    returnColumn( mainAxisSize: MainAxisSize.min, children: [ ClipRect( child: Align( alignment: Alignment. TopCenter, heightFactor: 0.5, child: child,)), Padding(Padding: EdgeInsets. Only (top: Bottom factor: 0.5),), (child: Align(Align: bottomCenter, heightFactor: 0.5, child: child,),]; }}Copy the code

Try it:

That’s it. In addition, child lets us design the content of the animation (whether it be text or graphics) as we wish.

  • Rotate the panel halfway around the X-axis

The Transform component has a Transform parameter of type Matrix4 that defines the transformation type to be applied. Matrix4 exposes a factory constructor named rotationX() that looks like we need to use, so let’s try it on the top half of the panel:

@override
Widget build(BuildContext context) {
   returnColumn( mainAxisSize: MainAxisSize.min, children: [ Transform( transform: Matrix4.rotationX(pi / 4), alignment: BottomCenter, child: ClipRect(Child: Align(Alignment: Align. TopCenter, heightFactor: 0.5, child: child, )), ), ... ] ,); }Copy the code

Try it:

What !!!! It looks like scaling, doesn’t it?

What’s going on? Answering this question was the hardest part of the task. I looked back at Flutter documentation, sample code, articles… Until I found this article. Changing the values of row 3 and column 2 of a Matrix4 matrix changes its perspective and gives a 3D effect to the transformation:

. Transform( transform: Matrix4.identity().. SetEntry (3, 2, 0.006).. rotateX(pi / 4), alignment: Alignment.bottomCenter, child: ClipRect( child: Align( alignment: Alignment. TopCenter, heightFactor: 0.5, Child: child,);Copy the code

Try again:

Good. But how about trying the magic number 0.006? To be honest, I don’t know how to calculate it exactly, just try to pick some values that I feel good about.

All that is left is to animate our component. This is a little tricky. In fact, every panel has two sides (front and back), but implementing it in code is unwise because only one side can be seen at a time. I suppose you want to create a panel to flip up animation, the animation can be decomposed into a continuous two stages (order), the first is the flip up half part to make the animation shows the lower part of the next panel, and then hide the lower part of the current panel, the second is the flip top half in the same direction, to show the first half of the half, While hiding the current top half:

The code for this animation implementation is long and not a good fit here. You can find it at the link at the bottom of this article. This is our final result:

That’s great. We just completed another UI challenge with Flutter. Practice makes perfect. I will continue to look for new challenges, solve them with Flutter and share the results with you. Thanks for reading.

P/S: There was a slight problem with the perspective transform (which caused the transformed image to skew). I used a very small value in rotateX() instead of zero to temporarily fix the problem.

The complete code: gist.github.com/hnvn/f1094f…

I have published my code in a package called Flip_panel

If you find any mistakes in your translation or other areas that need to be improved, you are welcome to the Nuggets Translation Program to revise and PR your translation, and you can also get the corresponding reward points. The permanent link to this article at the beginning of this article is the MarkDown link to this article on GitHub.


The Nuggets Translation Project is a community that translates quality Internet technical articles from English sharing articles on nuggets. The content covers Android, iOS, front-end, back-end, blockchain, products, design, artificial intelligence and other fields. If you want to see more high-quality translation, please continue to pay attention to the Translation plan of Digging Gold, the official Weibo, Zhihu column.