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
This commit is contained in:
Eric Vicenti 2016-10-19 15:20:05 -07:00 committed by Facebook Github Bot
parent c2ed2ece95
commit f9779e3eb7
2 changed files with 37 additions and 4 deletions

View File

@ -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,6 +210,7 @@ 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}
@ -212,9 +218,27 @@ class NavigationCardStack extends React.Component<DefaultProps, Props, void> {
);
}
_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;

View File

@ -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,
};