1. We design the AddButton, the MinusButton, the Counter

2. a) Rotate, Scale Down and TranslateX (move on the x-axis) the Add Button

2. b) Scale Down and TranslateX the Minus Button

3. Animate and increase/decrease counter value

4. Shake on 0 to show the minimum value allowed. (Bonus)

That’s all

Let’s begin…

Step 1:

- Design the AddButton

- Design the MinusButton, the Counter and the CompleteComponent that holds the buttons and the counter together

Step 2:

This is where we actually start moving the wheels and animating these components and we would use the Animated API from react native to accomplish all our needs.

a) Rotate, Scale Down and TranslateX the Add Button

Let’s break it down;

When we click on the AddButton ; it rotates, reduces in its size and moves on the x-axis a couple of pixels. We would create that effect using interpolation.

NOTE: For the sake of reusability, I pass the animationValue as a prop to the AddButton, MinusButton

b) Scale Down and TranslateX the Minus Button

This takes place at the same time as the Step 2(a) above so we would tie both this step and the previously written animation interpolations to the same animated value

Step 3: Animate and increase/decrease counter value

With these animations

- We are able to make the buttons move

// this is the function called when the AddButton is pressed

// Basically, if its not "open" yet, we use timing to move the animationValue from 0 to 1 over 500ms

// Else, we call incrementNumber() below

animateCircle = () => {

if (this.state.open) {

this.incrementNumber();

} else {

Animated.timing(this.state.animationValue, {

toValue: 1,

duration: 500

}).start(() => this.setState({ open: true }));

}

};

- We want to animate the numbers increasing and decreasing

We create a new animated value called counterAnimation that we use to animate the counter value. So when animateCounterAnimation is called, we animate the counterAnimation value from 0 to 1 over 250ms and when the animation is over, we reset counterAnimation to 0

animateCounterAnimation = () => {

Animated.timing(this.state.counterAnimation, {

toValue: 1,

duration: 250

}).start(() => this.state.counterAnimation.setValue(0));

};

We then have to connect the counterAnimation value to our transform styles. We create that effect by scaling the size of the counter value up and bringing it back down

Take a look…

const textStyle = this.props.counterAnimation.interpolate({

inputRange: [0, 0.5, 1],

outputRange: [1, 1.5, 1]

});



const textStyleTransform = {

transform: [{ scale: textStyle }]

};

Step 4: Shake on 0 to show the minimum value allowed (Bonus)

We set up a new animated value called shakeMotion and when the counter value gets to 0, if you press the Minus Button, it produces the shake animation to indicate that it can’t go lower than 0. Here is how to implement that

// Start the shakeMotionAnimation

shakeMotionAnimation = () => {

Animated.timing(this.state.shakeMotion, {

toValue: 1,

duration: 250

}).start(() => this.state.shakeMotion.setValue(0));

};



// Interpolate on the shakeMotion animated value

const shakeMotionTransform = {

transform: [

{

translateX: this.props.shakeMotion.interpolate({

inputRange: [0, 0.08, 0.25, 0.41, 0.58, 0.75, 0.92, 1],

outputRange: [0, -10, 10, -10, 10, -5, 5, 0]

})

}

]

};



// uses the shakeMotionTransform if the counter value is less than 0

const conditionalStyle = () =>

this.props.counter > 0 ? textStyleTransform : shakeMotionTransform;

Don’t forget to actually place the conditionalStyle() in the style object of your Animated.Text component

Here is the complete Gist

I would recommend you clone the repo onto your machine and play with it. That’s usually the best way to learn.

Hopefully, you learnt something reading this article.

Cheers