Creating an Asynchronous Loading Image Component in React Native — Part III
We add progressive and placeholder image support to our asynchronous image component in the last installment of this series.
Progressive images are low quality images that we display as a preview while we load the higher quality image from the network. Like the placeholder we’ve created before this makes our app feel faster to users and provides a higher fidelity experience than the color placeholder alone.
In the last part of this series we will add progressive image support to the placeholder and provide it with a simpler fade animation once the higher resolution image loads from the network.
Previous
Skip to the Source
Adding Progressive Support
To add a progressive image to our component we will need to add an Animated.Image and put it alongside the color placeholder we’ve defined before. Additionally we will have to change the conditions under which either the image or placeholder is shown.
When a placeholderSource is available in our props we will display the Animated.Image and when it is not we will display the color placeholder.
{(placeholderSource && !loaded) &&
<Animated.Image
source={placeholderSource}
style={[
style,
{
opacity: placeholderOpacity,
position: 'absolute',
transform: [{ scale: placeholderScale }]
}
]} />
}{(!placeholderSource && !loaded) &&
<Animated.View
style={[
style,
{
backgroundColor: placeholderColor,
opacity: placeholderOpacity,
position: 'absolute',
transform: [{ scale: placeholderScale }]
}
]} />
}
Making the Animation fit the Progressive Image
The explode animation we defined previously for the color placeholder doesn’t really work well here. If you ran the component in this state it would look something like this:
As a progressive image is generated from the image we will display we want an animation that is softer like the final demo we had above:
To get this ‘fade in’ animation we only need to change a few things in how the component is constructed and what properties the progressive image depends on. We add a condition for the image’s opacity in the state based on the availability of the placeholderSource prop:
constructor(props: Props) {
super(props)
this.state = {
loaded: false,
imageOpacity: props.placeholderSource
? new Animated.Value(1.0)
: new Animated.Value(0.0),
placeholderOpacity: new Animated.Value(1.0),
placeholderScale: new Animated.Value(1.0)
}
}
And remove the transform from the progressive image:
{(placeholderSource && !loaded) &&
<Animated.Image
source={placeholderSource}
style={[
style,
{
opacity: placeholderOpacity,
position: 'absolute'
}
]} />
}
Utilizing the Placeholder
With this in place we can use either a progressive image or static resource with our asynchronous image component like so:
//
// Progressive
//<AsyncImage
style={{
...styles
}}
placeholderSource={{
uri: 'https://i.imgur.com/TSl1zQR.jpg'
}}
source={{
uri: 'https://i.imgur.com/R5TraVR.png'
}}
placeholderColor='#b3e5fc'/>//
// Static
//<AsyncImage
style={{
...styles
}}
placeholderSource={require('./img/yourimage.png')}
source={{
uri: 'https://i.imgur.com/R5TraVR.png'
}}
placeholderColor='#b3e5fc'/>
Thanks!
Thanks for reading! Thank you for following this series. 🚀
Please feel free to reach out via Medium or Twitter. We’d love to hear what tutorials in React Native you’d like to see. 🙂
Did you know we curate the best resources on React Native and related frameworks just for you each week? Subscribe to our weekly React Native Newsletter to get it in your inbox each week. 🙌🏻