Created
June 19, 2019 23:12
-
-
Save shokimble/f315b82f575f28656797782765436d0b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Header that shrinks up and to the center as you scroll | |
To use pass in the onscroll event of a scrollview or something similar and the rest is handled | |
*/ | |
import React, { Component } from 'react'; | |
import { Text, View, StyleSheet, Dimensions, Animated, ScrollView } from 'react-native'; | |
import PropTypes from 'prop-types'; | |
import GlobalStyles from '../styles'; | |
export default class ShrinkHeader extends Component { | |
constructor(props) { | |
super(props); | |
this.offset = 0; | |
this.state = { | |
scrollOffset: new Animated.Value(0), | |
titleWidth: 0, | |
}; | |
this.props = props; | |
} | |
componentDidMount() { | |
this.state.scrollOffset.addListener(({ value }) => (this.offset = value)); | |
this.props.onScrollFuncAvailable(this.onScroll); | |
} | |
onScroll = e => { | |
const scrollSensitivity = 4 / 3; | |
const offset = e.nativeEvent.contentOffset.y / scrollSensitivity; | |
this.state.scrollOffset.setValue(offset); | |
}; | |
render() { | |
const { scrollOffset } = this.state; | |
const screenWidth = Dimensions.get('window').width; | |
return ( | |
<Animated.View | |
style={[ | |
styles.header, | |
{ | |
//paddingHorizontal: screenWidth * 0.05, | |
width: screenWidth - 15, //padding we have | |
height: scrollOffset.interpolate({ | |
inputRange: [100, 200], | |
outputRange: [120, 64], | |
extrapolate: 'clamp', | |
}), | |
}, | |
]}> | |
<Animated.Text | |
onLayout={e => { | |
if (this.offset === 0 && this.state.titleWidth === 0) { | |
const titleWidth = e.nativeEvent.layout.width; | |
this.setState({ titleWidth }); | |
} | |
}} | |
style={[GlobalStyles.headerText, { | |
fontSize: scrollOffset.interpolate({ | |
inputRange: [100, 200], | |
outputRange: [26, 18], | |
extrapolate: 'clamp', | |
}), | |
}]}> | |
{this.props.children} | |
</Animated.Text> | |
<Animated.View | |
style={{ | |
width: scrollOffset.interpolate({ | |
inputRange: [100, 200], | |
outputRange: [screenWidth * 0.9 - this.state.titleWidth, 0], | |
extrapolate: 'clamp', | |
}), | |
}} | |
/> | |
</Animated.View> | |
); | |
} | |
} | |
ShrinkHeader.propTypes = { | |
children: PropTypes.any, | |
onScrollFuncAvailable: PropTypes.func, | |
} | |
const styles = StyleSheet.create({ | |
header: { | |
flexDirection: 'row', | |
alignItems: 'flex-end', | |
justifyContent: 'center', | |
}, | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment