From 3b678c72626bd7446d302fd1fde02e1d105a4706 Mon Sep 17 00:00:00 2001 From: Jakob Kerkhove Date: Thu, 13 Apr 2017 15:31:34 +0200 Subject: [PATCH 1/6] Code styling and component background implementation --- .gitignore | 24 +--- README.md | 2 +- index.js | 4 +- lib/ParallaxView.js | 307 +++++++++++++++++++++++++++----------------- 4 files changed, 193 insertions(+), 144 deletions(-) diff --git a/.gitignore b/.gitignore index fb48be7..d3cc3b0 100644 --- a/.gitignore +++ b/.gitignore @@ -26,26 +26,4 @@ build/Release # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git node_modules -.idea/.name - -.idea/encodings.xml - -.idea/inspectionProfiles/profiles_settings.xml - -.idea/inspectionProfiles/Project_Default.xml - -.idea/misc.xml - -.idea/modules.xml - -.idea/react-native-parallax-view.iml - -.idea/scopes/scope_settings.xml - -.idea/vcs.xml - -.idea/workspace.xml - -.idea/libraries/react_native_parallax_view_node_modules.xml - -.idea/jsLibraryMappings.xml +.idea \ No newline at end of file diff --git a/README.md b/README.md index c930311..7d72c32 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ Additionally, here is an example of the usage | Prop | Required | Default | Type | Description | | :------------ |:---:|:---------------:| :---------------:| :-----| -| backgroundSource | YES | `null` | `object` | the `source` prop that get's passed to the background `` component. If left blank, no background is rendered | +| background | YES | `null` | `object` | Background can be image string, image object (with uri) or a React component to render | | header | NO | `null` | `renderable` | any content you want to render on top of the image. This content's opacity get's animated down as the scrollview scrolls up. (optional) | | windowHeight | NO | `300` | `number` | the resting height of the header image. If 0 is passed in, the background is not rendered. | | scrollableViewStyle | NO | `null` | `object` | this style will be mixed (overriding existing fields) with scrollable view style (view which is scrolled over the background) | diff --git a/index.js b/index.js index 6c032cf..dfb37d4 100644 --- a/index.js +++ b/index.js @@ -1 +1,3 @@ -module.exports = require('./lib/ParallaxView'); \ No newline at end of file +import ParallaxView from './lib/ParallaxView'; + +export default ParallaxView; \ No newline at end of file diff --git a/lib/ParallaxView.js b/lib/ParallaxView.js index 776bdb3..5fdc2df 100644 --- a/lib/ParallaxView.js +++ b/lib/ParallaxView.js @@ -1,142 +1,218 @@ -'use strict'; - -var React = require('react'); -var ReactNative = require('react-native'); -var { - Dimensions, - StyleSheet, - View, - ScrollView, - Animated, - } = ReactNative; -/** - * BlurView temporarily removed until semver stuff is set up properly - */ -//var BlurView /* = require('react-native-blur').BlurView */; -var ScrollableMixin = require('react-native-scrollable-mixin'); -var screen = Dimensions.get('window'); -var ScrollViewPropTypes = ScrollView.propTypes; +import React, { Component } from 'react'; +import { Dimensions, StyleSheet, View, ScrollView, Animated } from 'react-native'; +import ScrollableMixin from 'react-native-scrollable-mixin'; -var ParallaxView = React.createClass({ - mixins: [ScrollableMixin], +const screen = Dimensions.get('window'); +const ScrollViewPropTypes = ScrollView.propTypes; - propTypes: { +/** + * + * + * @property {Number} windowHeight + * @property {Node|String|{ uri: String}} background + * @property {Node} [header] + * @property {Object} contentInset + * + */ +class ParallaxView extends Component +{ + static propTypes = { ...ScrollViewPropTypes, windowHeight: React.PropTypes.number, - backgroundSource: React.PropTypes.oneOfType([ - React.PropTypes.shape({ - uri: React.PropTypes.string, - }), - // Opaque type returned by require('./image.jpg') - React.PropTypes.number, - ]), - header: React.PropTypes.node, - blur: React.PropTypes.string, + background: React.PropTypes.object, + header: React.PropTypes.node.optional, contentInset: React.PropTypes.object, - }, + scrollableViewStyle: React.PropTypes.object + }; - getDefaultProps: function () { - return { + constructor() { + const defaultProps = { windowHeight: 300, - contentInset: { - top: screen.scale - } + contentInset: { top: screen.scale } }; - }, - getInitialState: function () { - return { + super(defaultProps); + + // Initial props + this.props = defaultProps; + + // Initial state + this.state = { scrollY: new Animated.Value(0) }; - }, + + this.handleScroll = this.handleScroll.bind(this); + } /** - * IMPORTANT: You must return the scroll responder of the underlying - * scrollable component from getScrollResponder() when using ScrollableMixin. + * getScrollResponder method for ScrollableMixin + * @returns {ScrollView} */ getScrollResponder() { - return this._scrollView.getScrollResponder(); - }, + return this._scrollView.getScrollResponder(); + } + /** + * setNativeProps method for ScrollableMixin + * @param {Object} props + */ setNativeProps(props) { - this._scrollView.setNativeProps(props); - }, + this._scrollView.setNativeProps(props); + } - renderBackground: function () { - var { windowHeight, backgroundSource, blur } = this.props; - var { scrollY } = this.state; - if (!windowHeight || !backgroundSource) { - return null; + /** + * On each scroll, set the content offset + */ + handleScroll(eventData) { + const events = [ + { + nativeEvent: { + contentOffset: { + y: this.state.scrollY + } + } + } + ]; + const config = {}; + + if (typeof this.props.onScroll === 'function') { + config.listener = eventData => this.props.onScroll(eventData) } + + return Animated.event(events, config); + } + + /** + * Render the Parallax view + * @returns {XML} + */ + render() { + const { style, header, windowHeight, scrollableViewStyle } = this.props; + + const noHeaderStyle = { + paddingTop: windowHeight + }; + return ( - - {/* - !!blur && (BlurView || (BlurView = require('react-native-blur').BlurView)) && - - */} - + + {this.renderBackground()} + + this._scrollView = component} + style={[ styles.scrollView, header ? {} : noHeaderStyle ]} + onScroll={this.handleScroll()} + scrollEventThrottle={16} + > + {this.renderHeader()} + + + {this.props.children} + + + ); - }, + } - renderHeader: function () { - var { windowHeight, backgroundSource } = this.props; - var { scrollY } = this.state; - if (!windowHeight || !backgroundSource) { + /** + * Renders the background component / background image + * @returns {Node} + */ + renderBackground() { + const { windowHeight, background } = this.props; + const { scrollY } = this.state; + + if (!windowHeight || !background) { return null; } + + const style = { + height: windowHeight, + transform: [ + { + translateY: scrollY.interpolate({ + inputRange: [ -windowHeight, 0, windowHeight], + outputRange: [ windowHeight / 2, 0, -windowHeight / 3 ] + }) + }, + { + scale: scrollY.interpolate({ + inputRange: [ -windowHeight, 0, windowHeight ], + outputRange: [ 2, 1, 1 ] + }) + } + ] + }; + + if (typeof background === 'string') { + return ( + + ); + } + + if ( + typeof background === 'object' && + background !== null && + typeof background.uri === 'string' + ) { + return ( + + ); + } + return ( - - {this.props.header} + + {React.cloneElement(background, { style })} - ); - }, + ) + } + + /** + * Render the header (on top of the background) + * @returns {Node} + */ + renderHeader() { + const { windowHeight, background, header } = this.props; + const { scrollY } = this.state; + + if (!windowHeight || !background || !header) { + return null; + } + + const style = { + position: 'relative', + height: windowHeight, + opacity: scrollY.interpolate({ + inputRange: [ -windowHeight, 0, windowHeight / 1.2 ], + outputRange: [1, 1, 0] + }), + }; - render: function () { - var { style, ...props } = this.props; return ( - - {this.renderBackground()} - { this._scrollView = component; }} - {...props} - style={styles.scrollView} - onScroll={Animated.event( - [{ nativeEvent: { contentOffset: { y: this.state.scrollY }}}] - )} - scrollEventThrottle={16}> - {this.renderHeader()} - - {this.props.children} - - - + + {header} + ); } -}); +} -var styles = StyleSheet.create({ +const styles = StyleSheet.create({ container: { flex: 1, borderColor: 'transparent', @@ -147,16 +223,7 @@ var styles = StyleSheet.create({ background: { position: 'absolute', backgroundColor: '#2e2f31', - width: screen.width, - resizeMode: 'cover' - }, - blur: { - position: 'absolute', - left: 0, - right: 0, - top: 0, - bottom: 0, - backgroundColor: 'transparent', + width: screen.width }, content: { shadowColor: '#222', @@ -168,4 +235,6 @@ var styles = StyleSheet.create({ } }); -module.exports = ParallaxView; +Object.assign(ParallaxView.prototype, ScrollableMixin); + +export default ParallaxView; From d7c95a9bfebd240741c3aae29c697edd01da10e0 Mon Sep 17 00:00:00 2001 From: Jakob Kerkhove Date: Wed, 7 Jun 2017 11:35:05 +0200 Subject: [PATCH 2/6] Use AnimatedKeyboardAwareScrollView --- lib/ParallaxView.js | 5 +++-- package.json | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/ParallaxView.js b/lib/ParallaxView.js index 5fdc2df..593bd4a 100644 --- a/lib/ParallaxView.js +++ b/lib/ParallaxView.js @@ -1,5 +1,6 @@ import React, { Component } from 'react'; import { Dimensions, StyleSheet, View, ScrollView, Animated } from 'react-native'; +import { AnimatedKeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'; import ScrollableMixin from 'react-native-scrollable-mixin'; const screen = Dimensions.get('window'); @@ -99,7 +100,7 @@ class ParallaxView extends Component > {this.renderBackground()} - this._scrollView = component} style={[ styles.scrollView, header ? {} : noHeaderStyle ]} @@ -113,7 +114,7 @@ class ParallaxView extends Component > {this.props.children} - + ); } diff --git a/package.json b/package.json index f27ae2e..32d844d 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,8 @@ }, "homepage": "https://github.com/lelandrichardson/react-native-parallax-view", "dependencies": { - "react-native-scrollable-mixin": "^1.0.1" + "react-native-scrollable-mixin": "^1.0.1", + "react-native-keyboard-aware-scroll-view": "dejakob/react-native-keyboard-aware-scroll-view#master" }, "peerDependencies": { "react-native": ">=0.8.0 || 0.8.0-rc || 0.8.0-rc.2 || 0.8.0-rc.3" From 9382b340fae67640c8cd077e560aefca711ed3ab Mon Sep 17 00:00:00 2001 From: Jakob Kerkhove Date: Wed, 7 Jun 2017 12:00:51 +0200 Subject: [PATCH 3/6] Revert "Use AnimatedKeyboardAwareScrollView" This reverts commit d7c95a9bfebd240741c3aae29c697edd01da10e0. --- lib/ParallaxView.js | 5 ++--- package.json | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/ParallaxView.js b/lib/ParallaxView.js index 593bd4a..5fdc2df 100644 --- a/lib/ParallaxView.js +++ b/lib/ParallaxView.js @@ -1,6 +1,5 @@ import React, { Component } from 'react'; import { Dimensions, StyleSheet, View, ScrollView, Animated } from 'react-native'; -import { AnimatedKeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'; import ScrollableMixin from 'react-native-scrollable-mixin'; const screen = Dimensions.get('window'); @@ -100,7 +99,7 @@ class ParallaxView extends Component > {this.renderBackground()} - this._scrollView = component} style={[ styles.scrollView, header ? {} : noHeaderStyle ]} @@ -114,7 +113,7 @@ class ParallaxView extends Component > {this.props.children} - + ); } diff --git a/package.json b/package.json index 32d844d..f27ae2e 100644 --- a/package.json +++ b/package.json @@ -23,8 +23,7 @@ }, "homepage": "https://github.com/lelandrichardson/react-native-parallax-view", "dependencies": { - "react-native-scrollable-mixin": "^1.0.1", - "react-native-keyboard-aware-scroll-view": "dejakob/react-native-keyboard-aware-scroll-view#master" + "react-native-scrollable-mixin": "^1.0.1" }, "peerDependencies": { "react-native": ">=0.8.0 || 0.8.0-rc || 0.8.0-rc.2 || 0.8.0-rc.3" From aa0cc634cb62f3c4347bc149f604d2a9e00abe89 Mon Sep 17 00:00:00 2001 From: Jakob Kerkhove Date: Thu, 8 Jun 2017 11:47:45 +0200 Subject: [PATCH 4/6] Create README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 7d72c32..9c83bdb 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +* DEPRECATED - I will no longer maintain this repo * + # react-native-parallax-view Parallax view for vertical scrollview with a header image and header content From 7ca046ed1ed1ddd5ef809f4321c3fe09b37e55cf Mon Sep 17 00:00:00 2001 From: Jakob Kerkhove Date: Thu, 8 Jun 2017 11:48:16 +0200 Subject: [PATCH 5/6] Create README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9c83bdb..9700889 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -* DEPRECATED - I will no longer maintain this repo * +**DEPRECATED - I will no longer maintain this repo** # react-native-parallax-view From 0d92fb6d14435d1d02ff11788b57565be8c251bc Mon Sep 17 00:00:00 2001 From: Jakob Kerkhove Date: Thu, 8 Jun 2017 14:20:17 +0200 Subject: [PATCH 6/6] Create README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9700889..6ee4f28 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -**DEPRECATED - I will no longer maintain this repo** +**DEPRECATED - I will no longer maintain this repo. Consider using [https://github.com/dejakob/react-native-keyboard-aware-parallax-scroll-view](https://github.com/dejakob/react-native-keyboard-aware-parallax-scroll-view)** # react-native-parallax-view