#404 Daily dose : React Native Interactibles


LOOKING FOR A MAINTAINER

We love this project, but currently we don’t have enough time to work on it. So we are looking for a maintainer. If you have enough time and knowledge and want to become one – please let us know (levv@wix.comsergeyi@wix.com)

 

Description

This is an experimental implementation of a declarative API for handling fluid user interactions with views at 60 FPS in React Native. Here are some example use-cases for views that users can interact with:

  • Swipeable card (a la Google Now) springing into place unless swiped away with enough force
  • Drawer snapping between closed and open with buttons appearing gradually as it’s being dragged
  • Collapsible header that snaps to a smaller size as the content below is being scrolled
  • Chat heads (a la Facebook Messenger) that can be dragged around but snap to corners of the screen

All of these use-cases have views that continuously interact with the user’s gestures. These interactions are normally physical in nature, having properties like springiness, friction, elasticity and damping. In order to feel natural on a touch device they need to run at 60 FPS.

Why is this challenging?

The async nature of the React Native bridge incurs an inherent performance penalty. This traditionally prevents JavaScript code from running at high framerates. One of the most noticeable challenges is animations in JavaScript, which aren’t guaranteed to run at 60 FPS.

Modern animation libraries for React Native, like Animated, tackle this challenge with a declarative approach. In order to minimize passes over the bridge, animations are only declared in JavaScript but executed by a native driver on the other side – in 60 FPS.

Fluid user interactions take this a step further than animations. Interactions require UI to continuously react to the user’s gestures. This library is designed to support complex physical interactions with ease, using a full-fledged physics engine to drive the interaction on the native side.

Why is it named interactable?

First off, we are aware that interactable isn’t a real word. The correct form is interactive but this has connotation that isn’t necessarily related to physical interactions. Similar to Animated.View, we wanted to have Interactable.View – meaning a view you can interact with. And hey, Unity did it too.

 

Installation

Requires RN 0.40 and above.

  • Install the package from npm
npm install react-native-interactable --save
  • Link the native library to your project
react-native link react-native-interactable

Note: instead of linking automatically you can also link manually according to these instructions

node_modules/react-native-interactable/ios/Interactable.xcodeproj

Manually link via Cocoa Pods (iOS)

  • Add the following to your Podfile and run pod update:
pod 'Interactable', :path => '../node_modules/react-native-interactable'

 

Example

To see the library in action you have several options:

  • Build and run the example project on your computerThe example project has 4 use-cases implemented: swipeable carddrawercollapsible header and chat heads. It’s simplistic but easy to learn from.

    Note: It’s recommended to experience it on a real device and not on a simulator. The simulator has poor performance so the framerate isn’t like the real thing.

    To run the example, clone the repo and run from the root folder:

  cd real-life-example
  yarn
  react-native run-ios
  • Install and run the demo app from the App Store/Google Play on your phoneIf you don’t want to mess with building yourself, you can play with a pre-built demo on your phone.

    Download from Apple App Store (iOS)
    Download from Google Play Store (Android)

            

  • Build and run the demo app on your computerThe demo app contains more complex demonstrations than the example project. They’re harder to learn from, but they’re cool to watch. More info about the UX inspirations for the demo app.

    Note: It’s recommended to experience it on a real device and not on a simulator. The simulator has poor performance so the framerate isn’t like the real thing.
    To run the demo app, clone the repo and run from the root folder:

cd real-life-example
npm install
react-native run-ios

 

Implementation Details

Originally, the iOS implementation relied on UIKit Dynamics – a powerful native animation engine for physical interactions. A physics engine is required in order to make the interaction life-like. Consider the action of tossing a view connected via a spring to a snap point. A simple native spring animation will not be enough to take the initial velocity vector into account.

At some point, UIKit Dynamics was dropped in favor of a home-brewed physics implementation in order to provide more control over the behaviors. This also paved the way for the Android port since there’s no parallel to UIKit Dynamics for Android. The home-brewed physics engine was straightforward to port from Objective-C to Java and is now part of this library.

Contributing

If you are interested in the project, have feedback or want to contribute don’t hesitate to contact me. I’m particularly interested in ideas on how to expand the declarative API for more use-cases and suggestions on how to improve performance. PRs are always welcome.

License

MIT

Advertisements