Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@kolking/react-native-parallax-swiper

Package Overview
Dependencies
Maintainers
0
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@kolking/react-native-parallax-swiper

React Native component for building an impressive horizontal swiper with a parallax effect.

  • 1.0.1
  • latest
  • Source
  • npm
  • Socket score

Version published
Maintainers
0
Created
Source

React Native Parallax Swiper

A React Native component for building an impressive horizontal swiper with a parallax effect. The parallax swiper is great for creating an onboarding UI for your app or for displaying multi-screen swipeable announcements that should catch users' attention. The component utilizes the Reanimated library to achieve seamless 120fps animations.

Installation

First of all, make sure you have installed and properly configured Reanimated. Please refer to the official installation guide.

yarn

yarn add @kolking/react-native-parallax-swiper

npm

npm install @kolking/react-native-parallax-swiper

Create Image Layers

To achieve the parallax effect, you need to create a set of image layers, with each layer representing a different depth of the scene. A minimum of 3 layers (though 5 would be better) is required for each slide. Your scene may contain details beyond the screen that will become visible during parallax movement. In such cases, make the layers wider than the device viewport. There are many instructions on how to create layers for parallax scenes, so if you've never done it before, be sure to Google it. Below is a simple example of the layers for a single slide:

layers

Basic Example

import React from 'react';
import { Swiper, SwiperView } from '@kolking/react-native-parallax-swiper';

const slide1 = [
  require('./assets/Slide1-Layer1.png'),
  require('./assets/Slide1-Layer2.png'),
  require('./assets/Slide1-Layer3.png'),
];

const slide2 = [
  require('./assets/Slide2-Layer1.png'),
  require('./assets/Slide2-Layer2.png'),
  require('./assets/Slide2-Layer3.png'),
];

const MyComponent = () => (
  <Swiper>
    <SwiperView index={1} images={slide1} />
    <SwiperView index={2} images={slide2} />
  </Swiper>
);

export default MyComponent;

Swiper Props

The Swiper is a ScrollView component, so you can pass ScrollViewProps such as onScroll, onMomentumScrollEnd, and so on.

PropTypeDefaultDescription
currentnumberThe current slide index, used in controlled mode
styleViewStyleStyle object applied to the ScrollView
onChange(index: number) => voidThe callback that return the current slide index after change

SwiperView Props

PropTypeDefaultDescription
indexnumberThe view number (required)
imagesImageSourcePropType[]The array of image layers where background is the first and foreground is the last (required)
parallaxnumber1The amount of the parallax shift, where 0 means no parallax
stiffnessnumber50The stiffness of the spring animation
dampingnumber50The damping of the spring animation
massnumber1The mass of the spring animation
styleViewStyleStyle object applied to the view
contentStyleViewStyleStyle object applied to the content wrapper

Advanced Example

In the advanced example, the slides can also be swiped using buttons, and a page indicator is added to the bottom.

import React, { useCallback, useRef, useState } from 'react';
import {
  Animated,
  ImageSourcePropType,
  NativeScrollEvent,
  NativeSyntheticEvent,
  StyleSheet,
  Text,
  TouchableOpacity,
  useWindowDimensions,
  View,
} from 'react-native';
import { Swiper, SwiperView } from '@kolking/react-native-parallax-swiper';
import { PageIndicator } from 'react-native-page-indicator';

type Content = {
  title: string;
  text: string;
  images: ImageSourcePropType[];
};

const views: Content[] = [
  {
    title: 'Slide 1',
    text: 'Slide 1 description.',
    images: [
      require('./assets/Slide1-Layer1.png'),
      require('./assets/Slide1-Layer2.png'),
      require('./assets/Slide1-Layer3.png'),
    ],
  },
  {
    title: 'Slide 2',
    text: 'Slide 2 description.',
    images: [
      require('./assets/Slide2-Layer1.png'),
      require('./assets/Slide2-Layer2.png'),
      require('./assets/Slide2-Layer3.png'),
    ],
  },
];

type ButtonProps = {
  index: number;
  onPress: (index: number) => void;
};

const Button = ({ index, onPress }: ButtonProps) => {
  const isLast = index + 1 === views.length;

  const handlePress = useCallback(() => {
    onPress(isLast ? 0 : index + 1);
  }, [isLast, index, onPress]);

  return (
    <TouchableOpacity style={styles.button} activeOpacity={0.5} onPress={handlePress}>
      <Text style={styles.buttonText}>{isLast ? 'Start Over' : 'Next'}</Text>
    </TouchableOpacity>
  );
};

const MyComponent = () => {
  const { width } = useWindowDimensions();
  const [current, setCurrent] = useState(0);
  const currentPage = useRef(new Animated.Value(0)).current;

  const handleScroll = useCallback(
    ({ nativeEvent }: NativeSyntheticEvent<NativeScrollEvent>) => {
      currentPage.setValue(nativeEvent.contentOffset.x / width);
    },
    [currentPage, width],
  );

  return (
    <View style={styles.root}>
      <Swiper current={current} onChange={setCurrent} onScroll={handleScroll}>
        {views.map(({ title, text, images }, index) => (
          <SwiperView key={index} index={index} style={styles.view} images={images}>
            <Text style={styles.title}>{title}</Text>
            <Text style={styles.text}>{text}</Text>
            <Button index={index} onPress={setCurrent} />
          </SwiperView>
        ))}
      </Swiper>
      <View style={styles.pageIndicator}>
        <PageIndicator count={views.length} current={currentPage} color="white" />
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  root: {
    flex: 1,
  },
  view: {
    paddingVertical: 70,
    paddingHorizontal: 30,
    justifyContent: 'flex-end',
  },
  title: {
    fontSize: 22,
    fontWeight: '700',
    marginBottom: 10,
  },
  text: {
    fontSize: 15,
    marginBottom: 20,
  },
  button: {
    padding: 12,
    borderRadius: 5,
    backgroundColor: 'skyblue',
  },
  buttonText: {
    fontSize: 17,
    fontWeight: '700',
    textAlign: 'center',
  },
  pageIndicator: {
    left: 0,
    right: 0,
    bottom: 35,
    alignItems: 'center',
    position: 'absolute',
  },
});

export default MyComponent;

Feedback

I appreciate your feedback, so please star the repository if you like it. This is the best motivation for me to maintain the package and add new features. If you have any feature requests, found a bug, or have ideas for improvement, feel free to open an issue.

Also, please check out my other React Native components that might be a good fit for your project:

License

Licensed under the MIT license.

Keywords

FAQs

Package last updated on 21 Sep 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc