Skip to content

Instantly share code, notes, and snippets.

@shokimble
Created June 19, 2019 23:12
Show Gist options
  • Save shokimble/f315b82f575f28656797782765436d0b to your computer and use it in GitHub Desktop.
Save shokimble/f315b82f575f28656797782765436d0b to your computer and use it in GitHub Desktop.
/* 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