fix: use a separate shadow view for the cards

This commit is contained in:
satyajit.happy
2019-06-06 18:25:58 +02:00
parent 6a9f6af3ad
commit d15cbabaad
4 changed files with 56 additions and 24 deletions

View File

@@ -21,7 +21,7 @@ export function forHorizontalIOS({
})
: 0;
const opacity = interpolate(current, {
const overlayOpacity = interpolate(current, {
inputRange: [0, 1],
outputRange: [0, 0.07],
});
@@ -33,16 +33,15 @@ export function forHorizontalIOS({
return {
cardStyle: {
backgroundColor: '#eee',
transform: [
// Translation for the animation of the current card
{ translateX: translateFocused },
// Translation for the animation of the card on top of this
{ translateX: translateUnfocused },
],
shadowOpacity,
},
overlayStyle: { opacity },
overlayStyle: { opacity: overlayOpacity },
shadowStyle: { shadowOpacity },
};
}
@@ -60,7 +59,6 @@ export function forVerticalIOS({
return {
cardStyle: {
backgroundColor: '#eee',
transform: [
// Translation for the animation of the current card
{ translateY },

View File

@@ -105,6 +105,8 @@ export type NavigationConfig = TransitionPreset & {
mode: 'card' | 'modal';
headerMode: HeaderMode;
headerBackTitleVisible?: boolean;
cardShadowEnabled?: boolean;
cardOverlayEnabled?: boolean;
transparentCard?: boolean;
};
@@ -170,6 +172,7 @@ export type CardInterpolatedStyle = {
containerStyle?: any;
cardStyle?: any;
overlayStyle?: any;
shadowStyle?: any;
};
export type CardStyleInterpolator = (

View File

@@ -23,6 +23,8 @@ type Props = ViewProps & {
onGestureCanceled?: () => void;
onGestureEnd?: () => void;
children: React.ReactNode;
overlayEnabled: boolean;
shadowEnabled: boolean;
gesturesEnabled: boolean;
gestureResponseDistance?: {
vertical?: number;
@@ -85,6 +87,8 @@ const {
export default class Card extends React.Component<Props> {
static defaultProps = {
overlayEnabled: true,
shadowEnabled: true,
gesturesEnabled: true,
};
@@ -414,6 +418,8 @@ export default class Card extends React.Component<Props> {
current,
next,
direction,
overlayEnabled,
shadowEnabled,
gesturesEnabled,
children,
styleInterpolator,
@@ -424,6 +430,7 @@ export default class Card extends React.Component<Props> {
containerStyle,
cardStyle,
overlayStyle,
shadowStyle,
} = this.getInterpolatedStyle(styleInterpolator, current, next, layout);
const handleGestureEvent =
@@ -435,7 +442,7 @@ export default class Card extends React.Component<Props> {
<StackGestureContext.Provider value={this.gestureRef}>
<View pointerEvents="box-none" {...rest}>
<Animated.Code exec={this.exec} />
{overlayStyle ? (
{overlayEnabled && overlayStyle ? (
<Animated.View
pointerEvents="none"
style={[styles.overlay, overlayStyle]}
@@ -452,14 +459,21 @@ export default class Card extends React.Component<Props> {
onHandlerStateChange={handleGestureEvent}
{...this.gestureActivationCriteria()}
>
<Animated.View
style={[
styles.card,
cardStyle,
transparent ? styles.transparent : null,
]}
>
{children}
<Animated.View style={[StyleSheet.absoluteFill, cardStyle]}>
{shadowEnabled && !transparent ? (
<Animated.View
style={[styles.shadow, shadowStyle]}
pointerEvents="none"
/>
) : null}
<View
style={[
StyleSheet.absoluteFill,
transparent ? styles.transparent : styles.opaque,
]}
>
{children}
</View>
</Animated.View>
</PanGestureHandler>
</Animated.View>
@@ -474,20 +488,26 @@ const styles = StyleSheet.create({
flex: 1,
overflow: 'hidden',
},
card: {
...StyleSheet.absoluteFillObject,
shadowOffset: { width: -1, height: 1 },
shadowRadius: 5,
shadowColor: '#000',
backgroundColor: 'white',
elevation: 2,
},
overlay: {
...StyleSheet.absoluteFillObject,
backgroundColor: '#000',
},
shadow: {
top: 0,
left: 0,
bottom: 0,
width: 3,
position: 'absolute',
backgroundColor: '#fff',
shadowOffset: { width: -1, height: 1 },
shadowRadius: 5,
shadowColor: '#000',
shadowOpacity: 1,
},
transparent: {
backgroundColor: 'transparent',
shadowOpacity: 0,
},
opaque: {
backgroundColor: '#eee',
},
});

View File

@@ -35,6 +35,8 @@ type Props = {
transparentCard?: boolean;
headerMode: HeaderMode;
direction: GestureDirection;
cardOverlayEnabled?: boolean;
cardShadowEnabled?: boolean;
onTransitionStart?: (
curr: { index: number },
prev: { index: number }
@@ -159,6 +161,8 @@ export default class Stack extends React.Component<Props, State> {
const {
descriptors,
navigation,
cardOverlayEnabled,
cardShadowEnabled,
routes,
closingRoutes,
onOpenRoute,
@@ -205,6 +209,8 @@ export default class Stack extends React.Component<Props, State> {
closing={closingRoutes.includes(route.key)}
onOpen={() => onOpenRoute({ route })}
onClose={() => onCloseRoute({ route })}
overlayEnabled={cardOverlayEnabled}
shadowEnabled={cardShadowEnabled}
gesturesEnabled={getGesturesEnabled({ route })}
onTransitionStart={({ closing }) => {
onTransitionStart &&
@@ -244,6 +250,7 @@ export default class Stack extends React.Component<Props, State> {
scenes={[scenes[index - 1], scenes[index]]}
navigation={navigation}
styleInterpolator={headerStyleInterpolator}
style={styles.header}
/>
) : null}
{renderScene({ route })}
@@ -259,7 +266,7 @@ export default class Stack extends React.Component<Props, State> {
navigation={navigation}
onLayout={this.handleFloatingHeaderLayout}
styleInterpolator={headerStyleInterpolator}
style={styles.header}
style={[styles.header, styles.floating]}
/>
) : null}
</React.Fragment>
@@ -273,6 +280,10 @@ const styles = StyleSheet.create({
overflow: 'hidden',
},
header: {
// This is needed to show elevation shadow
zIndex: 1,
},
floating: {
position: 'absolute',
top: 0,
left: 0,