Skip to content

Instantly share code, notes, and snippets.

@Schniz
Last active April 8, 2018 02:00
Show Gist options
  • Save Schniz/e368f94073d740de6c786c762be1fa79 to your computer and use it in GitHub Desktop.
Save Schniz/e368f94073d740de6c786c762be1fa79 to your computer and use it in GitHub Desktop.
Reach Navigation? wat https://snack.expo.io/H19VSw6mb
import React from 'react';
import {Image, StyleSheet, TouchableOpacity, Dimensions, View, Animated, PanResponder, Text} from 'react-native';
import { Constants, BlurView } from 'expo';
class ReachNavigationDemo extends React.Component {
state = { isClosed: true, scroll: new Animated.Value(0) }
position = 0;
panResponder = PanResponder.create({
onMoveShouldSetResponderCapture: () => true,
onMoveShouldSetPanResponderCapture: (_, { dy }) => Math.abs(dy) > 0.5,
onPanResponderMove: (_, {dy}) => {
this.state.scroll.setValue(this.position + dy)
},
onPanResponderRelease: (e, { vy }) => {
this.setOpenState(vy > 0)
}
})
setOpenState = isClosed => {
if (isClosed !== this.state.isClosed && this.props.onOpenStateChange) {
setTimeout(this.props.onOpenStateChange)
}
this.position = isClosed ? 0 : -500;
this.setState({isClosed})
Animated.timing(this.state.scroll, {
toValue: this.position,
duration: 100,
}).start()
}
toggle = () => {
const state = JSON.parse(JSON.stringify(this.state.scroll))
this.setOpenState(state < 0)
}
isClosed = () => {
return this.state.isClosed
}
render() {
const {height: windowHeight, width: windowWidth} = Dimensions.get('window')
const height = windowHeight - 75
const interpolateScroll = outputRange => this.state.scroll.interpolate({
outputRange,
inputRange: [-height, 0, 100],
extrapolate: "clamp",
})
const maybeTouchable = x => this.state.isClosed ? (
<TouchableOpacity
onPress={this.isClosed() ? this.toggle : undefined}
style={{flex: 1}}
>
{x}
</TouchableOpacity>
) : x;
// interpolation!
const width = interpolateScroll([windowWidth, windowWidth - 50, windowWidth - 50])
const translateY = interpolateScroll([50, height, height + 10]);
const translateX = interpolateScroll([0, 25, 25]);
const shadowOpacity = interpolateScroll([0.7, 0.2, 0.2])
const shadowRadius = interpolateScroll([10, 2, 2])
return (
<Animated.View
{...this.panResponder.panHandlers}
style={{
position: 'absolute',
top: 0,
backgroundColor: '#f7f7f7',
left: 0,
shadowOpacity,
shadowRadius,
height,
width,
transform: [{ translateX }, { translateY }]
}}
>
{maybeTouchable(
<View flex={1}>
<Text style={{fontSize: 15, fontWeight: 'bold', letterSpacing: 3, padding: 8, color: 'rgba(0,0,0,0.6)'}}>YOU ARE A WIZARD HARRY</Text>
<Text style={{padding: 8}}>This is not negotiable</Text>
</View>
)}
</Animated.View>
);
}
}
const MapMock = ({style}) => (
<Image
source={{uri: 'https://i.stack.imgur.com/baRy9.png'}}
style={style}
/>
);
export default class App extends React.Component {
render() {
return (
<View flex={1}>
<MapMock style={StyleSheet.absoluteFill} />
<BlurView
tint="light"
intensity={80}
style={{height: Constants.statusBarHeight}}
/>
<ReachNavigationDemo />
</View>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment