Tenesse
Tenesse

Reputation: 145

Preload, cache gif Images to avoid flickering in React Native

I am trying to create an animation in react native where a character do some push ups. Going up and down is done at the moment I want.

So I separated a gif animation in 2 gifs, without repetition. One to make him going up and the other one to make him going down.. These images are locally stored

The problem is that there is a flickering when the gif change.

I tried react-fast-image, but the gif animation is too slow and the gif is looped automatically. I tried to put a transition image in the meatime images are switching but still a flicker behaviour. The image onLoadEnd callback seems to be called too early, before the image actually ends up to load.

here how I switch the images

if (up.includes(this.props.timer))
                this.setState({ currentGif: upGif, cacheImage: downPng })
if (down.includes(this.props.timer))
          this.setState({ currentGif: downGif, cacheImage: upPng }) 

Here is the render:

render() {
    return (
        <View
            style={{ position: 'absolute', bottom: 70 }}
        >
            <Image 
                source={this.state.cacheImage}
                style={{ width: 400, height: 330, position: 'relative', bottom: 70 }}
                fadeDuration={0}
            />
            <Image
                source={this.state.currentGif}
                style={{ width: 400, height: 330, position: 'absolute', bottom: 70 }}
                fadeDuration={0}
                onLoadEnd={() => {this.setState({cacheImage: null})}}  // the Image should be loaded so I can hide the cache Image, but it desapear before the gif is loaded
            />
        </View>
    )
}

Upvotes: 2

Views: 1675

Answers (1)

Artal
Artal

Reputation: 9143

You can use the Image.getSize API.

To get the size, RN downloads and caches the image. It's stated in the docs that this method can be used for preloading images. They also mention that a more explicit API will be provided in the future, so you can use this for now and switch to a better API when it's available.

Upvotes: 1

Related Questions