Skip to content
This repository has been archived by the owner on Feb 25, 2020. It is now read-only.

feat: expose animation related properties in context #278

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 31 additions & 25 deletions example/src/StackAnimationConsumerStack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import Animated from 'react-native-reanimated';
import {
createStackNavigator,
NavigationStackScreenProps,
StackAnimationProgressContext,
StackAnimationIsSwipingContext,
StackAnimationIsClosingContext,
StackCardAnimationContext,
} from 'react-navigation-stack';

const ListScreen = (props: NavigationStackScreenProps) => (
Expand All @@ -27,12 +25,14 @@ const ListScreen = (props: NavigationStackScreenProps) => (
);

const AnotherScreen = () => (
<StackAnimationProgressContext.Consumer>
{progress => {
const fontSize = Animated.interpolate(progress, {
inputRange: [0, 1],
outputRange: [8, 32],
});
<StackCardAnimationContext.Consumer>
{value => {
const fontSize = value
? Animated.interpolate(value.current.progress, {
inputRange: [0, 1],
outputRange: [8, 32],
})
: 32;

return (
<View
Expand All @@ -43,13 +43,15 @@ const AnotherScreen = () => (
backgroundColor: 'honeydew',
}}
>
<Animated.Text style={{ fontSize, opacity: progress }}>
<Animated.Text
style={{ fontSize, opacity: value ? value.current.progress : 1 }}
>
Animates on progress
</Animated.Text>
</View>
);
}}
</StackAnimationProgressContext.Consumer>
</StackCardAnimationContext.Consumer>
);

const YetAnotherScreen = () => (
Expand All @@ -61,36 +63,40 @@ const YetAnotherScreen = () => (
backgroundColor: 'papayawhip',
}}
>
<StackAnimationIsSwipingContext.Consumer>
{isSwiping => (
<StackCardAnimationContext.Consumer>
{value => (
<Animated.Text
style={{
fontSize: 24,
opacity: Animated.interpolate(isSwiping, {
inputRange: [0, 1],
outputRange: [1, 0],
}),
opacity: value
? Animated.interpolate(value.swiping, {
inputRange: [0, 1],
outputRange: [1, 0],
})
: 1,
}}
>
Disappears when swiping
</Animated.Text>
)}
</StackAnimationIsSwipingContext.Consumer>
<StackAnimationIsClosingContext.Consumer>
{isClosing => (
</StackCardAnimationContext.Consumer>
<StackCardAnimationContext.Consumer>
{value => (
<Animated.Text
style={{
fontSize: 24,
opacity: Animated.interpolate(isClosing, {
inputRange: [0, 1],
outputRange: [1, 0],
}),
opacity: value
? Animated.interpolate(value.closing, {
inputRange: [0, 1],
outputRange: [1, 0],
})
: 1,
}}
>
Disappears only when closing
</Animated.Text>
)}
</StackAnimationIsClosingContext.Consumer>
</StackCardAnimationContext.Consumer>
</View>
);

Expand Down
10 changes: 2 additions & 8 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,8 @@ export {
*/
export { default as StackGestureContext } from './utils/StackGestureContext';
export {
default as StackAnimationProgressContext,
} from './utils/StackAnimationProgressContext';
export {
default as StackAnimationIsSwipingContext,
} from './utils/StackAnimationIsSwipingContext';
export {
default as StackAnimationIsClosingContext,
} from './utils/StackAnimationIsClosingContext';
default as StackCardAnimationContext,
} from './utils/StackCardAnimationContext';

/**
* Types
Expand Down
4 changes: 0 additions & 4 deletions src/utils/StackAnimationIsClosingContext.tsx

This file was deleted.

4 changes: 0 additions & 4 deletions src/utils/StackAnimationIsSwipingContext.tsx

This file was deleted.

6 changes: 0 additions & 6 deletions src/utils/StackAnimationProgressContext.tsx

This file was deleted.

24 changes: 24 additions & 0 deletions src/utils/StackCardAnimationContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as React from 'react';
import Animated from 'react-native-reanimated';
import { Layout } from '../types';

type StackCardAnimationContextType = {
current: { progress: Animated.Node<number> };
next?: { progress: Animated.Node<number> };
index: number;
closing: Animated.Node<0 | 1>;
swiping: Animated.Node<0 | 1>;
layouts: {
screen: Layout;
};
insets: {
top: number;
right: number;
bottom: number;
left: number;
};
};

export default React.createContext<StackCardAnimationContextType | undefined>(
undefined
);
51 changes: 37 additions & 14 deletions src/views/Stack/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ import {
import memoize from '../../utils/memoize';
import StackGestureContext from '../../utils/StackGestureContext';
import PointerEventsView from './PointerEventsView';
import StackAnimationProgressContext from '../../utils/StackAnimationProgressContext';
import StackAnimationIsSwipingContext from '../../utils/StackAnimationIsSwipingContext';
import StackAnimationIsClosingContext from '../../utils/StackAnimationIsClosingContext';
import StackCardAnimationContext from '../../utils/StackCardAnimationContext';

type Props = ViewProps & {
index: number;
Expand Down Expand Up @@ -762,6 +760,29 @@ export default class Card extends React.Component<Props> {
this.props.insets.left
);

// Keep track of the animation context when deps changes.
private getCardAnimationContext = memoize(
(
index: number,
current: Animated.Node<number>,
next: Animated.Node<number> | undefined,
isSwiping: Animated.Node<0 | 1>,
isClosing: Animated.Node<0 | 1>,
layout: Layout,
insets: EdgeInsets
) => ({
index,
current: { progress: current },
next: next && { progress: next },
closing: isClosing,
swiping: isSwiping,
layouts: {
screen: layout,
},
insets,
})
);

private gestureActivationCriteria() {
const { layout, gestureDirection, gestureResponseDistance } = this.props;

Expand Down Expand Up @@ -913,17 +934,19 @@ export default class Card extends React.Component<Props> {
contentStyle,
]}
>
<StackAnimationProgressContext.Provider value={current}>
<StackAnimationIsSwipingContext.Provider
value={this.isSwiping}
>
<StackAnimationIsClosingContext.Provider
value={this.isClosing}
>
{children}
</StackAnimationIsClosingContext.Provider>
</StackAnimationIsSwipingContext.Provider>
</StackAnimationProgressContext.Provider>
<StackCardAnimationContext.Provider
value={this.getCardAnimationContext(
index,
current,
next,
this.isClosing,
this.isSwiping,
this.props.layout,
this.props.insets
)}
>
{children}
</StackCardAnimationContext.Provider>
</PointerEventsView>
</Animated.View>
</PanGestureHandler>
Expand Down