DEVLOG
Next.js ํ๋ก์ ํธ :: carousel ๊ตฌํํ๊ธฐ ๋ณธ๋ฌธ
๐ ๋ชฉ์ฐจ
๐ Carousel์ด๋?
ํํ ์ด๋ฌํ ํ์์ ๊ตฌ์กฐ๋ฅผ ์ฐ๋ฆฌ๋ ์ฌ๋ผ์ด๋๋ผ๊ณ ๋ถ๋ฅด๊ณคํ๋ค.
๊ทธ๋ฐ๋ฐ '์ฌ๋ผ์ด๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ'๋ผ๊ณ ๊ฒ์์ ํ๊ณ ์ฐพ์๋ณด๋ ค๊ณ ํ๋ ํ๊ตญ์์๋ง ์ด๋ฐ ๊ตฌ์กฐ๋ฅผ ์ฌ๋ผ์ด๋๋ผ๊ณ ํ๊ณ ์ฌ์ค์ carousel
์ด๋ผ๊ณ ๋ถ๋ฅด๋๊ฒ ๋ง๋ค.
carousel
์ ํ์ ๋ชฉ๋ง๋ผ๋ ๋ป! ๋น๋น ๋์๊ฐ๋,, ๊ทธ๋ฐ ๋๋!
์์ด๊ถ๋๋ผ์์ ์ด๋ฐ๊ฑธ ์ฌ๋ผ์ด๋๋ผ๊ณ ๋ถ๋ฅด๋ ๊ฒ ๊ฐ๋ค!
์ฌ์ค ์ค์ํ๊ฑด ์๋๋ฐ ์ฐพ์๋ณด๋ฉด์ ํฅ๋ฏธ๋ก์์ ๊ณต์ ํ๊ณ ์ถ์๋ค :)
๐ swiper
๋ฉ์ธํ์ด์ง์ ๋ค์ด๊ฐ ์บ๋ฌ์
์ ๊ตฌํํ๊ธฐ ์ํด ๋จผ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ถํฐ ์ ํํด์ผํ๋ค. ๋น์ฐํ ์ง์ ๋ง๋๋ ๊ฒ์ ๋๋ฌด ๋นํจ์จ์ ์ผ ๊ฒ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ค๊ณ ์ฐพ์๋ณด๋๋ฐ swiper
์ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํ๋ ๊ฒ ๊ฐ๊ณ ๊ณต์๋ฌธ์๋ ์ ๋ฆฌ๊ฐ ์ ๋์ด์๊ธธ๋ swiper
์ ์ ํํ๋ค.
๊ณต์ ์ฌ์ดํธ : https://swiperjs.com/react
ํฐ๋น ์ฌ์ดํธ ๋์์ธ์ ์ฐธ๊ณ ํ์ ๋ fadeํ๊ณผ carouselํ ์ด 2๊ฐ์ง์ ์ฌ๋ผ์ด๋๊ฐ ํ์ํ๋ฐ swiper
์ผ๋ก ๋๊ฐ์ง ๋ชจ๋ ๊ตฌํ์ด ๊ฐ๋ฅํ๋ค.
๊ทธ๋์ ์ด๋ฒ์๋ ํ์
์ ๋ฐ๋ผ ์ฌ์ฉํ ์ ์๋ ๊ณตํต ์ปดํฌ๋ํธ๋ฅผ ๋ง๋๋ ๊ฒ์ ์ง์คํ๋ค.
๊ธฐ๋ณธํ carousel
swiper
์ฌ์ฉ๋ฒ์ setting์ ์๋ ๊ฒ๋ค์ ์ ํ์ฉํ๋ฉด ๋งค์ฐ ๊ฐ๋จํ๋ค.
export const Carousel = (props: CarouselProps) => {
const { data } = props;
return (
<PosterLayout>
<Swiper
spaceBetween={10}
slidesPerView={3}
slidesPerGroup={3}
loop={false}
mousewheel={true}
navigation={true}
pagination={{
clickable: true,
}}
effect={"slide"}
autoplay={false}
breakpoints={
640: {
slidesPerView: 5,
slidesPerGroup: 5,
},
768: {
slidesPerView: 6,
slidesPerGroup: 6,
},
1024: {
slidesPerView: 7,
slidesPerGroup: 7,
},
1400: {
slidesPerView: 8,
slidesPerGroup: 8,
},
}
modules={[Navigation, Pagination, EffectFade, Mousewheel, Autoplay]}
>
<SwiperSlide>...</SwiperSlide>
</Swiper>
</PosterLayout>
);
};
fadeํ carousel
export const Carousel = (props: CarouselProps) => {
const { data, fade } = props;
return (
<PosterLayout fade={fade}>
<Swiper
spaceBetween={10}
slidesPerView={1}
slidesPerGroup={1}
loop={true} //๋ฃจํ๋ฐ๋ณต
navigation={true}
pagination={{
clickable: true,
}}
effect={"fade"} //fadeํ ์ดํํธ
autoplay={{ //์๋์ฌ์
delay: 5000,
disableOnInteraction: false,
}}
modules={[Navigation, Pagination, EffectFade, Mousewheel, Autoplay]}
onSlideChange={(c) => { //์ฌ๋ผ์ด๋ change์ ํ์ฌ index ๋ณ๊ฒฝ
setCurrentData(c.realIndex);
}}
>
</PosterLayout>
);
};
โ ๋ฌธ์ ๊ฐ ์๊ฒผ๋ค!
slide ๋ด๋ถ ๋ ์ด์์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋ณต๋ฌธ์ ๋๋ ค ์ถ๋ ฅํ๋ ๋ฐฉ์์ผ๋ก ์งํํ๋๋ฐ ๊ทธ๋ ๊ฒ ํ๋ ์ฐ์ธก ํ๋จ ์์ธํ๋ณด๊ธฐ ๋ฒํผ์ด ๊ฐ์ฅ ๋ง์ง๋ง ๋ฐ์ดํฐ ๊ฐ์ผ๋ก๋ง ์ถ๋ ฅ์ด ๋ผ์ ์ด๋ค ๋ฒํผ์ ๋๋ฌ๋ ๊ฐ์ฅ ๋ง์ง๋ง ์นด๋์ ์์ธ๋ก ์ด๋ํ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค...
fadeํ์ด๋ผ ์ฌ๋ผ์ด๋๊ฐ ์๋ก ์ถ์ ์ด ๋๋ฉด์ ๊ฐ์ฅ ๋ง์ง๋ง ๋ฒํผ๋ง ๋ ธ์ถ์ด ๋์ด์ ๊ทธ๋ฌ๋ ๊ฒ
๊ทธ๋์ ์ค๋ณต๋ ์ค์ผ๊ฒธ ๋ฒํผ์ ํ๋๋ก ์ ์งํ๊ณ ํ์ฌ ์ฌ๋ผ์ด๋์ id๋ฅผ ์์๋ด์ด state๋ก ๊ด๋ฆฌํ๋์์ผ๋ก ๋ณ๊ฒฝํ์ฌ ํด๊ฒฐํ๋ค.
const [fadeData, setFadeData] = useState<number[]>([]);
const [current, setCurrentData] = useState(0);
useEffect(() => {
if (fade && !fadeData.length) {
const _idData = data.map((item: movieResult) => item.id);
setFadeData(_idData);
}
}, [data, fade, fadeData]);
๐ carousel ์ปดํฌ๋ํธํ
์ฝ๊ฐ์ setting๊ณผ ์ถ๋ ฅํด๋ด๋ ํฌ์คํฐ์ ๊ตฌ์กฐ์ ์คํ์ผ๋ง ๋ค๋ฅด๊ธฐ๋๋ฌธ์ ์ด๋ฅผ ๊ณตํต๋๋ ๋ถ๋ถ์ ์ปดํฌ๋ํธ๋ก ์ฒ๋ฆฌํ๋ฉด ๋ ํธ๋ฆฌํ์ง ์์๊น?ํ๋ ์๊ฐ์ผ๋ก ์ปดํฌ๋ํธํ๋ฅผ ์งํํ๋ค.
export const Carousel = (props: CarouselProps) => {
const { data, fade } = props;
const [fadeData, setFadeData] = useState<number[]>([]);
const [current, setCurrentData] = useState(0);
useEffect(() => {
if (fade && !fadeData.length) {
//fade์ํ ๋ฐ์ดํฐ์ id์ ๋ณด๋ฅผ ์ ์ฅํ๋ ๋ฐฐ์ด
const _idData = data.map((item: movieResult) => item.id);
setFadeData(_idData);
}
}, [data, fade, fadeData]);
return (
<PosterLayout fade={fade}>
<Swiper
spaceBetween={10}
slidesPerView={fade ? 1 : 3}
slidesPerGroup={fade ? 1 : 3}
loop={fade || false}
mousewheel={!fade}
navigation={true}
pagination={{
clickable: true,
}}
effect={fade ? "fade" : "slide"}
autoplay={
fade
? {
delay: 5000,
disableOnInteraction: false,
}
: false
}
breakpoints={
fade
? {}
: {
640: {
slidesPerView: 5,
slidesPerGroup: 5,
},
768: {
slidesPerView: 6,
slidesPerGroup: 6,
},
1024: {
slidesPerView: 7,
slidesPerGroup: 7,
},
1400: {
slidesPerView: 8,
slidesPerGroup: 8,
},
}
}
modules={[Navigation, Pagination, EffectFade, Mousewheel, Autoplay]}
onSlideChange={(c) => {
fade && setCurrentData(c.realIndex);
}}
>
{data.map((result: movieResult) => {
const { id, title, poster_path, backdrop_path } = result;
return fade ? (
<SwiperSlide key={id}>
// fadeํ layout
</SwiperSlide>
) : (
<SwiperSlide key={id}>
// carouselํ layout
</SwiperSlide>
);
})}
</Swiper>
{fade && (
<div className="btn-more">
<Link href={`/contents/${fadeData[current]}`}>์์ธํ ๋ณด๊ธฐ </Link>
</div>
)}
</PosterLayout>
);
};
์์ฑ!!
๐ Next?
๋ค์์ ๊ฒ์์ด๋ ๋ฆฌ์คํธ ์ ์ฒด๋ณด๊ธฐ ํด๋ฆญ์ ๋ณด์ฌ์ง๋ ๋ฆฌ์คํธ๋ชจ๋์ ํ์ด์ง์ infinite scroll์ ๊ตฌํํ ์์ ์ด๋ค.
'frontend > next.js' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Next.js ํ๋ก์ ํธ :: ๋ฐฐํฌ(gh-pages, netlify, vercel) (1) | 2023.07.12 |
---|---|
Next.js ํ๋ก์ ํธ :: infinite scroll ๊ตฌํํ๊ธฐ (0) | 2023.07.12 |
Next.js ํ๋ก์ ํธ :: getServersideProps (0) | 2023.06.22 |
Next.js ํ๋ก์ ํธ :: Open API (TMDB), React-Query (0) | 2023.06.22 |
Next.js ํ๋ก์ ํธ :: ์ธํ (0) | 2023.06.22 |