Build an Animated Floating Action Button in React Native with Springy Menu

Jason Brown
InstructorJason Brown
Share this video with your friends

Social Share Links

Send Tweet

In this lesson we'll create an animated floating action button. This technique can be used as a quick action menu to hide additional options. When pressed we'll use Animated.parallel to execute our stagger menu options and execute our Animated.timing animation which will rotate our button and change our background color with interpolate. We use Animated.stagger to create a delay of our buttons sliding up. Animated.spring will give our buttons a spring effect as they shoot upwards.

[00:00] We'll start by importing animated, and touchable opacity form React Native. Next, we'll set up our state and say this.state = object. We'll say animate, which I will assign an animated value, default is "0We'll create fabs, which will be an array. We'll add three animated values that all default to "0We will also say this.open = false to keep track of whether the menus open or not, and then, we will create a handlepress function. When the button is pressed, we will bind that to this in the constructor.

[00:40] Now, we will go set up some styles in our stylesheet. Position style, will be an object, position, "absolute." We will position our button right, "45," and bottom, "45."

[00:53] We will set up a fab style and position, "absolute," bottom, "0and right, "0We'll set up a button which will say, width, "80," height, "80," border-radius, "40," align-items, "center," and justify-content, "center."

[01:28] Finally, we will add a fly out style. Background color is, "9439ff" and "+" on the inside of our button. Say font-weight, "bold," font-size, "30," and a color of "00768f." Now, we will go set up our main button. We will say touchable-opacity with an onpress that calls this.handlepress.

[02:02] Instead of that. We will create an amimated.view, with a style = styles.button to start. Inside of here, we will do our text "+" and style=styles.+. We need to wrap this in a view. Give it style=styles.position, it will be positioning all our buttons in the bottom right-hand corner.

[02:35] We will render our fabs. We will say this.state.fabs.map, which will take a function that will pass it on our animation and an index, and we will return a touchable-opacity. We will add a key of "i" because we are mapping over something.

[03:03] Style equals an array of styles.button, styles.fab. On press, we will call this .handlepress. We will additional add styles.flyout style to our fab button.

[03:21] When the button is pressed, a few animations were triggered that we need to interpolate. The first will be the background animation. We will say constbackgroundinterpolate = this.state.animate.interpolate, which is a function which takes an object. We will say input range is 0to 1. The output range will be colors, we will say, RGB: 9034153. We will interpolate that to RGB: 361163.

[03:56] I will set up the style, constbackgroundstyle = background-color, and we will do our background-interpolate. We will apply that to our wrapping view, but first, we need to change it to an animated view. We will switch this to an array, and then pass in our background style.

[04:24] He also need to set up our interpolation for our button for the color and the rotate. I will say constbuttoncolorinterpolate = this.state.animate.interpolate, they're our configuration object.

[04:37] We will say input range of 01, and output range colors RGB: 24214255. It will animate to white, RGB: 25525555. We will also do our rotate constbuttonrotate = this.state.animate.interpolate. Our input range again will be 01, and our output range will be 0degrees to 135 degrees.

[05:14] We will set up our button style, say constbuttonstyle = background-color, which I will be our button color interpolate. We will say transform, which is an array. We will do a rotate and pass in our button rotate. We'll take this style and apply it to our button. When we refresh, we will see that our button is showing up and the background color is purple.

[05:47] We will go and create a helper function to translate our fab button. We will say constgettransformstyle, is equal to a function that takes an animation and returns an object with a transform key on it which is an array.

[06:02] We will use translate Y and we will put in our animation. We will and get transform style, we will go to our fabs, and we will get our addtransformstyle with the animation that we are looping over. We'll setup our animation.

[06:19] We will go to handlepress, and we will say cost to value = this.open. If it is open, we will translate back to zero or we'll translate to one. Say constfflyouts = this.state.fabs.map, which will be our value "i", which we will return animated.spring. We will pass in our value. Our 2value will be I + 1 * -90 * 2value, and the friction will be "5."

[06:55] Now, use animated.parallel, which will trigger these two animations at the same time, which takes in an array. Say, animated.timing. Say this.state.animate 2value over duration of 300 milliseconds.

[07:09] Then, we'll do animated.stagger of 30 milliseconds, and do our fab flyouts. We will call start on this. We will toggle this.open to not this.open.

[07:31] When we refresh on our emulator, and we press our button. You see that it rotates and our buttons fly out and whichever one we press, will cause a springing animation back behind our fab button.