Open In App

Create an Image Carousal using React-Native

Last Updated : 22 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will build the Image Carousal using React Native language. In this interactive application, we have taken some sample GFG course images which are automatically and manually scrolled. When the user clicks on the image, the additional information about that course is shown in a modal with the course name and description. We have styled the appearance using basic styling properties.

Preview of final output: Let us have a look at how the final output will look like.

image_123986672

Prerequisites

Approach to Creating Image Carousel

The code snippet below is built in React Native which is the basic and simple implementation of Image Coarousal. In this application, we have used the useState hook to manage the state of the application. useEffect is used to manage the automatic scrolling and useRef to update the DOM. Here, we have taken the Image component where we are rendering the sample GFG course images through their URLs. Then, we create the Carousal effects and simultaneously build the Modal component which will show the information of course when the image is been clicked.

Steps to install & configure React Native:

Step 1: Create a react native application by using this command:

npx create-expo-app image-carousal

Step 2: After creating your project folder, i.e. image-carousal, use the following command to navigate to it:

cd  image-carousal

The updated dependencies in package.json file will look like:

"dependencies": {
"expo": "~49.0.15",
"expo-status-bar": "~1.6.0",
"react": "18.2.0",
"react-native": "0.72.6"
}

Project Structure:

PS

Example: Implementation of the above approach using React JS. Functionalities contain files as follows:

  • App.js: It is a parent component that calls the Image component in it.
  • Image.js: This is the component that is responsible for rendering the images and also provides the functionality of carousal with modal.

Javascript




// App.js
import React from 'react';
import { StyleSheet, View, Text } from 'react-native';
import ImageCarousel from './Image';
export default function App() {
    return (
        <View style={styles.container}>
            <Text style={styles.title}>
                GeeksforGeeks
            </Text>
            <Text style={styles.subtitle}>
                Image Carousel in React-Native
            </Text>
            <ImageCarousel />
        </View>
    );
}
const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#f5fcff',
    },
    title: {
        fontSize: 24,
        fontWeight: 'bold',
        color: 'green',
        marginBottom: 10,
    },
    subtitle: {
        fontSize: 18,
        color: '#333',
        marginBottom: 20,
    },
});


Javascript




