Flutter Flip Card Animation With 3D Effect
By: Ishan Fernando
Tags: Flutter, Flutter Card Flip, App Development, Flutter Widget, Flutter Animation

Implementing Card Flip Animation In Flutter will not be hard as you think because of the Widgets and Classes provided by Flutter.

I will teach you how to implement Flip card animation to your next flutter project from scratch. At the end of the article, you will have beautiful 3D Flip card animation with a few lines of code

Start with basic Container

To get started first you will need some kind of Container and we will use this as our main component when Animation occur. This is a basic container with the Icon in the Middle.

Container(

color: Colors.blueAccent,

width: 200,

height: 200,

child: Icon(

Icons.ac_unit,

color: Colors.white,

size: 50,

),

)

Implement Animation to Flip Card

When implementing an animation there are two things which we need, Animation class and AnimationController class. Animation class will do the actual Animation part and the AnimationController class will help to control the animation like whether we need to do forward or backwards or more.

Of course, we need to use a stateful widget for this implementation.

First Create a new object of AnimationController and Animation class. Also, we need to track the animation status to do flip in forward and backwards. For that, you can use AnimationStatus enum.

AnimationController _animationController;

Animation _animation;

AnimationStatus _animationStatus = AnimationStatus.dismissed;



@override

void initState() {

super.initState();

_animationController =

AnimationController(vsync: this, duration: Duration(seconds: 1));

_animation = Tween(end: 1, begin: 0).animate(_animationController)

..addListener(() {

setState(() {});

})

..addStatusListener((status) {

_animationStatus = status;

});

}

For the animationController we have to provide vsync and it accept TickerProvider. That can be provided by SingleTickerProviderStateMixin. Because of that, we use SingleTickerProviderStateMixin mixin by using with keyword like below.

class _FlipCardState extends State

with SingleTickerProviderStateMixin {

Duration property will define the duration of the animation between the start and stop. For this we use Tween Animation with begin value 0 and end as 1. addStatusListener method will set the status of the animation whether is dismissed, forward, reverse or completed. Dismissed mean the animation is stop in the beginning and that will be the initial value.

Make container Clickable

You can Wrap the container inside the GestureDetector widget to make it clickable. GestureDetector onTap will trigger when you tap the container and that where we need to start our animation. In there if the Animation is dismissed mean stop in start state, you can animate a container in forward. Which mean the Tween animation value will be changed in a forward manner.

GestureDetector(

onTap: () {

if (_animationStatus == AnimationStatus.dismissed) {

_animationController.forward();

} else {

_animationController.reverse();

}

},

child: Container(

color: Colors.blueAccent,

width: 200,

height: 200,

child: Icon(

Icons.ac_unit,

color: Colors.white,

size: 50,

),

)

,

)

Things not finished yet,

Add Transform with 3d Effect

The next thing you need to do is wrap the GestureDetector inside the Transform widget. Transform widget can use to add a different transform to child widget.

For the Flip animation, you need to rotate in x-axis from the middle. So we set alignment to centre and set some Matrix to transform property. You can just set 2D transform by setting only the rotateX. but if you need 3D kind of effect you have to setEntry method. You can change these values and play around to get a different effect and I think these values fit best for my case. I am not a math person and if you are you will have a better sense of these values.

Under the hood when the animation get started the value of animation which you can access from _animation.value get change from 0 to 1. So we are setting that value by multiplying with PI. PI is equal to 180 and from the start to the end we change that value from 0 to 180 and that exactly why it rotates 180 degrees.

Transform(

alignment: FractionalOffset.center,

transform: Matrix4.identity()

..setEntry(3, 2, 0.002)

..rotateX(pi * _animation.value),

child: GestureDetector(

onTap: () {

if (_animationStatus == AnimationStatus.dismissed) {

_animationController.forward();

} else {

_animationController.reverse();

}

},

child: Container(

color: Colors.blueAccent,

width: 200,

height: 200,

child: Icon(

Icons.ac_unit,

color: Colors.white,

size: 50,

),

)

,

),

)

Now the all animation and Flip card things are working as expected. But how can we change the card when it flips.

Add different card to front and Back

You can do a small trick to make it work. When Animation is in progress we know it changes values from 0 to 1. When this value comes to 0.5, the card which will be in a 90-degree angle. In that position, we can swipe the container. So if the animation value is less than 0.5 we use blue container and if not we use the red container. pretty easy right.

_animation.value <= 0.5

? Container(

color: Colors.blueAccent,

width: 200,

height: 200,

child: Icon(

Icons.ac_unit,

color: Colors.white,

size: 50,

),

)

: Container(

color: Colors.red,

width: 200,

height: 200,

child: Icon(

Icons.ac_unit,

color: Colors.white,

size: 50,

),

),

Now this is the Full Code.

class _FlipCardState extends State

with SingleTickerProviderStateMixin {

AnimationController _animationController;

Animation _animation;

AnimationStatus _animationStatus = AnimationStatus.dismissed;



@override

void initState() {

super.initState();

_animationController =

AnimationController(vsync: this, duration: Duration(seconds: 1));

_animation = Tween(end: 1, begin: 0).animate(_animationController)

..addListener(() {

setState(() {});

})

..addStatusListener((status) {

_animationStatus = status;

});

}



@override

Widget build(BuildContext context) {

return Scaffold(

appBar: AppBar(

// Here we take the value from the MyHomePage object that was created by

// the App.build method, and use it to set our appbar title.

title: Text(widget.title),

),

body: Container(

color: Color.fromARGB(255, 27, 28, 30),

child: Center(

child: Transform(

alignment: FractionalOffset.center,

transform: Matrix4.identity()

..setEntry(3, 2, 0.002)

..rotateX(pi * _animation.value),

child: GestureDetector(

onTap: () {

if (_animationStatus == AnimationStatus.dismissed) {

_animationController.forward();

} else {

_animationController.reverse();

}

},

child: _animation.value <= 0.5

? Container(

color: Colors.blueAccent,

width: 200,

height: 200,

child: Icon(

Icons.ac_unit,

color: Colors.white,

size: 50,

),

)

: Container(

color: Colors.red,

width: 200,

height: 200,

child: Icon(

Icons.ac_unit,

color: Colors.white,

size: 50,

),

),

),

),

),

),

);

}

}

Conclusion

I hope you get an idea about how to implement Flip card animation in flutter and If you have any questions please add a comment below.

Check the Full Video Here — https://youtu.be/36qFMp_uvF0

Originally published at mightytechno