Playing with React-Native animations and images[PART-1]

Shubhnik Singh Mann
4 min readSep 17, 2017

--

Like to dive straight into what’s going under the hood? Here it is 👇

What we will be creating.

INSPIRATION:

I was working on a project for which I needed some image animations, I looked out for the solutions and there were overwhelming number of good solutions out there but they had far more features then I needed. I was set to try my own 100% javascript animation thing and this would also help me learn a thing or two.I am adding more functionality then what I created in the project as a challenge and it will be fun.

OVERVIEW:

I have chunked the whole work(ongoing) in different parts, this is PART-1, in this part I will be creating the main animation effect that will scale and translate the image to the top. For this animation, React-Native's Animated API will be used.

Let’s get our hands dirty with the code:

First we need to display some images on the screen. I have assembled the images in different weird positions to verify if the animations are following the proper path. I will wrap the images in TouchableOpacity.When we press it than the image will animate according to its position.

Here, the data array is used to display the images on the screen. Once the image is clicked, following things happen:

  1. When the image(wrapped in TouchableOpacity) is pressed, the callback is called with an synthetic touch event object. We are interested in the nativeEvent object contained in it. And specifically in locationX(The X position of the touch, relative to the element), locationY(The Y position of the touch, relative to the element), pageX(The X position of the touch, relative to the root element), pageY(The X position of the touch, relative to the root element) . We are extracting these 4 values from the nativeEvent object using Javascript destructuring. We then calculate the x, y coordinates of the top left corner of the image relative to the screen.
const topLeftX = pageX - locationX    
const topLeftY = pageY - locationY

2. The state variable showLargeImage is set to true. This will render a View with absolute position and covering the whole screen. We will pass the position coordinates of the selected image to the rendered View as props. Using these position coordinates we will render a copy of the selected image in this View at the same position like that of the selected image, thus overlapping it. So basically we will animate the newly rendered image instead of the original.Here is what we will get now:

3. Now we will animate the new image as soon as it’s rendered. We will add the animation in the componentDidMount(). We will be using Animated.parallel(), to perform scale and translate parallely.

This animation will bring the image to life like this 👇

It’s clearly visible that there are two images, one being animated and other one beneath the the top View. We have to hide the image beneath the animated image to create a feel that we are animating it only and not an another image. That’s quite an easy thing, we just have to hide the selected image once the top View (black background) gets rendered. We need to replace this line in https://gist.github.com/shubhnik/10d2da6881b1824dd602e045e6086b98#file-imageview-js-L33 with this code

<Image source={{uri:source}} style={{flex:1, opacity:this.state.selectedIndex == index ? 0 : 1}}/>

4. Now the final task is to animate the image back to its initial position. For this we will do another parallel animation that will animate the scale and translation back to their values initialised in the state. Once the image gets transformed to the initial size and position, we will hide the foremost absolute positioned View . Finally we will get this animation 👇

Future Challenges:

  1. Creating a simple image slider.(Part 2).
  2. Using gestures with images.(Part 3)

I try to keep this article as concise as possible, all the code is here 👇

See you soon with PART-2, Happy Reacting, keep your code and environment clean and green!! 😄

--

--