A translation of the article was prepared specifically for students of the ReactJS / React Native-Developer course.
It is difficult to imagine a mobile application in which there is no animation. On the web, animations are usually simple, if they exist at all (maximum - one page replaces another). Animations in mobile applications require a completely different attention.
CSS3 has a relatively simple API that allows you to make simple animations. But in React Native you do not have this tool. Yes, even if it was, then it would not be enough.
So, what do you need to know if you are working with React Native and you need to implement full-fledged animations?
React Native has a tool like Animated, but it looks intimidating ... at least at first.
So, there are three “groups of things” or “blocks” if you want, which you need to know about in order to work with animation.
Block 0: The Need for Change
Animations are a change from one state to another:
- Transition from “hidden” to “visible”;
- Transition from a circle to a square.
Think about what to show before and after the animation.
Think about transitions and what styles you need to change for this:
- Should the object appear with a change in transparency, or should it just “fall” from above?
- Should the circle just turn into a square, or should it become a triangle in the middle of the process?
Block 1: A visual state known as Animated.Value
From a logical point of view, any component can either be shown or hidden - these are the meanings of “true” and “false”; there is no middle ground here. As a state, a display of whether the object is shown to be either true or false.
In a good user interface, objects do not hide suddenly and also do not appear suddenly. They appear gradually, helping the user to understand the interface.
Thus, it becomes clear that a visual state can be something between a true state and a false state.
How so?
We can introduce another variable to represent a range of visual states. We need this to be a number, because no matter what logical state we have, numbers help us represent intermediate values.
this._shown = new Animated.Value(0);
While a logical state can be binary (i.e. either
true
or
false
, 1 or 0), the visual state is a floating-point number.
Block 2: Transitions known as Animated.timing
Let's say some component is hidden: this means that the logical state of its visibility parameters will be false, and the visual state will also be 0.0. But what happens when we want to show a component? The logical state should immediately become true, while the visual state should gradually pass first at 0.1, 0.2, ... and finally completely at 1.0.
To do this, we need a way to tell the visual state the transition to 1.0.
And there are such ways. In fact, there are even a few.
The easiest way is basically:
Animated.timing(this._shown, { toValue: 1, duration: 300, }).start();
Here, we say
Animated
to change
_shown
to
1.0
in the 300 ms interval.
There are other transitions and ways to organize multiple transitions, but now we can use
Animated.timing
.
Block 3: Pixels known as Animated.View
and interpolate
Our
_shown
transitions between
0.0
and
1.0
mean nothing if we cannot see them. So how do we do this?
We need to somehow use
_shown
to set the transparency of the child component.
Suppose we had this code before starting work with animations:
<View style={{ opacity: this.state.shown ? 1 : 0 }}> <SomeComponent /> </View>
We set the transparency to
0
when we hide the component and to
1
when we show it.
Can we use the available
Animated.Value
and
_shown
to animate the transition from
0
to
1
?
Style Animation
We can use any
Animated.Value
when we work with styles.
We just need to change the
View
to
Animated.View
, and now we have the following:
const opacity = this._shown;
Isn't this an article about animations? Why are there still no pictures?
One more thing: interpolation
This word sounds scary, but the idea itself is quite simple. Interpolation allows us to maintain a visual state in the framework of 0 and 1, but give the possibility of "comparison" to something else.
Say, instead of just creating an inherited component, we want our component to "drop out from above." And we can do this by placing the hidden component 40px higher and animating its movement to the desired position, when the state changes to visible.
We can “match” our values from 0 to 1 with values from -40 to 0 using the usual
interpolate
call:
const top = this._shown.interpolate({ inputRange: [0, 1], outputRange: [-40, 0], });
This will create a new
Animated.Value
, whose value will be from -40 to 0.
In other words, it will be
-40
when
_shown
is
0
,
-20
when
_shown
=
0.5
and
0
when
_shown
1.0
.
Dark secret: with interpolate
you can also change values for colors and degrees.
Findings:
- The visual state is a numerical value, it should reflect the transition from one style to another.
-
Animated.Value
allows you to reflect the numerical value of the visual state. -
Animated.timing
can be used to move Animated.Value
to another number. -
Animated.Value
can be used for styles when replacing View
with Animated.View
.
Interpolation allows you to map one
Animated.Value
range to another, for example a range from
0
to
1
to a range from
5
to
25
or even to a range between black and green.
Sources:
In this article, we became acquainted with the animation primitives in React Native and gained an understanding of the basic idea. Here you can find resources that will help you explore this topic more deeply: