슬라이드를 직접 구현해보았다!

Hwang Tae Young·2023년 1월 20일
0
post-thumbnail

슬라이드를 구현해 보자,,,,!

✅ 구현할때, 생각 했던 것

  1. 주어진 배열에서 중복없이 10가지를 뽑아 슬라이드에 보여준다
  2. 슬라이드는 한 방향으로 움직일것이며, 끝과 처음이 이어지는 무한루프로 동작한다.
  3. 슬라이드에 마우스를 올렸을 때는 멈춘다

✅ 첫번째,

  • 주어진 배열에서 중복없이 10가지를 뽑아 슬라이드에 보여준다
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]);

✅ 두번째,

  • 슬라이드는 한 방향으로 움직일것이며, 끝과 처음이 이어지는 무한루프로 동작한다.

    기본적으로 이런식으로 내가 설정한 view갯수에 맞춰서 슬라이드가 움직일 것인데,

    이렇게 끝에 왔을때 슬라이드를 뒤에가 더이상 없는 현상이 발생한다!
    그래서 아래의 코드처럼 슬라이드를 추가해 주었고, 단방향으로 진행 할것이기 때문에 뒤에만 넣어주었다.
    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동작부터 되게 정신 없었고,
그 당시에 만들 때는, 블로그 게시글을 거의 복붙해서 진행을 한 느낌이 든다. 지금은 왜 저게 이렇게 되는지 정확하게 설명은 아직은 못하지만!
적어도 내 스스로가 원하는대로 수정은 할 수 있을 것 같다.
설연휴는 푹 쉬고! 설연휴 다음날부터 또 다시 달려보려고 한다!!

profile
더 나은 개발자가 되기 위해...☆

0개의 댓글