본문 바로가기
Js&React 실습/JSprac

[JS]이미지 슬라이더 만들기2(캐러셀)+변경

by sweesweet 2022. 7. 10.

https://sweesweett.github.io/jsprac/imgslider2.html

이전글에 낱장으로 다시 도전해보겠다고 괜한말을...해서....(아님)  다시 시도해보았다. 문제는 맨끝장에 도달하면 맨 앞장으로갈때 필름을 와랄라ㅏ로랄 돌리듯 돌아간다는점...? 가끔오류가 나면 빈 캐러셀이 날 맞이한다는점? 이유는 모르겠다

맨끝장에 도달할 때 자연스럽게 돌아가게 하는 방법을 찾아봤는데, 다들 맨 앞장과 맨 뒷장의 복사본을 맨앞과 맨앞에 붙여서 자연스럽게 만드는 것 같았당...

캐러셀의 원리

방법은 이렇다 div.visible을 저만한 크기(img와 같은크기)로 만들고 div.img__wrapper(img들을 감싸고있음)를 감싸게 한다. 그런다음 css로 overflow:hidden을 주게 하면, 딱 저영역만 보이게되고 img_wrapper를 움직이게하면 마치 슬라이더처럼 보이게 되는 것이다. 

여기서 주의해야 할 점은, img__wrapper는 position absolute 를 주어야한다

다른사람들은 transform:translateX()를 쓴 걸 볼 수있었다. 차이점을 사실 잘 모르겠당...<- 위치를 변경하면 (top,left...속성) 리페인트가 발생하기 때문에 효율적으로 transform을 쓰는게 낫다구 수업에서배움(성능저하초래)

 

js 코드

const imgWrapper = document.querySelector('.img__wrapper');
const newWidth = document.querySelector('.img__visible').offsetWidth;
let num = 0;
document.querySelector('#nextBtn').onclick = () => {
  if (num === imgWrapper.children.length - 1) {
    num = 0;
  } else {
    num++;
  }
  imgWrapper.style.left = `-${num * newWidth}px`;

};
document.querySelector('#prevBtn').onclick = () => {
  if (num === 0) {
    num = imgWrapper.children.length;
  }
  num--;

  imgWrapper.style.left = `-${num * newWidth}px`;
};

html코드

  <body>
    <div class="gotoback" onclick="location.href='./index.html'">뒤로가기</div>
    <div class="container">
      <h2>Image Slider</h2>
      <div class="img__visible">
        <div class="img__wrapper">
          <img class="img1" src="./img/slider/haechi_01.png" alt="메롱해치1" />
          <img class="img2" src="./img/slider/haechi_02.png" alt="메롱해치2" />
          <img class="img3" src="./img/slider/haechi_03.png" alt="메롱해치3" />
          <img class="img4" src="./img/slider/haechi_04.png" alt="메롱해치4" />
        </div>
      </div>
      <div class="btns">
        <button class="material-icons" id="prevBtn">navigate_before</button>
        <button class="material-icons" id="nextBtn">navigate_next</button>
      </div>
    </div>
 
  </body>

+0725 변경

카드 스와이퍼로 포인터 함수를 배운 김에(복습겸) 한번 잡아서 끌어 넘기는 스와이퍼를 만들어 보려했다

근데 이미지가 잡아끌어지는 현상이 발생해서 제대로 pointermove가 활성화되지 않아서 div로 변경했다

js코드의 버튼 부분은 위와 동일하다

<!-- 변경된 부분 -->
<div class="img__visible">
        <div class="img__wrapper"></div>
      </div>
//왼쪽버튼에 있는 함수를 toPrev로, 오른쪽에있는 함수를 toNext로 이름을 달았당.
const imgs = [// 배열로 해당 내용 담기
  {
    img: './img/slider/haechi_01.png',
    title: '메롱해치1',
    content: '너무귀엽죠?이렇게 귀여운 캐릭터가있다니!',
  },
  {
    img: './img/slider/haechi_02.png',
    title: '메롱해치2',
    content: '이미지슬라이더 테스트중이에요!',
  },
  {
    img: './img/slider/haechi_03.png',
    title: '메롱해치3',
    content: '미는거 해볼려고 지금 이러고있어요!',
  },
  {
    img: './img/slider/haechi_04.png',
    title: '메롱해치4',
    content: '으하하하 생각보다 힘들당',
  },
];
for (let i = 0; i < imgs.length; i++) {
  makeImgCard(i); // 함수실행으로 해당 카드 넣기
}

function makeImgCard(num) {
  const newImgCard = document.createElement('div');
  newImgCard.className = 'card';
  newImgCard.style.backgroundImage = `url(${imgs[num].img})`;
  const title = document.createElement('div');
  title.className = 'title';
  title.textContent = imgs[num].title;
  const content = document.createElement('div');
  content.className = 'content';
  content.textContent = imgs[num].content;
  newImgCard.prepend(title, content);
  imgWrapper.append(newImgCard);
}// imgWrapper에 넣기

function onPointerDown(e) {// visibleImg를 눌렀을 때 발생하는 이벤트
  startX = e.clientX + num * newWidth;// 이부분이 키포인트! 
  //visibleImg에 걸었기 떄문에 imgWrapper의 길이도 생각을 해야함
  console.log(startX);
  visibleImg.addEventListener('pointermove', onPointerMove);
  visibleImg.addEventListener('pointerup', onPointerUp);
  visibleImg.addEventListener('pointerleave', onPointerUp);
}
function onPointerMove(e) {
  moveX = e.clientX - startX;
  // console.log(moveX);
  imgWrapper.style.transform = `translateX(${moveX}px)`;
} // 왜안될까
function onPointerUp(e) {
  visibleImg.removeEventListener('pointermove', onPointerMove);
  visibleImg.removeEventListener('pointerup', onPointerUp);
  visibleImg.removeEventListener('pointerleave', onPointerUp);
  if (Math.abs(moveX) > (num + 0.6) * newWidth) {// 사진의 절반이상 넘어갔을 때 다음페이지로
    toNext();
  } else if (Math.abs(moveX) < (num - 0.6) * newWidth) {// 사진의 절반이상 갔을 때 이전 페이지로
    toPrev();
  }
  //0727 추가-해당이 안될땐 다시 그 슬라이더로 돌아감
  imgWrapper.style.transform = `translateX(-${num * newWidth}px)`;
}

document.querySelector('#nextBtn').onclick = toNext;
document.querySelector('#prevBtn').onclick = toPrev;
visibleImg.addEventListener('pointerdown', onPointerDown);

잡아서 당길때 계속 텍스트나 버튼에 드래그가 생겨서

css에

  user-select: none;

를 추가하였다!