mirror of
https://github.com/status-im/react-native.git
synced 2025-01-18 13:31:18 +00:00
Support animation and gesture for Pager.
Summary: We need to support animation and gesture for Pager. Reviewed By: ericvicenti Differential Revision: D3066596 fb-gh-sync-id: 1c1a3d34b4298b4b0dd158f817057ae22dea72f4 shipit-source-id: 1c1a3d34b4298b4b0dd158f817057ae22dea72f4
This commit is contained in:
parent
3c488afb0f
commit
4f8668b110
Libraries
CustomComponents/NavigationExperimental
NavigationCard.jsNavigationCardStack.jsNavigationCardStackPanResponder.jsNavigationCardStackStyleInterpolator.jsNavigationLegacyNavigator.jsNavigationPagerPanResponder.jsNavigationPagerStyleInterpolator.js
NavigationExperimental
@ -33,9 +33,11 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const Animated = require('Animated');
|
const Animated = require('Animated');
|
||||||
|
const NavigationCardStackPanResponder = require('NavigationCardStackPanResponder');
|
||||||
const NavigationCardStackStyleInterpolator = require('NavigationCardStackStyleInterpolator');
|
const NavigationCardStackStyleInterpolator = require('NavigationCardStackStyleInterpolator');
|
||||||
const NavigationContainer = require('NavigationContainer');
|
const NavigationContainer = require('NavigationContainer');
|
||||||
const NavigationLinearPanResponder = require('NavigationLinearPanResponder');
|
const NavigationPagerPanResponder = require('NavigationPagerPanResponder');
|
||||||
|
const NavigationPagerStyleInterpolator = require('NavigationPagerStyleInterpolator');
|
||||||
const NavigationPropTypes = require('NavigationPropTypes');
|
const NavigationPropTypes = require('NavigationPropTypes');
|
||||||
const React = require('react-native');
|
const React = require('react-native');
|
||||||
const ReactComponentWithPureRenderMixin = require('ReactComponentWithPureRenderMixin');
|
const ReactComponentWithPureRenderMixin = require('ReactComponentWithPureRenderMixin');
|
||||||
@ -91,7 +93,7 @@ class NavigationCard extends React.Component<any, Props, any> {
|
|||||||
}
|
}
|
||||||
if (panHandlers === undefined) {
|
if (panHandlers === undefined) {
|
||||||
// fall back to default pan handlers.
|
// fall back to default pan handlers.
|
||||||
panHandlers = NavigationLinearPanResponder.forHorizontal(props);
|
panHandlers = NavigationCardStackPanResponder.forHorizontal(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -119,4 +121,13 @@ const styles = StyleSheet.create({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = NavigationContainer.create(NavigationCard);
|
|
||||||
|
const NavigationCardContainer = NavigationContainer.create(NavigationCard);
|
||||||
|
|
||||||
|
// Export these buil-in interaction modules.
|
||||||
|
NavigationCardContainer.CardStackPanResponder = NavigationCardStackPanResponder;
|
||||||
|
NavigationCardContainer.CardStackStyleInterpolator = NavigationCardStackStyleInterpolator;
|
||||||
|
NavigationCardContainer.PagerPanResponder = NavigationPagerPanResponder;
|
||||||
|
NavigationCardContainer.PagerStyleInterpolator = NavigationPagerStyleInterpolator;
|
||||||
|
|
||||||
|
module.exports = NavigationCardContainer;
|
||||||
|
@ -37,7 +37,7 @@ const NavigationAnimatedView = require('NavigationAnimatedView');
|
|||||||
const NavigationCard = require('NavigationCard');
|
const NavigationCard = require('NavigationCard');
|
||||||
const NavigationCardStackStyleInterpolator = require('NavigationCardStackStyleInterpolator');
|
const NavigationCardStackStyleInterpolator = require('NavigationCardStackStyleInterpolator');
|
||||||
const NavigationContainer = require('NavigationContainer');
|
const NavigationContainer = require('NavigationContainer');
|
||||||
const NavigationLinearPanResponder = require('NavigationLinearPanResponder');
|
const NavigationCardStackPanResponder = require('NavigationCardStackPanResponder');
|
||||||
const NavigationPropTypes = require('NavigationPropTypes');
|
const NavigationPropTypes = require('NavigationPropTypes');
|
||||||
const React = require('React');
|
const React = require('React');
|
||||||
const ReactComponentWithPureRenderMixin = require('ReactComponentWithPureRenderMixin');
|
const ReactComponentWithPureRenderMixin = require('ReactComponentWithPureRenderMixin');
|
||||||
@ -46,7 +46,7 @@ const StyleSheet = require('StyleSheet');
|
|||||||
const emptyFunction = require('fbjs/lib/emptyFunction');
|
const emptyFunction = require('fbjs/lib/emptyFunction');
|
||||||
|
|
||||||
const {PropTypes} = React;
|
const {PropTypes} = React;
|
||||||
const {Directions} = NavigationLinearPanResponder;
|
const {Directions} = NavigationCardStackPanResponder;
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
NavigationAnimatedValue,
|
NavigationAnimatedValue,
|
||||||
@ -58,7 +58,7 @@ import type {
|
|||||||
|
|
||||||
import type {
|
import type {
|
||||||
NavigationGestureDirection,
|
NavigationGestureDirection,
|
||||||
} from 'NavigationLinearPanResponder';
|
} from 'NavigationCardStackPanResponder';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
direction: NavigationGestureDirection,
|
direction: NavigationGestureDirection,
|
||||||
@ -80,7 +80,18 @@ const defaultProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A controlled navigation view that renders a list of cards.
|
* A controlled navigation view that renders a stack of cards.
|
||||||
|
*
|
||||||
|
* +------------+
|
||||||
|
* +-+ |
|
||||||
|
* +-+ | |
|
||||||
|
* | | | |
|
||||||
|
* | | | Focused |
|
||||||
|
* | | | Card |
|
||||||
|
* | | | |
|
||||||
|
* +-+ | |
|
||||||
|
* +-+ |
|
||||||
|
* +------------+
|
||||||
*/
|
*/
|
||||||
class NavigationCardStack extends React.Component {
|
class NavigationCardStack extends React.Component {
|
||||||
_applyAnimation: NavigationAnimationSetter;
|
_applyAnimation: NavigationAnimationSetter;
|
||||||
@ -123,8 +134,8 @@ class NavigationCardStack extends React.Component {
|
|||||||
NavigationCardStackStyleInterpolator.forHorizontal(props);
|
NavigationCardStackStyleInterpolator.forHorizontal(props);
|
||||||
|
|
||||||
const panHandlers = isVertical ?
|
const panHandlers = isVertical ?
|
||||||
NavigationLinearPanResponder.forVertical(props) :
|
NavigationCardStackPanResponder.forVertical(props) :
|
||||||
NavigationLinearPanResponder.forHorizontal(props);
|
NavigationCardStackPanResponder.forHorizontal(props);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NavigationCard
|
<NavigationCard
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
*
|
*
|
||||||
* @providesModule NavigationLinearPanResponder
|
* @providesModule NavigationCardStackPanResponder
|
||||||
* @flow
|
* @flow
|
||||||
* @typechecks
|
* @typechecks
|
||||||
*/
|
*/
|
||||||
@ -65,10 +65,20 @@ const Actions = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pan responder that handles the One-dimensional gesture (horizontal or
|
* Pan responder that handles gesture for a card in the cards stack.
|
||||||
* vertical).
|
*
|
||||||
|
* +------------+
|
||||||
|
* +-+ |
|
||||||
|
* +-+ | |
|
||||||
|
* | | | |
|
||||||
|
* | | | Focused |
|
||||||
|
* | | | Card |
|
||||||
|
* | | | |
|
||||||
|
* +-+ | |
|
||||||
|
* +-+ |
|
||||||
|
* +------------+
|
||||||
*/
|
*/
|
||||||
class NavigationLinearPanResponder extends NavigationAbstractPanResponder {
|
class NavigationCardStackPanResponder extends NavigationAbstractPanResponder {
|
||||||
|
|
||||||
_isResponding: boolean;
|
_isResponding: boolean;
|
||||||
_isVertical: boolean;
|
_isVertical: boolean;
|
||||||
@ -181,7 +191,7 @@ function createPanHandlers(
|
|||||||
direction: NavigationGestureDirection,
|
direction: NavigationGestureDirection,
|
||||||
props: NavigationSceneRendererProps,
|
props: NavigationSceneRendererProps,
|
||||||
): NavigationPanPanHandlers {
|
): NavigationPanPanHandlers {
|
||||||
const responder = new NavigationLinearPanResponder(direction, props);
|
const responder = new NavigationCardStackPanResponder(direction, props);
|
||||||
return responder.panHandlers;
|
return responder.panHandlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,8 +208,17 @@ function forVertical(
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
// constants
|
||||||
|
ANIMATION_DURATION,
|
||||||
|
DISTANCE_THRESHOLD,
|
||||||
|
POSITION_THRESHOLD,
|
||||||
|
RESPOND_THRESHOLD,
|
||||||
|
|
||||||
|
// enums
|
||||||
Actions,
|
Actions,
|
||||||
Directions,
|
Directions,
|
||||||
|
|
||||||
|
// methods.
|
||||||
forHorizontal,
|
forHorizontal,
|
||||||
forVertical,
|
forVertical,
|
||||||
};
|
};
|
@ -32,15 +32,25 @@
|
|||||||
*/
|
*/
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
|
||||||
* Predefined interpolator that renders the animated style for NavigationCard.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
NavigationSceneRendererProps,
|
NavigationSceneRendererProps,
|
||||||
} from 'NavigationTypeDefinition';
|
} from 'NavigationTypeDefinition';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility that builds the style for the card in the cards stack.
|
||||||
|
*
|
||||||
|
* +------------+
|
||||||
|
* +-+ |
|
||||||
|
* +-+ | |
|
||||||
|
* | | | |
|
||||||
|
* | | | Focused |
|
||||||
|
* | | | Card |
|
||||||
|
* | | | |
|
||||||
|
* +-+ | |
|
||||||
|
* +-+ |
|
||||||
|
* +------------+
|
||||||
|
*/
|
||||||
|
|
||||||
function forHorizontal(props: NavigationSceneRendererProps): Object {
|
function forHorizontal(props: NavigationSceneRendererProps): Object {
|
||||||
const {
|
const {
|
||||||
layout,
|
layout,
|
||||||
|
@ -39,7 +39,9 @@ const NavigationCard = require('NavigationCard');
|
|||||||
const NavigationCardStackStyleInterpolator = require('NavigationCardStackStyleInterpolator');
|
const NavigationCardStackStyleInterpolator = require('NavigationCardStackStyleInterpolator');
|
||||||
const NavigationContext = require('NavigationContext');
|
const NavigationContext = require('NavigationContext');
|
||||||
const NavigationLegacyNavigatorRouteStack = require('NavigationLegacyNavigatorRouteStack');
|
const NavigationLegacyNavigatorRouteStack = require('NavigationLegacyNavigatorRouteStack');
|
||||||
const NavigationLinearPanResponder = require('NavigationLinearPanResponder');
|
const NavigationCardStackPanResponder = require('NavigationCardStackPanResponder');
|
||||||
|
const NavigationPagerPanResponder = require('NavigationPagerPanResponder');
|
||||||
|
const NavigationPagerStyleInterpolator = require('NavigationPagerStyleInterpolator');
|
||||||
const NavigatorBreadcrumbNavigationBar = require('NavigatorBreadcrumbNavigationBar');
|
const NavigatorBreadcrumbNavigationBar = require('NavigatorBreadcrumbNavigationBar');
|
||||||
const NavigatorNavigationBar = require('NavigatorNavigationBar');
|
const NavigatorNavigationBar = require('NavigatorNavigationBar');
|
||||||
const NavigatorSceneConfigs = require('NavigatorSceneConfigs');
|
const NavigatorSceneConfigs = require('NavigatorSceneConfigs');
|
||||||
@ -47,6 +49,7 @@ const React = require('react-native');
|
|||||||
const ReactComponentWithPureRenderMixin = require('ReactComponentWithPureRenderMixin');
|
const ReactComponentWithPureRenderMixin = require('ReactComponentWithPureRenderMixin');
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
|
NavigationActionCaller,
|
||||||
NavigationAnimatedValue,
|
NavigationAnimatedValue,
|
||||||
NavigationAnimationSetter,
|
NavigationAnimationSetter,
|
||||||
NavigationParentState,
|
NavigationParentState,
|
||||||
@ -73,15 +76,6 @@ type State = {
|
|||||||
routeStack: Array<any>,
|
routeStack: Array<any>,
|
||||||
};
|
};
|
||||||
|
|
||||||
function getConfigPopDirection(config: any): ?string {
|
|
||||||
if (config && config.gestures && config.gestures.pop) {
|
|
||||||
const direction = config.gestures.pop.direction;
|
|
||||||
return direction ? String(direction) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const RouteStack = NavigationLegacyNavigatorRouteStack;
|
const RouteStack = NavigationLegacyNavigatorRouteStack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,6 +102,7 @@ class NavigationLegacyNavigator extends React.Component<any, Props, State> {
|
|||||||
_renderScene: NavigationSceneRenderer;
|
_renderScene: NavigationSceneRenderer;
|
||||||
_routeFocused: any;
|
_routeFocused: any;
|
||||||
_routeToFocus: any;
|
_routeToFocus: any;
|
||||||
|
_onNavigate: NavigationActionCaller;
|
||||||
_stack: NavigationLegacyNavigatorRouteStack;
|
_stack: NavigationLegacyNavigatorRouteStack;
|
||||||
_useAnimation: boolean;
|
_useAnimation: boolean;
|
||||||
|
|
||||||
@ -206,6 +201,7 @@ class NavigationLegacyNavigator extends React.Component<any, Props, State> {
|
|||||||
|
|
||||||
componentWillMount(): void {
|
componentWillMount(): void {
|
||||||
this._applyAnimation = this._applyAnimation.bind(this);
|
this._applyAnimation = this._applyAnimation.bind(this);
|
||||||
|
this._onNavigate = this._onNavigate.bind(this);
|
||||||
this._onNavigationBarRef = this._onNavigationBarRef.bind(this);
|
this._onNavigationBarRef = this._onNavigationBarRef.bind(this);
|
||||||
this._onPositionChange = this._onPositionChange.bind(this);
|
this._onPositionChange = this._onPositionChange.bind(this);
|
||||||
this._renderCard = this._renderCard.bind(this);
|
this._renderCard = this._renderCard.bind(this);
|
||||||
@ -240,6 +236,7 @@ class NavigationLegacyNavigator extends React.Component<any, Props, State> {
|
|||||||
<NavigationAnimatedView
|
<NavigationAnimatedView
|
||||||
applyAnimation={this._applyAnimation}
|
applyAnimation={this._applyAnimation}
|
||||||
navigationState={this._stack.toNavigationState()}
|
navigationState={this._stack.toNavigationState()}
|
||||||
|
onNavigate={this._onNavigate}
|
||||||
renderOverlay={this._renderHeader}
|
renderOverlay={this._renderHeader}
|
||||||
renderScene={this._renderCard}
|
renderScene={this._renderCard}
|
||||||
style={this.props.style}
|
style={this.props.style}
|
||||||
@ -285,37 +282,37 @@ class NavigationLegacyNavigator extends React.Component<any, Props, State> {
|
|||||||
const {scene} = props;
|
const {scene} = props;
|
||||||
const {configureScene} = this.props;
|
const {configureScene} = this.props;
|
||||||
|
|
||||||
let isVertical = false;
|
// Default getters for style and pan responders.
|
||||||
|
let styleGetter = NavigationCardStackStyleInterpolator.forHorizontal;
|
||||||
|
let panResponderGetter = NavigationCardStackPanResponder.forHorizontal;
|
||||||
|
|
||||||
if (configureScene) {
|
if (configureScene) {
|
||||||
const route = RouteStack.getRouteByNavigationState(scene.navigationState);
|
const route = RouteStack.getRouteByNavigationState(scene.navigationState);
|
||||||
const config = configureScene(route, this.state.routeStack);
|
const config = configureScene(route, this.state.routeStack);
|
||||||
const direction = getConfigPopDirection(config);
|
|
||||||
|
|
||||||
switch (direction) {
|
if (config) {
|
||||||
case 'left-to-right':
|
const gestures = config.gestures || {};
|
||||||
// default.
|
if (gestures.pop && gestures.pop.direction === 'left-to-right') {
|
||||||
break;
|
// pass, will use default getters.
|
||||||
|
} else if (gestures.pop && gestures.pop.direction === 'top-to-bottom') {
|
||||||
case 'top-to-bottom':
|
styleGetter = NavigationCardStackStyleInterpolator.forVertical;
|
||||||
isVertical = true;
|
panResponderGetter = NavigationCardStackPanResponder.forVertical;
|
||||||
break;
|
} else if (
|
||||||
|
gestures.jumpBack &&
|
||||||
default:
|
gestures.jumpForward &&
|
||||||
// unsupported config.
|
gestures.jumpBack.direction === 'left-to-right' &&
|
||||||
if (__DEV__) {
|
gestures.jumpForward.direction === 'right-to-left'
|
||||||
console.warn('unsupported scene configuration %s', direction);
|
) {
|
||||||
}
|
styleGetter = NavigationPagerStyleInterpolator.forHorizontal;
|
||||||
|
panResponderGetter = NavigationPagerPanResponder.forHorizontal;
|
||||||
|
} else if (__DEV__) {
|
||||||
|
console.warn('unsupported scene configuration', config);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const style = isVertical ?
|
const style = styleGetter(props);
|
||||||
NavigationCardStackStyleInterpolator.forVertical(props) :
|
const panHandlers = panResponderGetter(props);
|
||||||
NavigationCardStackStyleInterpolator.forHorizontal(props);
|
|
||||||
|
|
||||||
const panHandlers = isVertical ?
|
|
||||||
NavigationLinearPanResponder.forVertical(props) :
|
|
||||||
NavigationLinearPanResponder.forHorizontal(props);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NavigationCard
|
<NavigationCard
|
||||||
@ -421,6 +418,24 @@ class NavigationLegacyNavigator extends React.Component<any, Props, State> {
|
|||||||
this.navigationContext.emit('didfocus', {route: route});
|
this.navigationContext.emit('didfocus', {route: route});
|
||||||
this.props.onDidFocus && this.props.onDidFocus(route);
|
this.props.onDidFocus && this.props.onDidFocus(route);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_onNavigate(action: any): void {
|
||||||
|
switch (action) {
|
||||||
|
case NavigationCardStackPanResponder.Actions.BACK:
|
||||||
|
this.pop();
|
||||||
|
break;
|
||||||
|
case NavigationPagerPanResponder.Actions.JUMP_BACK:
|
||||||
|
this.jumpBack();
|
||||||
|
break;
|
||||||
|
case NavigationPagerPanResponder.Actions.JUMP_FORWARD:
|
||||||
|
this.jumpForward();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (__DEV__) {
|
||||||
|
console.warn('unsupported gesture action', action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Legacy static members.
|
// Legacy static members.
|
||||||
|
@ -0,0 +1,222 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2013-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
* @providesModule NavigationPagerPanResponder
|
||||||
|
* @flow
|
||||||
|
* @typechecks
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const Animated = require('Animated');
|
||||||
|
const NavigationAbstractPanResponder = require('NavigationAbstractPanResponder');
|
||||||
|
const NavigationCardStackPanResponder = require('NavigationCardStackPanResponder');
|
||||||
|
|
||||||
|
const clamp = require('clamp');
|
||||||
|
|
||||||
|
import type {
|
||||||
|
NavigationPanPanHandlers,
|
||||||
|
NavigationSceneRendererProps,
|
||||||
|
} from 'NavigationTypeDefinition';
|
||||||
|
|
||||||
|
import type {
|
||||||
|
NavigationGestureDirection,
|
||||||
|
} from 'NavigationCardStackPanResponder';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Primitive gesture directions.
|
||||||
|
*/
|
||||||
|
const {
|
||||||
|
ANIMATION_DURATION,
|
||||||
|
DISTANCE_THRESHOLD,
|
||||||
|
POSITION_THRESHOLD,
|
||||||
|
RESPOND_THRESHOLD,
|
||||||
|
Directions,
|
||||||
|
} = NavigationCardStackPanResponder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Primitive gesture actions.
|
||||||
|
*/
|
||||||
|
const Actions = {
|
||||||
|
JUMP_BACK: {type: 'jump_back'},
|
||||||
|
JUMP_FORWARD: {type: 'jump_forward'},
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pan responder that handles gesture for a card in the cards list.
|
||||||
|
*
|
||||||
|
* +-------------+-------------+-------------+
|
||||||
|
* | | | |
|
||||||
|
* | | | |
|
||||||
|
* | | | |
|
||||||
|
* | Next | Focused | Previous |
|
||||||
|
* | Card | Card | Card |
|
||||||
|
* | | | |
|
||||||
|
* | | | |
|
||||||
|
* | | | |
|
||||||
|
* +-------------+-------------+-------------+
|
||||||
|
*/
|
||||||
|
class NavigationPagerPanResponder extends NavigationAbstractPanResponder {
|
||||||
|
|
||||||
|
_isResponding: boolean;
|
||||||
|
_isVertical: boolean;
|
||||||
|
_props: NavigationSceneRendererProps;
|
||||||
|
_startValue: number;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
direction: NavigationGestureDirection,
|
||||||
|
props: NavigationSceneRendererProps,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
this._isResponding = false;
|
||||||
|
this._isVertical = direction === Directions.VERTICAL;
|
||||||
|
this._props = props;
|
||||||
|
this._startValue = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
onMoveShouldSetPanResponder(event: any, gesture: any): boolean {
|
||||||
|
const props = this._props;
|
||||||
|
|
||||||
|
if (props.navigationState.index !== props.scene.index) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const layout = props.layout;
|
||||||
|
const isVertical = this._isVertical;
|
||||||
|
const axis = isVertical ? 'dy' : 'dx';
|
||||||
|
const index = props.navigationState.index;
|
||||||
|
const distance = isVertical ?
|
||||||
|
layout.height.__getValue() :
|
||||||
|
layout.width.__getValue();
|
||||||
|
|
||||||
|
return (
|
||||||
|
Math.abs(gesture[axis]) > RESPOND_THRESHOLD &&
|
||||||
|
distance > 0 &&
|
||||||
|
index > 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onPanResponderGrant(): void {
|
||||||
|
this._isResponding = false;
|
||||||
|
this._props.position.stopAnimation((value: number) => {
|
||||||
|
this._isResponding = true;
|
||||||
|
this._startValue = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onPanResponderMove(event: any, gesture: any): void {
|
||||||
|
if (!this._isResponding) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
layout,
|
||||||
|
navigationState,
|
||||||
|
position,
|
||||||
|
scenes,
|
||||||
|
} = this._props;
|
||||||
|
|
||||||
|
const isVertical = this._isVertical;
|
||||||
|
const axis = isVertical ? 'dy' : 'dx';
|
||||||
|
const index = navigationState.index;
|
||||||
|
const distance = isVertical ?
|
||||||
|
layout.height.__getValue() :
|
||||||
|
layout.width.__getValue();
|
||||||
|
|
||||||
|
const prevIndex = Math.max(
|
||||||
|
0,
|
||||||
|
index - 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
const nextIndex = Math.min(
|
||||||
|
index + 1,
|
||||||
|
scenes.length - 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
const value = clamp(
|
||||||
|
prevIndex,
|
||||||
|
this._startValue - (gesture[axis] / distance),
|
||||||
|
nextIndex,
|
||||||
|
);
|
||||||
|
|
||||||
|
position.setValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
onPanResponderRelease(event: any, gesture: any): void {
|
||||||
|
if (!this._isResponding) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._isResponding = false;
|
||||||
|
|
||||||
|
const {
|
||||||
|
navigationState,
|
||||||
|
onNavigate,
|
||||||
|
position,
|
||||||
|
} = this._props;
|
||||||
|
|
||||||
|
const isVertical = this._isVertical;
|
||||||
|
const axis = isVertical ? 'dy' : 'dx';
|
||||||
|
const index = navigationState.index;
|
||||||
|
const distance = gesture[axis];
|
||||||
|
|
||||||
|
position.stopAnimation((value: number) => {
|
||||||
|
this._reset();
|
||||||
|
if (
|
||||||
|
distance > DISTANCE_THRESHOLD ||
|
||||||
|
value <= index - POSITION_THRESHOLD
|
||||||
|
) {
|
||||||
|
onNavigate(Actions.JUMP_BACK);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
distance < -DISTANCE_THRESHOLD ||
|
||||||
|
value >= index + POSITION_THRESHOLD
|
||||||
|
) {
|
||||||
|
onNavigate(Actions.JUMP_FORWARD);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onPanResponderTerminate(): void {
|
||||||
|
this._isResponding = false;
|
||||||
|
this._reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
_reset(): void {
|
||||||
|
const props = this._props;
|
||||||
|
Animated.timing(
|
||||||
|
props.position,
|
||||||
|
{
|
||||||
|
toValue: props.navigationState.index,
|
||||||
|
duration: ANIMATION_DURATION,
|
||||||
|
}
|
||||||
|
).start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createPanHandlers(
|
||||||
|
direction: NavigationGestureDirection,
|
||||||
|
props: NavigationSceneRendererProps,
|
||||||
|
): NavigationPanPanHandlers {
|
||||||
|
const responder = new NavigationPagerPanResponder(direction, props);
|
||||||
|
return responder.panHandlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
function forHorizontal(
|
||||||
|
props: NavigationSceneRendererProps,
|
||||||
|
): NavigationPanPanHandlers {
|
||||||
|
return createPanHandlers(Directions.HORIZONTAL, props);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
Actions,
|
||||||
|
forHorizontal,
|
||||||
|
};
|
84
Libraries/CustomComponents/NavigationExperimental/NavigationPagerStyleInterpolator.js
Normal file
84
Libraries/CustomComponents/NavigationExperimental/NavigationPagerStyleInterpolator.js
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2013-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
* Facebook, Inc. ("Facebook") owns all right, title and interest, including
|
||||||
|
* all intellectual property and other proprietary rights, in and to the React
|
||||||
|
* Native CustomComponents software (the "Software"). Subject to your
|
||||||
|
* compliance with these terms, you are hereby granted a non-exclusive,
|
||||||
|
* worldwide, royalty-free copyright license to (1) use and copy the Software;
|
||||||
|
* and (2) reproduce and distribute the Software as part of your own software
|
||||||
|
* ("Your Software"). Facebook reserves all rights not expressly granted to
|
||||||
|
* you in this license agreement.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
|
||||||
|
* OR IMPLIED WARRANTIES (INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE) ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL FACEBOOK OR ITS AFFILIATES, OFFICERS, DIRECTORS OR
|
||||||
|
* EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @providesModule NavigationPagerStyleInterpolator
|
||||||
|
* @flow
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import type {
|
||||||
|
NavigationSceneRendererProps,
|
||||||
|
} from 'NavigationTypeDefinition';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility that builds the style for the card in the cards list.
|
||||||
|
*
|
||||||
|
* +-------------+-------------+-------------+
|
||||||
|
* | | | |
|
||||||
|
* | | | |
|
||||||
|
* | | | |
|
||||||
|
* | Next | Focused | Previous |
|
||||||
|
* | Card | Card | Card |
|
||||||
|
* | | | |
|
||||||
|
* | | | |
|
||||||
|
* | | | |
|
||||||
|
* +-------------+-------------+-------------+
|
||||||
|
*/
|
||||||
|
|
||||||
|
function forHorizontal(props: NavigationSceneRendererProps): Object {
|
||||||
|
const {
|
||||||
|
layout,
|
||||||
|
position,
|
||||||
|
scene,
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
const index = scene.index;
|
||||||
|
const inputRange = [index - 1, index, index + 1];
|
||||||
|
|
||||||
|
const width = layout.initWidth;
|
||||||
|
const translateX = position.interpolate({
|
||||||
|
inputRange,
|
||||||
|
outputRange: [width, 0, -width],
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
opacity : 1,
|
||||||
|
shadowColor: 'transparent',
|
||||||
|
shadowRadius: 0,
|
||||||
|
transform: [
|
||||||
|
{ scale: 1 },
|
||||||
|
{ translateX },
|
||||||
|
{ translateY: 0 },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
forHorizontal,
|
||||||
|
};
|
@ -14,11 +14,9 @@
|
|||||||
const NavigationAnimatedView = require('NavigationAnimatedView');
|
const NavigationAnimatedView = require('NavigationAnimatedView');
|
||||||
const NavigationCard = require('NavigationCard');
|
const NavigationCard = require('NavigationCard');
|
||||||
const NavigationCardStack = require('NavigationCardStack');
|
const NavigationCardStack = require('NavigationCardStack');
|
||||||
const NavigationCardStackStyleInterpolator = require('NavigationCardStackStyleInterpolator');
|
|
||||||
const NavigationContainer = require('NavigationContainer');
|
const NavigationContainer = require('NavigationContainer');
|
||||||
const NavigationHeader = require('NavigationHeader');
|
const NavigationHeader = require('NavigationHeader');
|
||||||
const NavigationLegacyNavigator = require('NavigationLegacyNavigator');
|
const NavigationLegacyNavigator = require('NavigationLegacyNavigator');
|
||||||
const NavigationLinearPanResponder = require('NavigationLinearPanResponder');
|
|
||||||
const NavigationReducer = require('NavigationReducer');
|
const NavigationReducer = require('NavigationReducer');
|
||||||
const NavigationRootContainer = require('NavigationRootContainer');
|
const NavigationRootContainer = require('NavigationRootContainer');
|
||||||
const NavigationStateUtils = require('NavigationStateUtils');
|
const NavigationStateUtils = require('NavigationStateUtils');
|
||||||
@ -42,12 +40,6 @@ const NavigationExperimental = {
|
|||||||
CardStack: NavigationCardStack,
|
CardStack: NavigationCardStack,
|
||||||
Header: NavigationHeader,
|
Header: NavigationHeader,
|
||||||
LegacyNavigator: NavigationLegacyNavigator,
|
LegacyNavigator: NavigationLegacyNavigator,
|
||||||
|
|
||||||
// Animations Style Interpolators:
|
|
||||||
CardStackStyleInterpolator: NavigationCardStackStyleInterpolator,
|
|
||||||
|
|
||||||
// Interactions:
|
|
||||||
LinearPanResponder: NavigationLinearPanResponder,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = NavigationExperimental;
|
module.exports = NavigationExperimental;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user