useEffect(() => {
if (pokemonAllList.length <= 1) {
return;
}
//pokemonAllList의 데이터가 저장되기 전에 받아왔을 경우는 동작 안하게 막음
const pokemonList = [];
const slideItemList = [];
//2가지가 나눠져있는 이유는, 10마리 포켓몬 배열과 슬라이드에 쓸 배열을 나눠주기 위해서
const duplicateCheck = new Set();
//set자료형을 이용해 중복을 방지하였다.
//숫자가 중복이 되면 원하는 개수보다 적은 개수를 얻을 수 있기 때문에,
for문이 아닌 while문을 사용했다.
while (pokemonList.length <= 9) {
const randomNum = Math.floor(Math.random() * pokemonAllList.length + 1);
if (duplicateCheck.has(randomNum)) {
continue;
}
duplicateCheck.add(randomNum);
pokemonList.push(pokemonAllList[randomNum]);
slideItemList.push(pokemonAllList[randomNum]);
}
for (let i = 1; i <= viewSlideNumber; i++) {
slideItemList.push(pokemonList[i - 1]);
}
setTodayPokemon([...slideItemList]);
}, [pokemonAllList]);
for (let i = 1; i <= viewSlideNumber; i++) {
slideItemList.push(pokemonList[i - 1]);
}
이런식으로 복사본이 생기게 되면, 동작을 어떻게 할 것이냐!
위의 이미지와 같이, 복사본들이 전부다 보여지게 되었을 때
transition의 값을 0으로 만들고 슬라이드를 맨처음으로 보낸다, 그런 다음 다시 원래의 설정으로 돌아오게 한다!
css
<ul
className="flex items-center m-auto"
onMouseEnter={() => {
stopInterval();
}}
onMouseLeave={() => {
startInterval();
}}
style={{
width: `${(todayPokemon.length * 100) / viewSlideNumber}%`,
//전체 width는 포켓몬의 갯수로 해주되, 보여주고싶은 만큼 나눈다.
transform: `translateX(-${(100 / todayPokemon.length) * curIdx}%)`,
//X축으로 슬라이드 아이템의 크기만큼 움직인다.
transition: `all ${slideTransition}ms`,
}}
>
{todayPokemon?.map(({ name, url }, idx) => {
const id = url.split("/")[url.split("/").length - 2];
return (
<li
key={idx}
style={{
width: `${100 / viewSlideNumber}%`,
//자식요소는 부모요소에서 width을 나눠가지기 때문에 100에서 보여지는 숫자만 나누면 된다.
padding: `0 1rem`,
}}
>
<PokemonCard name={name} id={String(id)} />
</li>
);
})}
</ul>
useEffect(() => {
if (curIdx >= todayPokemon.length - viewSlideNumber + 1) {
//복제한 슬라이드들이 전부다 보여지는 시점에 동작하게 만들었다.
setSlideTranstion(0);
setCurIdx(0);
//슬라이드가 넘어온 순간 transition을 0으로 만들어 효과를 없애고 curIdx값을 0으로 만들어 처음으로 보내버린다.
setTimeout(() => {
setSlideTranstion(transition);
setCurIdx((prev) => prev + 1);
}, 10);
//슬라이드가 넘어온 순간에 텀이 생기는데, 그 텀을 최소화 하기위에 setTimeout를 사용하였다.
}
}, [curIdx, todayPokemon.length, transition, slideTransition]);
<ul
className="flex items-center m-auto"
onMouseEnter={() => {
stopInterval();
}}
onMouseLeave={() => {
startInterval();
}}
style={{
width: `${(todayPokemon.length * 100) / viewSlideNumber}%`,
transform: `translateX(-${(100 / todayPokemon.length) * curIdx}%)`,
transition: `all ${slideTransition}ms`,
}}
>
여기는 간단하게 슬라이드가 동작되는 ul에 마우스를 올리면 멈추고, 마우스가 떠나면 움직이게끔 하였다!
예전에 바닐라자바스크립트로 슬라이드를 구현해본 경험이 있어서, 정말 쉽게 잘 할 줄 알았는데 setInterval동작부터 되게 정신 없었고,
그 당시에 만들 때는, 블로그 게시글을 거의 복붙해서 진행을 한 느낌이 든다. 지금은 왜 저게 이렇게 되는지 정확하게 설명은 아직은 못하지만!
적어도 내 스스로가 원하는대로 수정은 할 수 있을 것 같다.
설연휴는 푹 쉬고! 설연휴 다음날부터 또 다시 달려보려고 한다!!