#3 NETFLIX SLIDER
<Slider>
<Row>
<Box />
<Box />
<Box />
<Box />
<Box />
<Box />
</Row>
<Row>
<Box />
<Box />
<Box />
<Box />
<Box />
<Box />
</Row>
<Row>
<Box />
<Box />
<Box />
<Box />
<Box />
<Box />
</Row>
</Slider>
motion을 사용할 때 위와 같이 모든걸 render하지않고 key만 사용하면 한 줄에서 표현 가능 !
<AnimatePresence>
해당 컴포넌트를 사용하게 되면 나타날때나 특정 요소가 사라지기 전에 지정한 애니메이션 효과
<Slider
variants={}
initial={}
animate={}
exit={}
>
</AnimatePresence>
const rowVariants = {
hidden: {
x: window.innerWidth,
},
visible: {
x: 0,
},
exit: {
x: -window.innerWidth,
},
};
window.outerWidth : 브라우저 전체의 너비
window.outerHeight : 브라우저 전체의 높이
window.innerWidth : 브라우저 화면의 너비
window.innerHeight : 브라우저 화면의 높이
outerWidth vs innerWidth 비교 이미지
https://www.cluemediator.com/how-to-get-the-window-size-in-javascript
How to get the window size in JavaScript - Clue Mediator
How to get the window size in JavaScript, How to get the size of the current Browser Window, get window width, get window height using JS
www.cluemediator.com
문제1. 빠르게 두번 누르면 큰 여백이 생김
-->ROW가 사라지기도전에 새 ROW가 연속으로 exit하게되어서
-->
const [leaving, setLeaving] = useState(false);
const increaseInex = () => {
if (leaving) return; //TRUE이면 INDEX 넘어가지않고 끝 / FALSE이면 = 처음이면
setLeaving(true); // /TRUE로 바뀌고
setIndex((prev) => prev + 1); /다음페이지로넘어감
};
큰 간격이 생기진 않지만
LEAVING이 항상 TRUE라 그다음으로 안넘어가
ANIMATEPRESENCE PROP사용
---> onExitComplete
exit 중인 모든 노드들이 애니메이션을 끝내면 실행됩니다.
ex) AnimatePresenceProps.onExitComplete?: (() => void) | undefined
https://www.framer.com/docs/animate-presence/###onexitcomplete
const increaseInex = () => {
if (leaving) return;
toggleLeaving();
setIndex((prev) => prev + 1);
};
const toggleLeaving = () => setLeaving((prev) => !prev);
<AnimatePresence initial={false} onExitComplete={toggleLeaving}>
문제2. 초기 화면에서 row가 우측에서 들어오는 문제
<AnimatePresence initial={false} onExitComplete={toggleLeaving}>
initial
initial={false}를 전달하면 AnimatePresence는 컴포넌트가 처음 렌더링될 때 자식의 초기 애니메이션을 비활성화합니다.
slice()
slice() 메서드는 어떤 배열의 begin부터 end까지(end 미포함)에 대한 얕은 복사본을 새로운 배열 객체로 반환합니다. 원본 배열은 바뀌지 않습니다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
Array.prototype.slice() - JavaScript | MDN
slice()** **메서드는 어떤 배열의 begin부터 end까지(end 미포함)에 대한 얕은 복사본을 새로운 배열 객체로 반환합니다. 원본 배열은 바뀌지 않습니다.
developer.mozilla.org
배경으로 사용한 첫번 째 영화 제외하고 적용시키기
{data?.results
.slice(1)
.slice(
offset * index,
offset * index + offset
)
.map((movie) => (
<Box
key={movie.id}
)}
page를 무한대로 늘릴 수 없어서
const increaseInex = () => {
if (data) {
if (leaving) return;
toggleLeaving();
const totalMovies = data?.results.length - 1;
const maxIndex = Math.floor(totalMovies / offset) - 1; //0부터 시작해야돼서
setIndex((prev) => (prev === maxIndex ? 0 : prev + 1));
}
};
배경 적용하기
const Box = styled(motion.div)<{ bgPhoto: string }>` 괄호가 있을 때는 여기다가 작성
background-color: white;
background-image: url(${(props) => props.bgPhoto});
background-size: cover;
background-position: center center;
height: 200px;
color: red;
font-size: 60px;
`;
{data?.results
.slice(1)
.slice(
offset * index,
offset * index + offset
)
.map((movie) => (
<Box
key={movie.id}
bgPhoto={makeImagePath(
movie.backdrop_path ,
"w500" //사이즈
)}
data?.results[0].backdrop_path 의 경우에는 data가 존재하지 않을 가능성이 있기 때문에 || "" 이 필요합니다.
Box 컴포넌트 안에서 movie.backdrop_path의 경우에는 movie라는 것은 이미 array를 map으로 순회하기 때문에 movie가 무조건 존재하는것으로 간주되기 때문에 ||""이 필요없습니다.
비슷한 이치로 data?.results[0].backdrop_path 에서
? 대신 ! 을 사용하면
data!.results[0].backdrop_path
data가 반드시 존재한다고 타입스크립트에 알려주는것이기 때문에 뒤쪽의 ||""가 필요 없습니다.