// Image.js
import React, { useState, useEffect, useRef } from 'react';
import {
    View,
    Text,
    Image,
    StyleSheet,
    ScrollView,
    Dimensions,
    TouchableOpacity,
    Animated,
    Modal,
} from 'react-native';
const { width } = Dimensions.get('window');
const height = (width * 14) / 20;
const gfgImages = [
];
const gfgCourses = [
    {
        title: 'DSA to Development Coding Guide',
        description: 'Learn the essentials of Data Structures and Algorithms for development.',
    },
    {
        title: 'Full Stack Node.js',
        description: 'Master the art of Full Stack Development with Node.js.',
    },
    {
        title: 'GATE Data Science and AI',
        description: 'Prepare for GATE with a focus on Data Science and Artificial Intelligence.',
    },
    {
        title: 'Data Science Live',
        description: 'Explore the world of Data Science through live projects and examples.',
    },
];
const ImageCarousel = () => {
    const [activeInd, setActiveInd] = useState(0);
    const [modalShow, setModalShow] = useState(false);
    const [autoScrollEnabled, setAutoScrollEnabled] = useState(true);
    const scrollX = new Animated.Value(0);
    const scrollViewRef = useRef();
    const imageClickFunction = (ind) => {
        setActiveInd(ind);
        setModalShow(true);
    };
    useEffect(() => {
        let inter;
        if (autoScrollEnabled) {
            inter = setInterval(() => {
                const newInd = (activeInd + 1) % gfgImages.length;
                setActiveInd(newInd);
                scrollViewRef.current.scrollTo({ x: newInd * width, animated: true });
            }, 4000);
        }
        return () => clearInterval(inter);
    }, [activeInd, autoScrollEnabled]);
 
    return (
        <View style={styles.container}>
            <ScrollView ref={scrollViewRef}
                        horizontal
                        pagingEnabled
                        showsHorizontalScrollIndicator={false}
                        onMomentumScrollEnd={(event) => {
                            const newIndex = Math.floor
                            (event.nativeEvent.contentOffset.x / width);
                            setActiveInd(newIndex);
                }}
                onScroll={Animated.event(
                    [{ nativeEvent: { contentOffset: { x: scrollX } } }],
                    { useNativeDriver: false }
                )}>
                {gfgImages.map((image, index) => (
                    <TouchableOpacity   key={index}   
                                        activeOpacity={0.9}
                                        style={styles.imageContainer}   
                                        onPress={() => imageClickFunction(index)}>
                        <Image source={{ uri: image }} style={styles.image} />
                    </TouchableOpacity>
                ))}
            </ScrollView>
            <View style={styles.pagination}>
                {gfgImages.map((_, index) => (
                    <Animated.View key={index}
                                   style={[styles.paginationDot,{
                                    opacity: scrollX.interpolate({
                                    inputRange: [
                                        (index - 1) * width,
                                        index * width,
                                        (index + 1) * width,
                                    ],
                                    outputRange: [0.5, 1, 0.5],
                                    extrapolate: 'clamp',
                                })}]}/>
                ))}
            </View>
            <Modal animationType="slide"
                   transparent={true}
                   visible={modalShow}
                   onRequestClose={() => setModalShow(false)}>
                <View style={styles.modalContainer}>
                    <View style={styles.modalContent}>
                        <Text style={styles.modalTitle}>
                            {gfgCourses[activeInd].title}
                        </Text>
                        <Text style={styles.modalDescription}>
                            {gfgCourses[activeInd].description}
                        </Text>
                        <TouchableOpacity style={styles.closeButton}
                                          onPress={() => setModalShow(false)}>
                            <Text style={styles.closeButtonText}>Close</Text>
                        </TouchableOpacity>
                    </View>
                </View>
            </Modal>
        </View>
    );
};
const styles = StyleSheet.create({
    container: {
        width,
        height,
        backgroundColor: '#272',
        borderRadius: 10,
        overflow: 'hidden',
    },
    imageContainer: {
        width,
        height,
        borderRadius: 10,
        overflow: 'hidden',
    },
    image: {
        width,
        height,
        resizeMode: 'cover',
        borderRadius: 10,
        borderWidth: 4,
        borderColor: '#ff0000',
    },
    pagination: {
        flexDirection: 'row',
        position: 'absolute',
        bottom: 20,
        alignSelf: 'center',
    },
    paginationDot: {
        width: 10,
        height: 10,
        borderRadius: 5,
        backgroundColor: '#6b52ae',
        margin: 8,
    },
    modalContainer: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: 'rgba(0, 0, 0, 0.5)',
    },
    modalContent: {
        backgroundColor: '#fff',
        borderRadius: 10,
        padding: 20,
        width: width - 40,
        alignItems: 'center',
    },
    modalTitle: {
        fontSize: 24,
        fontWeight: 'bold',
        marginBottom: 10,
        color: '#6b52ae',
    },
    modalDescription: {
        fontSize: 18,
        textAlign: 'center',
        marginBottom: 20,
        color: '#555',
    },
    closeButton: {
        backgroundColor: '#4a3',
        padding: 12,
        borderRadius: 8,
        alignSelf: 'stretch',
        alignItems: 'center',
        marginTop: 10,
    },
    closeButtonText: {
        color: '#fff',
        fontWeight: 'bold',
        fontSize: 16,
    },
});
export default ImageCarousel;


Steps to run the application:

Step 1: Run the App via the following command.

npx expo start

Step 2: Run the command according to your Operating System.

  • Android
npx react-native run-android
  • IOS
npx react-native run-ios

Output:

Output



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads