Creating 3D sphere component with React Native and THREE

Using ‘expo-three’ module, you can display 3D objects with React Native

Bi Yoo
4 min readNov 16, 2017

What we will be building

We are going to create a 3D sphere, and …

Feel free to change the map image

also make it follow your finger tip!

Gesture enabled using PanResponder

What you will need

TL;DR

If you just would like to see the demo and play with the code,

The key here is to use ‘expo-three’ package to create a WebGL wrapper for THREE. For people who wanted to use it in production, here are some drawbacks I discovered. So use it with caution!

  • ‘expo-three’ is under active development. It is possible that it might get removed just like createTHREEViewClass wrapper.
  • Shades(shadow) and Lighting were not working at the time of writing. However, mapping (texture from image) was working fine.
  • Wrapping the component with Animated.View seemed to work OK, but some animations were not working properly.

Making a sphere

This is pretty simple. First, on your create-react-native-app, npm install --save the packages, three and expo-three .

Next, import Expo , Three , and ExpoTHREE . Your import statements should look like this,

Now, we need to make use out of them. We can write,

That Expo.GLView is a component that acts as an OpenGL render target. Besides onContextCreate , it also takes msaaSamples , which is for iOS multi-sampling, and any props that you would normally pass into the <View> component, as you can see in the above exmple, style={{ flex:1 }} .

Next, let’s define this._onGLContextCreate .

I won’t go through what each line is doing because this is just a basic scene setting with THREE.js, which has not much to do with React Native. You can find more details about THREE here.

The key is const renderer = ExpoTHREE.createRenderer({ gl }) , this is why we needed that package.

Some helpful tips I’d like to share though, when I tried to cast shadow and lighting on the object,

const light = new THREE.PointLight( 0xff0000, 1, 100 );

That line is responsible for setting the point light to the scene, but even though I set everything correctly based on the documentation, it did not work. Ambient, directional, hemisphere, etc., none of them worked.

Also, it takes color as Hex value(recommended), RGB string, HSL sting, and even color name. How to use it? You can write,

const color = new THREE.color( “aliceblue” )

and add that to either the scene if you want to change the background color, or to the mesh if you want the object to have a different color. Here we are importing an image to wrap around the sphere, so defining color is not necessary.

If everything is written correctly, you should see this,

Enabling PanResponder

First, import PanResponder class from “react-native” . We are going to import the View and Animated class as well since directly passing animated value props to <Expo.GLView> wasn’t possible.

I have already written about how to setup PanResponder in my previous blog, so I’ll skip the setup instructions. Please refer to the blog if you are not familar with that API.

The key is wrapping <Expo.GLView> with <Animated.View> like so,

We need the View wrapper to make the Animated library work.

And now that component is responsive to the gesture!

It works pretty smoothly, please try out my snack :)

Conclusion

When I was working as a graphic designer, I was always fascinated with 3D graphics, playing with Blender for hours (I got to learn some python along the way as a bonus).

For web, THREE.js is probably the De facto libraries you can use to create 3D scenes, so I wanted see if I could do that with React Native.

After some research, it turns out that the Expo’s createTHREEViewClass , the Webgl wrapper was something that I could’ve used to enable WebGL with React Native. However, it is deprecated.

There’s also WebGL binding for React called gl-react, but I wasn’t able to make it work for React-Native (Anyone?), but something I could look into.

As always, I hope this was helpful to your project, and until next,

Happy coding! :)

**Korean version of this article hasn’t been written yet**

--

--

Bi Yoo

Designer. Programmer. Lover of technology & art. 🦄