쇼핑몰과 같은 웹 페이지에서 위와 같이 홈 화면에 슬라이더가 있는 걸 흔히 볼 수 있다. Slider라고도 하지만 웹 용어로 Carousel이라고도 한다. react-slick 라이브러리가 유명하고 간단해서 그걸 사용했는데, 다른 라이브러리들도 많고 구현할 수 있는 선택의 폭이 넓다. (swiper 등)
react-slick 라이브러리
리액트에서 제공하는 라이브러리로 슬라이더(캐러셀)을 쉽게 구현하도록 해준다. 공식 문서에서 바로 사용할 수 있는 대표적인 예시 슬라이더들을 제공해준다.
Get Started | React Slick
React slick is a carousel component built with React. It is a react port of slick carousel
react-slick.neostack.com
npm install react-slick --save
라이브러리에 css를 함께 적용시키기 위해 아래 slick-carousel을 함께 다운로드 받는다.
npm install slick-carousel --save
사용법
아래는 공식 문서에서 설명하는 사용 예시이다.
import React from "react";
import Slider from "react-slick";
export default function SimpleSlider() {
var settings = {
dots: true,
infinite: true,
speed: 500,
slidesToShow: 1,
slidesToScroll: 1,
};
return (
<Slider {...settings}>
<div>
<h3>1</h3>
</div>
<div>
<h3>2</h3>
</div>
<div>
<h3>3</h3>
</div>
<div>
<h3>4</h3>
</div>
<div>
<h3>5</h3>
</div>
<div>
<h3>6</h3>
</div>
</Slider>
);
}
Slider 컴포넌트를 하나 만들고 settings 변수를 통해 옵션을 컴포넌트에 전달할 수 있다. 사용할 수 있는 옵션의 가짓수가 꽤 많아서 다양한 커스텀이 가능한 게 장점이다. (아래 외에도 더 많은 옵션이 있다.)
const settings = {
dots: true, // 네비게이션 도트 표시 여부
infinite: true, // 무한 루프 여부
speed: 500, // 슬라이드 전환 속도 (ms)
slidesToShow: 1, // 한 번에 보여줄 슬라이드 개수
slidesToScroll: 1, // 한 번에 넘길 슬라이드 개수
autoplay: true, // 자동 재생 여부
autoplaySpeed: 3000, // 자동 재생 스피드
pauseOnHover: true // 마우스를 올리면 자동 재생을 멈출 지 여부
arrows: true, // 좌우 화살표 표시 여부
};
css를 적용하기 위해선 설명한 바와 같이 slick- carousel을 다운로드 받고 아래와 같이 css 파일을 임포트해야 한다.
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
css 적용을 생략하면 아래처럼 이상하게 나온다. (당연한 건데 처음에 이것때문에 헤맸음)
커스텀 화살표
원하는 디자인대로 구현하기 위해 화살표를 svg로 대체하고 싶었다. 그리고 화살표를 슬라이더 밖이 아닌 슬라이더 이미지 위에 배치해두고자 했다.
화살표를 커스텀하기 위해 화살표들을 따로 선언한 뒤 옵션에서 prevArrow와 nextArrow를 변수들로 대체해주었다.
화살표들을 absolute로 지정해서 슬라이더 위에 올라가도록 배치하였다.
커스텀 도트
위와 같이 슬라이드가 움직일 때마다 도트의 모양이 바뀌는 애니메이션을 적용하기 위해서 따로 css 파일을 만들었다.
css는 아래 블로그를 참고했습니다.
[react-slick] dots css 커스텀하기
react-slick라이브러리에서 dots를 바꾸기 위해서는 setting(props)값에 dotsClass를 추가해줘야 한다. default로 되어 있는 class 선택자 대신 dotsClass명으로 class 선택자명을 바꿔 커스텀이 가능하다. DOCS 버튼
kimyk60.tistory.com
// BannerSlider.css
.dots_custom {
display: inline-block;
vertical-align: middle;
margin: auto 0;
padding: 0;
}
.dots_custom li {
list-style: none;
cursor: pointer;
display: inline-block;
margin: 0 6px;
padding: 0;
}
.dots_custom li button {
border: none;
background-color: white;
color: transparent;
cursor: pointer;
display: block;
height: 8px;
width: 8px;
border-radius: 100%;
padding: 0;
}
.dots_custom li.slick-active button {
width: 30px;
border-radius: 100px;
}
/* 애니메이션 */
.dots_custom {
@apply inline-flex items-center justify-center space-x-2;
}
.dots_custom li {
@apply list-none cursor-pointer inline-flex items-center justify-center;
}
.dots_custom li button {
@apply border-0 bg-white text-transparent cursor-pointer block h-2 w-2 rounded-full p-0 transition-all duration-300 ease-in-out;
}
.dots_custom li.slick-active button {
@apply w-7 rounded-full;
}
전체 코드
"use client";
import React from "react";
import Slider from "react-slick";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
import "./BannerSlider.css";
const CustomPrevArrow = (props: any) => {
const { onClick } = props;
return (
<div className="absolute left-4 top-1/2 transform -translate-y-1/2 z-10">
{/* svg */}
</div>
);
};
const CustomNextArrow = (props: any) => {
const { onClick } = props;
return (
<div className="absolute right-4 top-1/2 transform -translate-y-1/2 z-10">
{/* svg */}
</div>
);
};
export default function BannerSlider() {
const settings = {
dots: true,
infinite: true,
speed: 500,
slidesToShow: 1,
slidesToScroll: 1,
autoplay: true,
autoplaySpeed: 3000,
prevArrow: <CustomPrevArrow />,
nextArrow: <CustomNextArrow />,
appendDots: (dots: any) => (
<div
style={{
width: "100%",
position: "absolute",
bottom: "24px",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<ul> {dots} </ul>
</div>
),
dotsClass: "dots_custom",
};
const slides = [
{ id: 1, image: "/img/slider1.png", alt: "Slide 1" },
{ id: 2, image: "/img/slider1.png", alt: "Slide 2" },
{ id: 3, image: "/img/slider1.png", alt: "Slide 3" },
];
return (
<Slider {...settings}>
{slides.map((slide) => (
<div key={slide.id}>
<img
src={slide.image}
alt={slide.alt}
className="w-full h-auto object-cover"
/>
</div>
))}
</Slider>
);
}
'넥스트' 카테고리의 다른 글
[Next.js] TMDB API를 이용한 영화 앱 (Typescript) (3) | 2024.09.05 |
---|