Permalink
Browse files

Enable native animations when possible

Summary:
The `position` animated value is used for scale, translateX, and tranlateY
animations, which are all supported by NativeAnimatedHelper. Unfortunately,
native animations are incompatible with JS driven animations, which the
`enableGestures` flag enables.

This diff therefore conditionally enables native animations based on the native
module's precense, and the state of `enableGestures`.

Ideally the animations would be refactored so that they could fully leverage
native animations, as they are far superior for navigational components.

Reviewed By: oyvindkinsey

Differential Revision: D4020977

fbshipit-source-id: 8e1d015c4d41fee103469f6f9ffa02ff4f1f5517
  • Loading branch information...
1 parent c2ed2ec commit f9779e3eb79d50ddf0d80bbc0d047914d9e0c10c @ericvicenti ericvicenti committed with Facebook Github Bot Oct 19, 2016
@@ -32,11 +32,12 @@
*/
'use strict';
-const NavigationTransitioner = require('NavigationTransitioner');
+const NativeAnimatedModule = require('NativeModules').NativeAnimatedModule;
const NavigationCard = require('NavigationCard');
-const NavigationCardStackStyleInterpolator = require('NavigationCardStackStyleInterpolator');
const NavigationCardStackPanResponder = require('NavigationCardStackPanResponder');
+const NavigationCardStackStyleInterpolator = require('NavigationCardStackStyleInterpolator');
const NavigationPropTypes = require('NavigationPropTypes');
+const NavigationTransitioner = require('NavigationTransitioner');
const React = require('React');
const StyleSheet = require('StyleSheet');
const View = require('View');
@@ -145,7 +146,11 @@ class NavigationCardStack extends React.Component<DefaultProps, Props, void> {
gestureResponseDistance: PropTypes.number,
/**
- * Enable gestures. Default value is true
+ * Enable gestures. Default value is true.
+ *
+ * When disabled, transition animations will be handled natively, which
+ * improves performance of the animation. In future iterations, gestures
+ * will also work with native-driven animation.
*/
enableGestures: PropTypes.bool,
@@ -205,16 +210,35 @@ class NavigationCardStack extends React.Component<DefaultProps, Props, void> {
render(): React.Element<any> {
return (
<NavigationTransitioner
+ configureTransition={this._configureTransition}
navigationState={this.props.navigationState}
render={this._render}
style={this.props.style}
/>
);
}
+ _configureTransition = () => {
+ const isVertical = this.props.direction === 'vertical';
+ const animationConfig = {};
+ if (
+ !!NativeAnimatedModule
+
+ // Gestures do not work with the current iteration of native animation
+ // driving. When gestures are disabled, we can drive natively.
+ && !this.props.enableGestures
+
+ // Native animation support also depends on the transforms used:
+ && NavigationCardStackStyleInterpolator.canUseNativeDriver(isVertical)
+ ) {
+ animationConfig.useNativeDriver = true;
+ }
+ return animationConfig;
+ }
+
_render(props: NavigationTransitionProps): React.Element<any> {
const {
- renderHeader
+ renderHeader,
} = this.props;
const header = renderHeader ? <View>{renderHeader(props)}</View> : null;
@@ -161,7 +161,16 @@ function forVertical(props: NavigationSceneRendererProps): Object {
};
}
+function canUseNativeDriver(isVertical: boolean): boolean {
+ // The native driver can be enabled for this interpolator because the scale,
+ // translateX, and translateY transforms are supported with the native
+ // animation driver.
+
+ return true;
+}
+
module.exports = {
forHorizontal,
forVertical,
+ canUseNativeDriver,
};

2 comments on commit f9779e3

@mkonicek
Contributor

Nice! 👍

@stereodenis
Contributor

🎉

Please sign in to comment.