@@ -4,16 +4,14 @@ const {
4
4
Component,
5
5
Dimensions,
6
6
ScrollView,
7
- StyleSheet,
8
7
View
9
8
} = React ;
10
9
11
- const {
12
- any,
13
- func,
14
- number,
15
- string
16
- } = React . PropTypes ;
10
+ const styles = require ( './styles' ) ;
11
+
12
+ const { any, func, number, string } = React . PropTypes ;
13
+
14
+ const window = Dimensions . get ( 'window' ) ;
17
15
18
16
const SCROLLVIEW_REF = 'ScrollView' ;
19
17
@@ -28,8 +26,7 @@ const IPropTypes = {
28
26
renderScrollComponent : func ,
29
27
renderFixedHeader : func ,
30
28
renderBackground : func ,
31
- stickyHeaderHeight : number ,
32
- style : any
29
+ stickyHeaderHeight : number
33
30
} ;
34
31
35
32
class ParallaxScrollView extends Component {
@@ -38,7 +35,11 @@ class ParallaxScrollView extends Component {
38
35
if ( props . renderStickyHeader && ! props . stickyHeaderHeight ) {
39
36
console . error ( 'Property `stickyHeaderHeight` must be set if `renderStickyHeader` is used' )
40
37
}
41
- this . state = { scrollY : new Animated . Value ( 0 ) } ;
38
+ this . state = {
39
+ scrollY : new Animated . Value ( 0 ) ,
40
+ viewHeight : window . height ,
41
+ viewWidth : window . width
42
+ } ;
42
43
this . _footerComponent = { setNativeProps ( ) { } } ; // Initial stub
43
44
this . _footerHeight = 0 ;
44
45
this . _animatedEvent = Animated . event ( [ { nativeEvent : { contentOffset : { y : this . state . scrollY } } } ] ) ;
@@ -65,14 +66,16 @@ class ParallaxScrollView extends Component {
65
66
const bodyComponent = this . _wrapChildren ( children , { contentBackgroundColor, stickyHeaderHeight } ) ;
66
67
const footerSpacer = this . _renderFooterSpacer ( { contentBackgroundColor } ) ;
67
68
const maybeStickyHeader = this . _maybeRenderStickyHeader ( { parallaxHeaderHeight, stickyHeaderHeight, headerBackgroundColor, renderFixedHeader, renderStickyHeader } ) ;
69
+ const scrollElement = renderScrollComponent ( scrollViewProps ) ;
68
70
69
71
return (
70
- < View style = { styles . container } >
72
+ < View style = { [ style , styles . container ] }
73
+ onLayout = { ( e ) => this . _maybeUpdateViewDimensions ( e ) } >
71
74
{ background }
72
75
{
73
- React . cloneElement ( renderScrollComponent ( scrollViewProps ) , {
76
+ React . cloneElement ( scrollElement , {
74
77
ref : SCROLLVIEW_REF ,
75
- style : [ style , styles . scrollView ] ,
78
+ style : [ styles . scrollView , scrollElement . props . style ] ,
76
79
scrollEventThrottle : 16 ,
77
80
onScroll : this . _onScroll . bind ( this ) ,
78
81
} ,
@@ -130,24 +133,36 @@ class ParallaxScrollView extends Component {
130
133
prevOnScroll ( e ) ;
131
134
}
132
135
136
+ _maybeUpdateViewDimensions ( e ) {
137
+ const { nativeEvent : { layout : { width, height} } } = e ;
138
+
139
+ if ( width !== this . state . viewWidth || height !== this . state . viewHeight ) {
140
+ this . setState ( {
141
+ viewWidth : width ,
142
+ viewHeight : height
143
+ } ) ;
144
+ }
145
+ }
146
+
133
147
_renderBackground ( { headerBackgroundColor, parallaxHeaderHeight, stickyHeaderHeight, renderBackground } ) {
148
+ const { viewWidth, viewHeight, scrollY } = this . state ;
134
149
const midpoint = ( parallaxHeaderHeight - stickyHeaderHeight ) / 2 ;
135
150
return (
136
151
< Animated . View
137
152
style = { [ styles . backgroundImage , {
138
153
backgroundColor : headerBackgroundColor ,
139
154
height : parallaxHeaderHeight ,
140
- width : window . width ,
155
+ width : viewWidth ,
141
156
transform : [ {
142
- translateY : this . state . scrollY . interpolate ( {
157
+ translateY : scrollY . interpolate ( {
143
158
inputRange : [ 0 , midpoint ] ,
144
159
outputRange : [ 0 , - midpoint ] ,
145
160
extrapolateRight : 'extend' ,
146
161
extrapolateLeft : 'clamp'
147
162
} )
148
163
} , {
149
- scale : this . state . scrollY . interpolate ( {
150
- inputRange : [ - window . height , 0 ] ,
164
+ scale : scrollY . interpolate ( {
165
+ inputRange : [ - viewHeight , 0 ] ,
151
166
outputRange : [ 5 , 1 ] ,
152
167
extrapolate : 'clamp'
153
168
} )
@@ -184,13 +199,14 @@ class ParallaxScrollView extends Component {
184
199
}
185
200
186
201
_wrapChildren ( children , { contentBackgroundColor, stickyHeaderHeight } ) {
202
+ const { viewHeight } = this . state ;
187
203
return (
188
204
< View
189
205
style = { { backgroundColor : contentBackgroundColor } }
190
206
onLayout = { e => {
191
207
// Adjust the bottom height so we can scroll the parallax header all the way up.
192
208
const { nativeEvent : { layout : { height } } } = e ;
193
- const footerHeight = Math . max ( 0 , window . height - height - stickyHeaderHeight ) ;
209
+ const footerHeight = Math . max ( 0 , viewHeight - height - stickyHeaderHeight ) ;
194
210
if ( this . _footerHeight !== footerHeight ) {
195
211
this . _footerComponent . setNativeProps ( { style : { height : footerHeight } } ) ;
196
212
this . _footerHeight = footerHeight ;
@@ -208,15 +224,16 @@ class ParallaxScrollView extends Component {
208
224
}
209
225
210
226
_maybeRenderStickyHeader ( { parallaxHeaderHeight, stickyHeaderHeight, headerBackgroundColor, renderFixedHeader, renderStickyHeader } ) {
227
+ const { viewWidth, viewHeight, scrollY } = this . state ;
211
228
if ( renderStickyHeader ) {
212
229
const midpoint = ( parallaxHeaderHeight - stickyHeaderHeight ) / 2 ;
213
230
return (
214
- < View style = { [ styles . stickyHeader , { height : stickyHeaderHeight } ] } >
231
+ < View style = { [ styles . stickyHeader , { width : viewWidth , height : stickyHeaderHeight } ] } >
215
232
< Animated . View
216
233
style = { {
217
234
backgroundColor : headerBackgroundColor ,
218
235
height : stickyHeaderHeight ,
219
- opacity : this . state . scrollY . interpolate ( {
236
+ opacity : scrollY . interpolate ( {
220
237
inputRange : [ 0 , midpoint ] ,
221
238
outputRange : [ 0 , 1 ] ,
222
239
extrapolate : 'clamp'
@@ -225,7 +242,7 @@ class ParallaxScrollView extends Component {
225
242
< Animated . View
226
243
style = { {
227
244
transform : [ {
228
- translateY : this . state . scrollY . interpolate ( {
245
+ translateY : scrollY . interpolate ( {
229
246
inputRange : [ 0 , midpoint ] ,
230
247
outputRange : [ stickyHeaderHeight , 0 ] ,
231
248
extrapolate : 'clamp'
@@ -247,47 +264,13 @@ class ParallaxScrollView extends Component {
247
264
ParallaxScrollView . propTypes = IPropTypes ;
248
265
249
266
ParallaxScrollView . defaultProps = {
250
- renderBackground : ( ) => < View /> ,
251
- renderParallaxHeader : ( ) => < View /> ,
252
267
headerBackgroundColor : '#000' ,
253
268
contentBackgroundColor : '#fff' ,
254
269
onChangeHeaderVisibility : ( ) => { } ,
255
270
renderScrollComponent : props => < ScrollView { ...props } /> ,
256
- stickyHeaderHeight : 0 ,
257
- style : { }
271
+ renderBackground : ( ) => < View /> ,
272
+ renderParallaxHeader : ( ) => < View /> ,
273
+ stickyHeaderHeight : 0
258
274
} ;
259
275
260
- const window = Dimensions . get ( 'window' ) ;
261
-
262
- const styles = StyleSheet . create ( {
263
- container : {
264
- flex : 1 ,
265
- backgroundColor : 'transparent'
266
- } ,
267
- parallaxHeaderContainer : {
268
- backgroundColor : 'transparent' ,
269
- overflow : 'hidden'
270
- } ,
271
- parallaxHeader : {
272
- backgroundColor : 'transparent' ,
273
- overflow : 'hidden'
274
- } ,
275
- backgroundImage : {
276
- position : 'absolute' ,
277
- backgroundColor : 'transparent' ,
278
- top : 0
279
- } ,
280
- stickyHeader : {
281
- backgroundColor : 'transparent' ,
282
- position : 'absolute' ,
283
- overflow : 'hidden' ,
284
- top : 0 ,
285
- left : 0 ,
286
- width : window . width
287
- } ,
288
- scrollView : {
289
- backgroundColor : 'transparent'
290
- }
291
- } ) ;
292
-
293
276
module . exports = ParallaxScrollView ;
0 commit comments