npm i swiper
// import Swiper core and required modules import { Navigation, Pagination, Scrollbar, A11y } from 'swiper/modules'; import { Swiper, SwiperSlide } from 'swiper/react'; // Import Swiper styles import 'swiper/css'; import 'swiper/css/navigation'; import 'swiper/css/pagination'; import 'swiper/css/scrollbar'; export default () => { return ( <Swiper // install Swiper modules modules={[Navigation, Pagination, Scrollbar, A11y]} spaceBetween={50} slidesPerView={3} navigation pagination={{ clickable: true }} scrollbar={{ draggable: true }} onSwiper={(swiper) => console.log(swiper)} onSlideChange={() => console.log('slide change')} > <SwiperSlide>Slide 1</SwiperSlide> <SwiperSlide>Slide 2</SwiperSlide> <SwiperSlide>Slide 3</SwiperSlide> <SwiperSlide>Slide 4</SwiperSlide> ... </Swiper> ); };
freeMode : false, // 슬라이드 넘길 때 위치 고정 여부 autoHeight : true, // 현재 활성 슬라이드높이 맞게 높이조정 a11y : false, // 접근성 매개변수(접근성 관련 대체 텍스트 설정이 가능) resistance : false, // 슬라이드 터치 저항 여부 slideToClickedSlide : true, // 해당 슬라이드 클릭시 슬라이드 위치로 이동 allowTouchMove : true, // (false-스와이핑안됨)버튼으로만 슬라이드 조작이 가능 watchOverflow : true // 슬라이드가 1개 일 때 pager, button 숨김 여부 설정 slidesOffsetBefore : number, // 슬라이드 시작 부분 여백 slidesOffsetAfter : number,
EX) Row.js
import React, { useCallback, useEffect, useState } from 'react' import { axiosInnstance } from '../api/axios'; import './Row.css'; import MovieModal from './MovieModal'; import { Autoplay, Navigation, Pagination, Scrollbar, A11y } from 'swiper/modules'; import { Swiper, SwiperSlide } from 'swiper/react'; import 'swiper/css'; import 'swiper/css/navigation'; import 'swiper/css/pagination'; import 'swiper/css/scrollbar'; import styled from 'styled-components'; const Row = ({title, id, delay,fetchUrl}) => { const [movies, setMovies] = useState([]); const [modalOpen, setModalOpen] = useState(false); //클릭한 영화 정보 가져오기 const [movieSelected, setMovieSelection] = useState({}); const fetchMovieData= useCallback( async () => { const response= await axiosInnstance.get(fetchUrl, {}); setMovies(response.data.results); }, [fetchUrl] ); useEffect(() =>{ fetchMovieData(); }, [fetchMovieData]); const handleClick=useCallback((movie)=>{ console.log("movie ",movie); setModalOpen(true); setMovieSelection(movie); }, [setModalOpen, setMovieSelection]); return ( <Container> <h2>{title}</h2> <Swiper modules={[Autoplay, Navigation, Pagination, Scrollbar, A11y]} spaceBetween={10} slidesPerView={5} navigation //arrow 버튼 사용유무 pagination={{ clickable: true }} // 페이지 버튼 사용여부 scrollbar={{ draggable: true }} // onSwiper={(swiper) => console.log(swiper)} // onSlideChange={() => console.log('slide change')} // loop={true} //loop 기능을 사용할지 여부 => 버전업 기본값 true 사용하면 waring speed={1500} //슬라이드 이동 속도 autoplay={{ delay: delay, disableOnInteraction: false, }} breakpoints={{ 1968: { slidesPerView: 6, slidesPerGroup: 6, }, 1568: { slidesPerView: 5, slidesPerGroup: 5, }, 1378: { slidesPerView: 4, slidesPerGroup: 4, }, 1060: { slidesPerView: 3, slidesPerGroup: 3, }, 756: { slidesPerView: 2, slidesPerGroup: 2, }, 456: { slidesPerView:1, slidesPerGroup: 1, }, }} className="mySwiper" > {movies.map((movie, index) => ( <SwiperSlide className='row__poster' key={index}> <img key={movie.id} src={`https://image.tmdb.org/t/p/w300${movie.backdrop_path}`} alt={movie.title} onClick={()=>handleClick(movie)} /> </SwiperSlide> ))} </Swiper> {modalOpen && <MovieModal {...movieSelected} setModalOpen={setModalOpen} /> } </Container> ) } export default Row const Container=styled.div` padding: 0, 0 30px; `;
Row.css
.slider { position: relative; scroll-behavior: smooth !important; } .slider__arrow-left { background-clip: content-box; padding: 20px 0; box-sizing: border-box; transition: 400ms all ease-in-out; cursor: pointer; width: 80px; z-index: 1000; position: absolute; left: 0; top: 0; height: 100%; display: flex; align-items: center; justify-content: center; visibility: hidden; } .slider__arrow-right { padding: 20px 0; background-clip: content-box; box-sizing: border-box; transition: 400ms all ease-in-out; cursor: pointer; width: 80px; z-index: 1000; position: absolute; right: 0; top: 0; height: 100%; display: flex; align-items: center; justify-content: center; visibility: hidden; } .arrow { transition: 400ms all ease-in-out; font-size: 38px; font-weight: bold; } .arrow:hover { transition: 400ms all ease-in-out; transform: scale(1.5); } .slider:hover .slider__arrow-left { transition: 400ms all ease-in-out; visibility: visible; } .slider:hover .slider__arrow-right { transition: 400ms all ease-in-out; visibility: visible; } .slider__arrow-left:hover { background: rgba(20, 20, 20, 0.5); transition: 400ms all ease-in-out; } .slider__arrow-right:hover { background: rgba(20, 20, 20, 0.5); transition: 400ms all ease-in-out; } .row__posters { display: flex; overflow-y: hidden; overflow-x: scroll; padding: 20px 0 20px 20px; scroll-behavior: smooth !important; cursor: pointer; } .row__posters::-webkit-scrollbar { display: none; } .row__poster { object-fit: contain; width: 100%; max-height: 144px; margin-right: 10px; transition: transform 450ms; border-radius: 4px; } .row__poster:hover { transform: scale(1.08); } .row__posterLarge { max-height: 320px; } .row__posterLarge:hover { transform: scale(1.1); opacity: 1; } .row__arrow-left { position: absolute; top: 0; left: 20px; height: 100%; width: 32px; background: rgba(0, 0, 0, 0.2); display: flex; align-items: center; } .row__arrow-right { position: absolute; top: 0; right: 0px; height: 100%; width: 32px; background: rgba(0, 0, 0, 0.2); display: flex; align-items: center; } @media screen and (min-width: 1200px) { .row__poster { max-height: 160px; } .row__posterLarge { max-height: 360px; } } @media screen and (max-width: 768px) { .row__poster { max-height: 100px; } .row__posterLarge { max-height: 280px; } } .swiper-pagination{ text-align: right !important; } .swiper-pagination-bullet{ background: gray !important; opacity: 1 !important; } .swiper-pagination-bullet-active{ background-color: #fff !important; } .swiper-horizontal { text-align: center !important; } .swiper .swiper-button-next, .swiper .swiper-button-prev{ color: #fff; } .row__poster{ cursor: pointer; }
소스 :
https://github.com/braverokmc79/react-disney-plus-app
댓글 ( 0)
댓글 남기기