혼자 이것저것 공부해보는/디즈니 앱 플러스 클론 코딩

swiper 모듈을 이용한 터치 슬라이드 구현하기

silver님 2024. 8. 1. 16:55

swiper 모듈을 이용한 터치 슬라이드 구현하기

 

 

 

● Swiper 모듈 설치 

npm install swiper --save

 

 

Row.js 

import axios from '../api/axios';
import React, { useCallback, useEffect, useState } from 'react';
import "./Row.css";
import MovieModal from './MovieModal';

import { Navigation, Pagination, Scrollbar, A11y } from 'swiper/modules';
import { Swiper, SwiperSlide } from 'swiper/react';

import "swiper/css";
import "swiper/css/navigation";
import "swiper/css/scrollbar";
import "swiper/css/pagination";
import styled from 'styled-components';

const Row = ({ title, id, fetchUrl }) => {
  const [Movies, setMovies] = useState([]); // 초기 상태를 빈 배열로 설정
  const [modalOpen, setModalOpen] = useState(false);
  const [movieSelected, setMovieSelection] = useState({});

  const fetchMovieData = useCallback(async () => {
    try {
      const response = await axios.get(fetchUrl);
      console.log('response', response);
      setMovies(response.data.results);
    } catch (error) {
      console.error('Failed to fetch movies:', error);
    }
  }, [fetchUrl]);

  useEffect(() => {
    fetchMovieData();
  }, [fetchMovieData]);

  const handleClick = (movie) => {
    setModalOpen(true);
    setMovieSelection(movie);
  }

  return (
    <Container>
      <h2>{title}</h2>
      <Swiper
        // install Swiper modules
        modules={[Navigation, Pagination, Scrollbar, A11y]}
        loop={true}  // loop 기능을 사용할 것인지
        navigation   // arrow 버튼 사용 유무 
        pagination={{ clickable: true }}  // 페이지 버튼 보이게 할지
        breakpoints={{
          1378: {
            slidesPerView: 6, // 한번에 보이는 슬라이드 개수 
            slidesPerGroup: 6, 
          },
          998: {
            slidesPerView: 5, // 한번에 보이는 슬라이드 개수 
            slidesPerGroup: 5, 
          },
          625: {
            slidesPerView: 4, // 한번에 보이는 슬라이드 개수 
            slidesPerGroup: 4, 
          },
          0: {
            slidesPerView: 3, // 한번에 보이는 슬라이드 개수 
            slidesPerGroup: 3, 
          },

        }}
      >
        <Content id={id}>
          {Movies && Movies.map(movie => (
            <SwiperSlide key={movie.id}>
              <Wrap>
                <img
                  src={`https://image.tmdb.org/t/p/original/${movie.backdrop_path}`}
                  alt={movie.name} // alt 속성 추가
                  onClick={() => handleClick(movie)}
                />
              </Wrap>
            </SwiperSlide>
          ))}
        </Content>
      </Swiper>

      {modalOpen && (
        <MovieModal
          {...movieSelected}
          setModalOpen={setModalOpen}
        />
      )}
    </Container>
  );
};

export default Row;

const Container = styled.div`
  padding: 0 0 26px; 
`;

const Content = styled.div``;

const Wrap = styled.div`
  width: 95%;
  height: 95%;
  padding-top: 56.25%;
  border-radius: 10px;
  box-shadow: rgb(0 0 0/69%) 0px 26px 30px -10px, 
              rgb(0 0 0/73%) 0px 16px 10px -10px; 
  cursor: pointer;
  overflow: hidden;
  position: relative;
  transition: all 250ms cubic-bezier(0.25, 0.46, 0.45, 0.94) 0s;
  border: 3px solid rgba(249, 249, 249, 0.1); 

  img {
    inset: 0px;
    display: block;
    height: 100%;
    object-fit: cover;
    opacity: 1;
    position: absolute;
    width: 100%;
    transition: opacity 500ms ease-in-out;
    z-index:1;
  }
  &:hover {
    box-shadow: rgb(0 0 0 / 80%) 0px 40px 58px -16px,
      rgb(0 0 0 / 72%) 0px 30px 22px -10px;
    transform: scale(0.98);
    border-color: rgba(249, 249, 249, 0.8);
  }
`;

 

 

Row.css

.swiper-pagination {
  text-align: right !important;
}

.swiper-pagination-bullet {
  background: gray !important;
  opacity: 1 !important;
}

.swiper-pagination-bullet-active {
  background-color: white !important;
}

.swiper-button-prev {
  color: white !important;
}

.swiper-button-next {
  color: white !important;
}

.swiper-button-next::after, .swiper-button-prev::after {
  font-size: 1.3rem !important;
  font-weight: 600 !important;
}
728x90
반응형