Skip to content

Commit d7f674b

Browse files
committed
Add foreground prop
1 parent 9180c5c commit d7f674b

File tree

6 files changed

+83
-10
lines changed

6 files changed

+83
-10
lines changed

demo.gif

1.35 MB
Loading

exemple/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
node_modules/**/*
22
.exponent/*
33
npm-debug.*
4+
ImageHeaderScrollView.js

exemple/main.js

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,20 @@ const TvShow = () => (
1717
<View style={{ flex:1 }}>
1818
<StatusBar barStyle="light-content" />
1919
<HeaderImageScrollView
20-
maxHeight={200}
20+
maxHeight={250}
2121
minHeight={66}
22+
maxOverlayOpacity={0.6}
23+
minOverlayOpacity={0.3}
24+
fadeOutForeground
2225
renderHeader={() => (
2326
<Image source={tvShowContent.image} style={styles.image} />
2427
)}
25-
>
28+
renderForeground={() => (
29+
<View style={styles.titleContainer}>
30+
<Text style={styles.imageTitle}>{tvShowContent.title}</Text>
31+
</View>
32+
)}
33+
>
2634
<View style={styles.section}>
2735
<Text style={styles.title}>
2836
<Text style={styles.name}>{tvShowContent.title}</Text>, ({tvShowContent.year})
@@ -48,7 +56,7 @@ const TvShow = () => (
4856

4957
const styles = StyleSheet.create({
5058
image: {
51-
height: 200,
59+
height: 250,
5260
width: Dimensions.get('window').width,
5361
alignSelf: 'stretch',
5462
resizeMode: 'cover',
@@ -88,6 +96,17 @@ const styles = StyleSheet.create({
8896
fontSize: 16,
8997
color: 'white',
9098
},
99+
titleContainer: {
100+
flex: 1,
101+
alignSelf: 'stretch',
102+
justifyContent: 'center',
103+
alignItems: 'center',
104+
},
105+
imageTitle: {
106+
color: 'white',
107+
backgroundColor: 'transparent',
108+
fontSize: 24,
109+
}
91110
});
92111

93112
Exponent.registerRootComponent(TvShow);

src/__tests__/__snapshots__/index.js.snap

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,24 @@ exports[`test renders correctly by default 1`] = `
5151
} />
5252
<View />
5353
</View>
54+
<View
55+
style={
56+
Object {
57+
"height": 125,
58+
"left": 0,
59+
"opacity": 1,
60+
"overflow": "hidden",
61+
"position": "absolute",
62+
"right": 0,
63+
"top": 0,
64+
"transform": Array [
65+
Object {
66+
"translateY": 0,
67+
},
68+
],
69+
}
70+
}>
71+
<View />
72+
</View>
5473
</View>
5574
`;

src/__tests__/index.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import React from 'react';
22
import 'react-native';
3-
import ImageHeaderScrollView from '../index.js';
43
import renderer from 'react-test-renderer';
4+
import ImageHeaderScrollView from '../index.js';
55

6-
it('renders correctly by default', () => {
7-
const tree = renderer.create(
8-
<ImageHeaderScrollView />
9-
).toJSON();
10-
expect(tree).toMatchSnapshot();
6+
describe('ImageHeaderScrollView', () => {
7+
it('renders correctly by default', () => {
8+
const tree = renderer.create(
9+
<ImageHeaderScrollView />,
10+
).toJSON();
11+
expect(tree).toMatchSnapshot();
12+
});
1113
});

src/index.js

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@ class ImageHeaderScrollView extends Component {
5555
this.props.maxHeight,
5656
this.props.minHeight,
5757
]);
58-
const overlayOpacity = this.interpolateOnImageHeight([0, this.props.maxOverlayOpacity]);
58+
const overlayOpacity = this.interpolateOnImageHeight([
59+
this.props.minOverlayOpacity,
60+
this.props.maxOverlayOpacity,
61+
]);
5962

6063
const headerScale = this.state.scrollY.interpolate({
6164
inputRange: [-this.props.maxHeight, 0],
@@ -72,6 +75,26 @@ class ImageHeaderScrollView extends Component {
7275
);
7376
}
7477

78+
renderForeground() {
79+
const headerTranslate = this.state.scrollY.interpolate({
80+
inputRange: [0, this.props.maxHeight * 2],
81+
outputRange: [0, -this.props.maxHeight * 2 * this.props.foregroundParallaxRatio],
82+
extrapolate: 'clamp',
83+
});
84+
const opacity = this.interpolateOnImageHeight([1, -0.3]);
85+
86+
const headerTransformStyle = {
87+
height: this.props.maxHeight,
88+
transform: [{ translateY: headerTranslate }],
89+
opacity: this.props.fadeOutForeground ? opacity : 1,
90+
};
91+
return (
92+
<Animated.View style={[styles.header, headerTransformStyle]}>
93+
{ this.props.renderForeground() }
94+
</Animated.View>
95+
);
96+
}
97+
7598
render() {
7699
return (
77100
<View style={styles.container}>
@@ -87,25 +110,34 @@ class ImageHeaderScrollView extends Component {
87110
</Animated.View>
88111
</ScrollView>
89112
{ this.renderHeader() }
113+
{ this.renderForeground() }
90114
</View>
91115
);
92116
}
93117
}
94118

95119
ImageHeaderScrollView.propTypes = {
96120
renderHeader: React.PropTypes.func,
121+
renderForeground: React.PropTypes.func,
97122
maxHeight: React.PropTypes.number,
98123
minHeight: React.PropTypes.number,
99124
children: React.PropTypes.node || React.PropTypes.nodes,
100125
maxOverlayOpacity: React.PropTypes.number,
126+
minOverlayOpacity: React.PropTypes.number,
101127
childrenStyle: View.propTypes.style,
128+
foregroundParallaxRatio: React.PropTypes.number,
129+
fadeOutForeground: React.PropTypes.bool,
102130
};
103131

104132
ImageHeaderScrollView.defaultProps = {
105133
maxHeight: 125,
106134
minHeight: 80,
107135
maxOverlayOpacity: 0.3,
136+
minOverlayOpacity: 0,
108137
renderHeader: () => <View />,
138+
renderForeground: () => <View />,
139+
foregroundParallaxRatio: 1,
140+
fadeOutForeground: false,
109141
};
110142

111143
export default ImageHeaderScrollView;

0 commit comments

Comments
 (0)