Open oferRounds opened 4 years ago
I’m not using expo by the way... So can’t use the example with the blur
@zmnv Thank you very much, missed this! Will look into it!
Thank you, works perfect!
There is one problem actually which I notice – the shadow does not cover the navigation bar nor the tab bar (using react native navigation
), any idea how workaround this issue?
@oferRounds, I used BottomSheet on the top level of my app
Thank @zmnv , it worked for me. This is my example for anyone who comes late
import React from 'react'
import {
Image,
StyleSheet,
Text,
TouchableWithoutFeedback,
View,
TextInput,
SafeAreaView,
TouchableOpacity
} from 'react-native';
import BottomSheet from 'reanimated-bottom-sheet'
import Animated from 'react-native-reanimated'
const AnimatedView = Animated.View
let fall = new Animated.Value(1)
export default class Example extends React.Component {
renderInner = () => (
<View style={styles.panel}>
<TextInput
style={styles.search}
onFocus={() => {
this.bs.current.snapTo(1)
}}
placeholder="search"
/>
<Text style={styles.panelTitle}>San Francisco Airport</Text>
<Text style={styles.panelSubtitle}>
International Airport - 40 miles away
</Text>
<View style={styles.panelButton}>
<Text style={styles.panelButtonTitle}>Directions</Text>
</View>
<View style={styles.panelButton}>
<Text style={styles.panelButtonTitle}>Search Nearby</Text>
</View>
{/* <Image
style={styles.photo}
source={require('./assets/airport-photo.jpg')}
/> */}
</View>
)
renderHeader = () => (
<View style={styles.header}>
<View style={styles.panelHeader}>
<View style={styles.panelHandle} />
</View>
</View>
)
bs = React.createRef()
renderShadow = () => {
const animatedShadowOpacity = Animated.interpolate(fall, {
inputRange: [0, 1],
outputRange: [0.5, 0],
})
return (
<AnimatedView
pointerEvents="none"
style={[
styles.shadowContainer,
{
opacity: animatedShadowOpacity,
},
]}
/>
)
}
render() {
return (
<SafeAreaView style={{ flex: 1 }}>
<View style={styles.container}>
{this.renderShadow()}
<BottomSheet
ref={this.bs}
snapPoints={[500, 250, 0]}
renderContent={this.renderInner}
renderHeader={this.renderHeader}
initialSnap={1}
callbackNode={fall}
/>
<TouchableOpacity style={{ marginTop: 100, borderWidth: 1, borderColor: 'red' }}
onPress={() => this.bs.current.snapTo(0)}>
<Text>aaa</Text>
{/* <Image style={styles.map} source={require('./assets/map-bg.jpg')} /> */}
</TouchableOpacity>
</View>
</SafeAreaView>
)
}
}
const IMAGE_SIZE = 200
const styles = StyleSheet.create({
search: {
borderColor: 'gray',
borderWidth: StyleSheet.hairlineWidth,
height: 40,
borderRadius: 10,
paddingHorizontal: 15,
},
container: {
flex: 1,
backgroundColor: '#F5FCFF',
},
box: {
width: IMAGE_SIZE,
height: IMAGE_SIZE,
},
panelContainer: {
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
},
panel: {
height: 600,
padding: 20,
backgroundColor: '#fff',
},
header: {
backgroundColor: '#fff',
shadowColor: '#000000',
paddingTop: 20,
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
},
panelHeader: {
alignItems: 'center',
},
panelHandle: {
width: 40,
height: 8,
borderRadius: 4,
backgroundColor: '#00000040',
marginBottom: 10,
},
panelTitle: {
fontSize: 27,
height: 35,
},
panelSubtitle: {
fontSize: 14,
color: 'gray',
height: 30,
marginBottom: 10,
},
panelButton: {
padding: 20,
borderRadius: 10,
backgroundColor: '#318bfb',
alignItems: 'center',
marginVertical: 10,
},
panelButtonTitle: {
fontSize: 17,
fontWeight: 'bold',
color: 'white',
},
photo: {
width: '100%',
height: 225,
marginTop: 30,
},
map: {
height: '100%',
width: '100%',
},
// Shadow
shadowContainer: {
...StyleSheet.absoluteFillObject,
backgroundColor: '#000',
},
})
@zmnv but i still can press some items under mask overlay layout. How to prevent it? thank you
@zmnv but i still can press some items under mask overlay layout. How to prevent it? thank you
hey, i have same problem did you solve it?
I prevent that with:
renderShadow = () => {
const animatedShadowOpacity = Animated.interpolate(fall, {
inputRange: [0, 1],
outputRange: [0.5, 0],
});
const clickthrough = Animated.cond(greaterThan(fall, 0), 'none', 'auto');
return (
<AnimatedView
pointerEvents={clickthrough}
style={[
styles.shadowContainer,
{
opacity: animatedShadowOpacity,
},
]}
/>
);
};
Still new to this library so dunno if this is the recommended way
I prevent that with:
renderShadow = () => { const animatedShadowOpacity = Animated.interpolate(fall, { inputRange: [0, 1], outputRange: [0.5, 0], }); const clickthrough = Animated.cond(greaterThan(fall, 0), 'none', 'auto'); return ( <AnimatedView pointerEvents={clickthrough} style={[ styles.shadowContainer, { opacity: animatedShadowOpacity, }, ]} /> ); };
Still new to this library to dunno if this is the recommended way
Hi, thanks for your solution. It works but it also disables click even when the bottom sheet and shadow not open. Please help? thank you
Hi @anhquan291; Some while ago now but if I remember correctly I fixed that with the BottomSheet props:
...
enabledGestureInteraction={true}
enabledContentGestureInteraction={false} />
Hi @anhquan291; Some while ago now but if I remember correctly I fixed that with the BottomSheet props:
... enabledGestureInteraction={true} enabledContentGestureInteraction={false} />
Thank you. I'll try it
You only need to set a zIndex to the shadowContainer to keep over the back content to avoid interaction
shadowContainer: { ...StyleSheet.absoluteFillObject, backgroundColor: '#292C36', zIndex:10, }
I get this near Animated.interpolate(fall,{....});
TypeError: undefined is not a function
Any suggestions ??
Here is the full snippet:
const renderShadow = () => {
const animatedShadowOpacity = Animated.interpolate(fall, {
inputRange: [0, 1],
outputRange: [0.5, 0],
});
return (
<AnimatedView
pointerEvents="none"
style={[
styles.shadowContainer,
{
opacity: animatedShadowOpacity,
},
]}
/>
);
};
I get this near Animated.interpolate(fall,{....});
TypeError: undefined is not a function
Any suggestions ??
Here is the full snippet:
const renderShadow = () => { const animatedShadowOpacity = Animated.interpolate(fall, { inputRange: [0, 1], outputRange: [0.5, 0], }); return ( <AnimatedView pointerEvents="none" style={[ styles.shadowContainer, { opacity: animatedShadowOpacity, }, ]} /> ); };
Downgrading react-native-reanimated package to 1.7.0 helped.
The api for reanimated is changed in v2, try interpolateNode: https://docs.swmansion.com/react-native-reanimated/docs/migration
const fall = React.useRef(new Animated.Value(1)).current;
const animatedShadowOpacity = Animated.interpolateNode(fall, {
inputRange: [0, 1],
outputRange: [0.5, 0],
});
return (
<>
<BottomSheet .../>
<Animated.View
pointerEvents="none"
style={[
styles.shadowContainer,
{
opacity: animatedShadowOpacity,
},
]}
/>
</>
);
const styles = StyleSheet.create({
shadowContainer: {
...StyleSheet.absoluteFillObject,
backgroundColor: '#000',
},
});
Hi!
Thanks for this awesome library!
Quick question please: How can I mask the background? if I just add a mask view, it darken also the bottom sheet... Any idea?