넷플릭스 처럼 영화들의 슬라이더를 보여주자
Home에서 Banner만든 밑에 넣어줄 것이다.
원래는 Sliders로 따로 컴포넌트를 만들어서 api 데이터를 넘겨주는 식으로 하고 싶었는데
타입스크립트라서 방법이 너무 까다로움 ㅜ 그래서 실패...
const offset = 6;
...
<Slider>
<AnimatePresence>
<Row>
{nowPlayingData?.results
.slice(1)
.slice(offset * index, offset * index + offset)
.map((movie) => (
<Box
key={movie.id}
bgPhoto={makeImagePath(movie.backdrop_path, "w500")}
/>
))}
</Row>
</AnimatePresence>
</Slider >
나중에 넣을 애니메이션을 위해 AnimatePresence로 감싸주고
slice함수를 이용해준다
Banner에서 이미 첫번째 result의 데이터가 쓰였음으로 그거 제외하고
한 화면에 6(offset)개의 데이터들만 보이도록 설정한다
const rowVariants = {
hidden:{
x:window.outerWidth + 10,
},
visible: {
x: 0,
},
exit:{
x:-window.outerWidth - 10,
},
};
...
const incraseIndex = () => {
if (nowPlayingData) {
if (leaving) return;
toggleLeaving();
const totalMovies = nowPlayingData.results.length - 1;
const maxIndex = Math.floor(totalMovies / offset) - 1;
setBack(false);
setIndex((prev) => (prev === maxIndex ? 0 : prev + 1));
}
};
const toggleLeaving = () => setLeaving((prev) => !prev);
...
<AnimatePresence initial = {false} onExitComplete={toggleLeaving}>
{/* 맨 처음에는 애니 작동 x */}
<Row
variants={rowVariants}
initial="hidden"
animate="visible"
exit="exit"
transition={{ type: "tween", duration: 1 }}
key={index}
>
{nowPlayingData?.results
.slice(1)
.slice(offset * index, offset * index + offset)
.map((movie) => (
<Box
key={movie.id}
bgPhoto={makeImagePath(movie.backdrop_path, "w500")}
/>
))}
</Row>
<Next onClick = {incraseIndex} whileHover={{scale:1.2}}> <BiArrowFromLeft/></Next>
</AnimatePresence>
...
next에 해당하는 버튼을 누르면 다음 영화들 목록으로 넘어가는 애니메이션을 만든다.
onEixtComplete 속성은 버튼을 연속해서 누를시 애니메이션이 이상하게 작동되는 것을 막는다
window.outerWidth : 브라우저 전체의 너비
window.outerHeight : 브라우저 전체의 높이
window.innerWidth : 브라우저 화면의 너비
window.innerHeight : 브라우저 화면의 높이
현재 6개의 box들이 브라우저 전제의 너비만큼 지정되어 있으므로 window.outerWidth를 이용해서 x값에 대한 애니메이션을 주었다
const rowVariants = {
hidden: (back:boolean)=> ({
x: back ? -window.outerWidth - 10 : window.outerWidth + 10,
}),
visible: {
x: 0,
},
exit:(back:boolean)=> ( {
x: back ? window.outerWidth + 10 : -window.outerWidth - 10,
}),
};
...
<AnimatePresence custom = {back} initial = {false} onExitComplete={toggleLeaving}>
{/* 맨 처음에는 애니 작동 x */}
<Row
variants={rowVariants}
initial="hidden"
animate="visible"
exit="exit"
transition={{ type: "tween", duration: 1 }}
key={index}
custom = {back}
>
{nowPlayingData?.results
.slice(1)
.slice(offset * index, offset * index + offset)
.map((movie) => (
<Box
key={movie.id}
bgphoto={makeImagePath(movie.backdrop_path, "w500")}
/>
))}
</Row>
<Prev onClick = {increaseIndex} whileHover = {{scale:1.2}} key = "increase"><BiArrowFromRight/></Prev>
<Next onClick = {decreaseIndex} whileHover = {{scale:1.2}} key = "decrease"><BiArrowFromLeft/></Next>
</AnimatePresence>
custom을 통해 props를 지정한 애니메이션을 지정해줬다
그러므로 뒤로 가는 애니메이션도 가능!!
만들다 보니까 스크롤이 자꾸 눈에 거슬려서 아예 안 보이게 해줬다
스크롤바 안 보이게
body{-ms-overflow-style:none; }
body::-webkit-scrollbar { display:none; }
완성!
하나의 슬라이더만 넣는 것이 아니라 api별로 총 4개의 슬라이더를 가져올것이다.
이걸 prop으로 넘겨서 Slider라는 컴포넌트에 따로 만들것이다
근데!!! 이걸 하는게 드럽게 오래 걸렸다 원래는
//Home
...
<Slider data = {nowPlayingData}/>
//Slider
function Slider(data:IGetMoviesResult){
...
}
이런 식으로 넘겼는데
'{ data: IGetMoviesResult | undefined; }' 형식은 'IntrinsicAttributes & IGetMoviesResult' 형식에 할당할 수 없습니다.'IntrinsicAttributes & IGetMoviesResult' 형식에 'data' 속성이 없습니다
'{ dates?: { maximum: string; minimum: string; } | undefined; results?: IMovie[] | undefined; total_pages?: number | undefined; total_results?: number | undefined; }' 형식은 'IGetMoviesResult' 형식에 할당할 수 없습니다.'dates' 속성의 형식이 호환되지 않습니다.'{ maximum: string; minimum: string; } | undefined' 형식은 '{ maximum: string; minimum: string; }' 형식에 할당할 수 없습니다.'undefined' 형식은 '{ maximum: string; minimum: string; }' 형식에 할당할 수 없습니다.
결국 다른 노마드코더 챌린지 우수작품 받으신 분의 코드를 참고해서 이렇게 해결했다
// Home
...
<Slider
title="Now Playing Movies"
data={nowPlayingData?.results ?? []}/>
// Slider
interface SlidersProps {
title?: string;
data: IMovie[];
}
function Slider({title, data }: SlidersProps) {
...
}
근데..... 분명 저런 비슷한 형태로 시도를 했을 땐 실패했는데...................뭐 해결됐으니까......
앞으로 object를 prop으로 넘길땐 이 코드 참고해야겠다
암튼 !신나게 데이터 연결해서 완성시켰다
NETFLIX CLONE(React)(3) - Search (0) | 2022.08.12 |
---|---|
NETFLIX CLONE(React)(2-4) - 상세 페이지 구현 (0) | 2022.08.04 |
NETFLIX CLONE(React)(2-3) - Box animation (0) | 2022.07.30 |
NETFLIX CLONE(React)(2-1) - Home Screen (0) | 2022.07.24 |
NETFLIX CLONE(React)(1) - Header 설정 (0) | 2022.07.22 |