I’m creating a React Native component that shows as a placeholder for live data (in other words: loading boxes) and changing it’s color to indicate that stuff is loading..
Here’s how you go about doing that:
Animated
value, and give it the initial value.1// set a value to be animated
2const currentColor = new Animated.Value(0)
.interpolate()
on the animated value you just created. Interpolate will take an array of input values inputRange
, and another one of output values outputRange
, and then map the values to each other. You can either do this interpolation inside your Animate
function, or you can define it separately, which i did, like so:1// interpolate color value
2const changeColor = currentColor.interpolate({
3 inputRange: [0, 1, 2],
4 outputRange: ['gainsboro', 'whitesmoke', 'gainsboro']
5})
What the code above would mean is that at my initial value of 0
, the color would be gainsboro
and when i move to 1
it’ll change to whitesmoke
. Then i’m changing it back to gainsboro
at 2
(because i want to loop the color change). If you set the toValue
as 1
in the above code, it’ll only transition till whitesmoke
and ignore what comes afterwards.
1// define the looping animation
2const animateColor = ()=> {
3 Animated.loop(
4 Animated.sequence([
5 Animated.timing(currentColor, {
6 toValue: 2, // the value in interpolated output range that you want to go to
7 duration: 2000 // ms
8 }),
9 ])
10 ).start()
11 }
In my animation, i’ll loop
a sequence
of changes. Inside the sequence, i’m animating between different values (mapped to my colors above). Using the .timing()
function, i’m changing the value i want to animate (defined as currentColor
) over a period of 2000ms (i.e. 2sec) and going from the initial value of 0
to the interpolated value of 2
(using toValue
).
The above two steps can also be combined like so:
animateColor
. I’ll then pass that function to the useEffect()
hook (i.e. the equivalent of componentDidMount()
)1export default function App() {
2 useEffect(() => {
3 // start the animation to change background color
4 animateColor()
5 })
6 return (
7 // component goes here..
8 );
9}
In your component, when you’re setting styles, you’ll use the Animated.Value
you defined in order to change color, in our case backgroundColor: changeColor
Here’s the full code:
1import React, { useEffect } from 'react'
2import { Animated, StyleSheet, View } from 'react-native'
3
4// set a value to be animated
5const currentColor = new Animated.Value(0)
6
7// interpolate color value
8const changeColor = currentColor.interpolate({
9 inputRange: [0, 1, 2], // the values that the animation will transition from
10 outputRange: ['gainsboro', 'whitesmoke', 'gainsboro'] // values that are animating
11})
12
13// define the looping animation
14const animateColor = ()=> {
15 Animated.loop(
16 Animated.sequence([
17 Animated.timing(currentColor, {
18 toValue: 2, // the value in interpolated output range that you want to go to
19 duration: 2000 // ms
20 }),
21 ])
22 ).start()
23 }
24
25export default function App() {
26 useEffect(() => {
27 // start the animation to change background color
28 animateColor()
29 })
30 return (
31 <View style={styles.container}>
32 <Animated.View style={{ height: 150, width: 150, backgroundColor: changeColor, borderRadius: 8, margin: 8}}></Animated.View>
33 </View>
34 );
35}
36
37const styles = StyleSheet.create({
38 container: {
39 flex: 1,
40 backgroundColor: '#fff',
41 alignItems: 'center',
42 justifyContent: 'center',
43 },
44});
rgba
values, you may have to look into hex-to-rgba
Stylesheet
properties in React Native are pretty limited. You can find a list of all supported properties herestyled-components
?Can i use SVGs as placeholder? Sure. you’d have to use another library (e.g. react-native-svg
)to add SVG support to React Native, and then you’d have to create a custom animated components using createAnimatedComponent to be able to animate an <Svg>
component
See example here
1import { Path } from "react-native-svg";
2const AnimatedPath = Animated.createAnimatedComponent(Path);
See Animating SVG in React Native