UNPKG

react-native-parallax-swiper

Version:
234 lines (199 loc) 11.9 kB
# React Native Parallax Swiper [![npm](https://img.shields.io/npm/v/react-native-parallax-swiper.svg?style=flat-square)](https://www.npmjs.com/package/react-native-parallax-swiper) [![npm](https://img.shields.io/npm/dm/react-native-parallax-swiper.svg?style=flat-square)](https://www.npmjs.com/package/react-native-parallax-swiper) [![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier) Configurable parallax swiper based on an iOS pattern. **Features** * **Flexible.** Pass your own Animated.Value and use that value for both ParallaxSwiper and your own UI. * **Performant.** Leverages useNativeDriver for 60FPS and no latency. * **Cross-platform.** Implement your parallax on both iOS and Android. * **Progress Bar.** Horizontal or vertical progress bar. ![Twitter Moments Demo](https://user-images.githubusercontent.com/10658888/30244667-636cfc0e-9588-11e7-9805-3a0c5649ab4b.gif) ![Vevo Demo](https://user-images.githubusercontent.com/10658888/30244668-66164c3a-9588-11e7-9cfa-c0c5dc29090c.gif) ![Lightbox Demo](https://user-images.githubusercontent.com/10658888/30244669-68924b4e-9588-11e7-9426-b081953115fc.gif) ## Examples <img alt="React Native Parallax Swiper Expo QR code" src="images/QR-code.png" width="160px"/> Check out the GIF examples above via [Expo](https://expo.io/@zachgibson/ParallaxSwiperExample). Or clone this repo and: ```shell $ cd examples/ParallaxSwiperExample $ npm install $ react-native link $ react-native run-ios ``` ## Installation ```shell $ npm install react-native-parallax-swiper --save ``` ## Usage ```JSX import React from "react"; import { Animated, Text, View, Image, StyleSheet, Dimensions } from "react-native"; import { ParallaxSwiper, ParallaxSwiperPage } from "react-native-parallax-swiper"; const { width, height } = Dimensions.get("window"); export default class App extends React.Component { myCustomAnimatedValue = new Animated.Value(0); getPageTransformStyle = index => ({ transform: [ { scale: this.myCustomAnimatedValue.interpolate({ inputRange: [ (index - 1) * (width + 8), // Add 8 for dividerWidth index * (width + 8), (index + 1) * (width + 8) ], outputRange: [0, 1, 0], extrapolate: "clamp" }) }, { rotate: this.myCustomAnimatedValue.interpolate({ inputRange: [ (index - 1) * (width + 8), index * (width + 8), (index + 1) * (width + 8) ], outputRange: ["180deg", "0deg", "-180deg"], extrapolate: "clamp" }) } ] }); render() { return ( <ParallaxSwiper speed={0.5} animatedValue={this.myCustomAnimatedValue} dividerWidth={8} dividerColor="black" backgroundColor="black" onMomentumScrollEnd={activePageIndex => console.log(activePageIndex)} showProgressBar={true} progressBarBackgroundColor="rgba(0,0,0,0.25)" progressBarValueBackgroundColor="white" > <ParallaxSwiperPage BackgroundComponent={ <Image style={styles.backgroundImage} source={{ uri: "https://goo.gl/wtHtxG" }} /> } ForegroundComponent={ <View style={styles.foregroundTextContainer}> <Animated.Text style={[styles.foregroundText, this.getPageTransformStyle(0)]} > Page 1 </Animated.Text> </View> } /> <ParallaxSwiperPage BackgroundComponent={ <Image style={styles.backgroundImage} source={{ uri: "https://goo.gl/gt4rWa" }} /> } ForegroundComponent={ <View style={styles.foregroundTextContainer}> <Animated.Text style={[styles.foregroundText, this.getPageTransformStyle(1)]} > Page 2 </Animated.Text> </View> } /> <ParallaxSwiperPage BackgroundComponent={ <Image style={styles.backgroundImage} source={{ uri: "https://goo.gl/KAaVXt" }} /> } ForegroundComponent={ <View style={styles.foregroundTextContainer}> <Animated.Text style={[styles.foregroundText, this.getPageTransformStyle(2)]} > Page 3 </Animated.Text> </View> } /> </ParallaxSwiper> ); } } const styles = StyleSheet.create({ backgroundImage: { width, height }, foregroundTextContainer: { flex: 1, alignItems: "center", justifyContent: "center", backgroundColor: "transparent" }, foregroundText: { fontSize: 34, fontWeight: "700", letterSpacing: 0.41, color: "white" } }); ``` ## ParallaxSwiper Props | Prop | Type | Default | Description | | ------------------------------------- | -------------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | **`speed`** | _Number_ | `0.25` | This number determines how fast `BackgroundComponent` moves. Set to 0 for no movement at all, set to 1 and background will move as fast as the scroll. | | **`dividerWidth`** | _Number_ | `8` | The width of the divider between each page. (horizontal only) | | **`dividerColor`** | _String_ | `black` | Color of divider. | | **`backgroundColor`** | _String_ | `black` | ParallaxSwiper’s background color. | | **`scrollToIndex`** | _Number_ | 0 | Scroll to page with a smooth animation. _Note_: You need to use state if you want to change index any other time than when component is rendered. | | **`onMomentumScrollEnd`** | _Function_ | `N/A` | Fired when ScrollView stops scrolling and is passed the current page index. | | **`animatedValue`** | _Number (Animated.Value)_ | `0` | Optionally pass a new instance of Animated.Value to access the animated value outside of ParallaxSwiper. | | **`vertical`** | _Boolean_ | `false` | When true, ParallaxSwiper’s children are arranged vertically in a column instead of horizontally in a row. For now only iOS supports this. | | **`showsHorizontalScrollIndicator`** | _Boolean_ | `false` | When true, shows a horizontal scroll indicator. The default value is false. | | **`showsVerticalScrollIndicator`** | _Boolean_ | `false` | When true, shows a vertical scroll indicator. The default value is false. | | **`children`** | _React component (ParallaxSwiperPage)_ | `N/A` | Each top-level ParallaxSwiperPage child. | | **`showProgressBar`** | _Boolean_ | false | When true, a progress bar will render on bottom for horizontal and left on vertical. | | **`progressBarThickness`** | _Number_ | 4 | Thickness translates to height for horizontal and width for vertical progress bar. | | **`progressBarBackgroundColor`** | _String_ | `rgba(255,255,255,0.25)` | Background color of progress bar background. | | **`progressBarValueBackgroundColor`** | _String_ | `white` | Background color of progress bar value background. | ## ParallaxSwiperPage Props | Prop | Type | Default | Description | | ------------------------- | --------------- | ------- | ---------------------------------------------------------------------------------------------- | | **`BackgroundComponent`** | _React element_ | `N/A` | This component will render in the background of the page and will be animated based on scroll. | | **`ForegroundComponent`** | _React element_ | `N/A` | This component will render in the foreground of the page. | ## TODO * [x] Create Expo demos * [x] Create examples * [x] Expose current index * [x] Support scrollToIndex * [x] Fix Android * [x] Expose Animated.Value for animation outside of ParallaxSwiper * [ ] Add drag effects e.g. zoom, blur, darken * [ ] Expose rest of [ScrollView](http://facebook.github.io/react-native/releases/0.47/docs/scrollview.html#scrollview) props * [ ] Use FlatList instead of ScrollView ## Why another parallax component? 😒 This component is inspired by an iOS pattern that no react-native-parallax-whatever previously delivered. It emulates this pattern by using the [ScrollView](http://facebook.github.io/react-native/releases/0.48/docs/scrollview.html) component which has features like velocity, paging, and platform specific easing curves; It also has optional dividers to split up each page. You can see this pattern in apps like [iOS Camera Roll](https://goo.gl/GY3bFQ), [Twitter Moments](https://goo.gl/CvzCQA), [Kylie Jenner’s app](https://goo.gl/yDB69S), [Vevo’s app](https://goo.gl/FMSSeF), and more. ## Contributors | [<img src="https://avatars0.githubusercontent.com/u/2807897?v=4&s=460" width="80px;"/><br /><sub>Chris LeBlanc</sub>](https://github.com/LeBlaaanc)<br />[💻] | | :-----------------------------------------------------------------------------------------------------------------------------------------------------------: | ## Questions or suggestions? Hit me up on [Twitter](https://twitter.com/zacharykeith_), or create an [issue](https://github.com/zachgibson/react-native-parallax-swiper/issues). ## Copyright Copyright (c) 2017 [Zachary Gibson](http://zachgibsondesign.com/) Licensed under the MIT license.