We'll start by importing animated and touchable without feedback from React Native.
Now, let's take a look at how we're going to build our heart. A heart will be a singular wrapping view, with two pieces that will make up each side of the heart. There's a generic heart shape and then a left and a right heart piece.
The heart shape has a width of 30 and height of 45 that's positioned absolutely. It has a border top left radius, and border top right radius, which means the top will be rounded, but the bottom will be straight.
Then, for the left piece or the right piece, we either rotate it 45 degrees negatively or positively, which will cause them to sit on top of each other. To prove this, we'll add a background color to our left heart, and now, when we refresh, we can see that one piece of our heart exists.
Now, if I add the background color of black to the other and refresh, you can see now that the two pieces are sitting on top of each other.
Let's remove our background color and take a look at how we're going to create a heart that looks empty.
Because of how we've built this heart, we can't use the normal border style to create an outline. Instead, what we'll do is we'll create another heart that has two pieces of heart that are white, and we'll absolute position it, and scale it to 09. You can see that here in our styles, that we've scaled it to 09, and then we set the background color to white.
Then we'll render it on top of and inside of our current heart, and that way, it will look like there's a border. We'll render that, I'll remove this fill style, and when we refresh, you can see that there's a gray heart on the outside with a 09 scaled white heart on the inside.
Now that we have our heart rendering, we can go back to our index and start setting up our bouncy heart. The first thing we'll do is set up our state.
We'll create this.state and it'll equal an object. We'll add a liked key to keep track of whether or not we've pressed the button or not. We'll add a scale animation, and we'll say, a new animated value that we default to zero. Then we'll create an array of animations. We'll all default them to zero, and these will be the animations for the heart.
We'll copy and paste this and we'll create six different hearts.
Now, we'll set up a trigger like function that will be called when our button is pressed, and we'll also bind it to this in our constructor. Inside of our trigger like, we'll call this.setState and toggle our like by saying not this.state.liked.
Now, we'll scroll down to our heart and we'll wrap it in a touchable without feedback. As well, we'll add an animated.view, we'll put this inside of the animated view. We'll add our onPress, which we'll call this.triggerLike. Also, to our heart want filled equals this.state.liked.
Now, if you refresh your emulator, and we press the heart, we can trigger it being filled in.
We want to add feedback to our heart, so we'll say constBouncyHeart equals this.state.scale.interpolate, which is a function that takes an object, and we'll say input range is 012, and our output range is 1.81.
Now, we'll set up our button style, so say constHeartButtonStyle equals an object, and we'll say transform, which is an array, we'll add the scale transform, and we'll add in our bouncy heart. We'll apply that heart button style to our animated view, so we say style equals HeartButtonStyle.
Now, up in our trigger like, we'll call animated.spring, and we'll do it on our this.state.scale animated value. We'll take a configuration object, and we'll say to value of two, with a friction of three. Then we'll call start on our spring animation.
We'll add a callback function to our start call, which we call when the animation is complete, and we'll say this.state.scale.setValue, and we'll set it back to zero, so that we can respring the animation if the button is pressed.
Now, if you refresh your emulator, we press our heart, we can see that it springs. Then when we unpress it, it springs again.