• 로그인
  • 장바구니에 상품이 없습니다.

home2 게시판 JavaScript, TS 게시판 캐러셀에 스와이프 기능 만들기

캐러셀에 스와이프 기능 만들기

3 글 보임 - 1 에서 3 까지 (총 3 중에서)
  • 글쓴이
  • #134599

    이가영
    참가자

    [1] HTML

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>캐러셀에 스와이프 기능</title>
      <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
      <link rel="stylesheet" href="./style.css">
    </head>
    <body>
      <!-- carousel(이미지 슬라이드) 제작 -->
       <div style="overflow:hidden;">
        <div class="slide-container">
          <div class="slide-box">
            < img src="./img/car1.png" alt="">
          </div>
          <div class="slide-box">
            < img src="./img/car2.png" alt="">
          </div>
          <div class="slide-box">
            < img src="./img/car3.png" alt="">
          </div>
        </div>
       </div>
       <div class="button-container">
        <button class="slide">버튼1</button>
        <button class="slide">버튼2</button>
        <button class="slide">버튼3</button>
        <button class="previous">이전</button>
        <button class="next">다음</button>
       </div>
      <script src="./script.js"></script>
      <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous">
      </script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"
        integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ=="
        crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    </body>
    </html>

    [2] CSS

    * {
      margin: 0; padding: 0;
    }
    button {
      border: none;
      border-radius: 5px;
      background-color: black;
      color: white;
      padding: 10px 20px;
      margin: 10px 0px;
      font-weight: bold;
      font-size: 13px;
    }
    .button-container {
      margin-left: 5px;
    }
    .slide {
      background-color: brown;
    }
    /* carousel */
    .slide-container {
      width: 300vw; /* 브라우저폭 */
      /* transition: all 1s; */
      margin: 20px 0px;
    }
    .slide-box {
      width: 100vw;
      float: left; /* 왼쪽 배치 */
    }
    .slide-box img {
      width: 100%;
    }

    [3] JavaScript

    // carousel
    const slidesContainer = document.querySelector('.slide-container');
    const slides = document.querySelectorAll('.slide-box');
    const slideBtnsContainer = document.querySelector('.button-container');
    const slideBtns = document.querySelectorAll("button[class='slide']");
    const slidePreviousBtn = document.querySelector('.previous');
    const slideNextBtn = document.querySelector('.next');
    var currentPos = 0;
    var slideNum = slides.length;
    // 슬라이드 버튼 이동 기능
    slideBtnsContainer.addEventListener('click', function(e){
        if (e.target && e.target.classList.contains('slide')){
            // 버튼 1, 2, 3
            const index = [...slideBtns].indexOf(e.target); // 눌린 버튼의 인덱스
            currentPos = index;
        } else if (e.target && e.target.classList.contains('previous')){
            // 이전 버튼
            currentPos--;
        } else if (e.target && e.target.classList.contains('next')){
            // 다음 버튼
            currentPos++;
        }
        if (currentPos < 0) currentPos = slideNum - 1;
        else if (currentPos > slideNum - 1) currentPos = 0;
        slidesContainer.style = `transform: translateX(-${currentPos * 100}vw)`;
    });
    // 스와이프 + 슬라이드 이동 기능
    function swipe(){
        var startPos = 0;
        var activateMousedown = false;
        // 마우스 누르고 있을 경우 현재 위치 읽기
        slidesContainer.addEventListener('mousedown', function(e) {
            activateMousedown = true;
            slidesContainer.querySelector('.slide-box>img').setAttribute('draggable', 'false');
            startPos = e.clientX; // 시작 위치
            console.log(startPos);
        });
        // 마우스 드래그 했을 때 슬라이드 이동
        slidesContainer.addEventListener('mousemove', function(e) {
            if (activateMousedown) {
                const distance = e.clientX - startPos;
                slidesContainer.style.transform = `translateX(${distance}px)`;
            }
        });
        // 마우스 뗐을 때 슬라이드 원위치 이동 or 슬라이드 전환
        slidesContainer.addEventListener('mouseup', function(e){
            const distance = e.clientX - startPos;
            activateMousedown = false;
            
            if (distance < -100) {
                currentPos++;
                // 첫 번째 이미지 스와이프 방지
                if (currentPos > slideNum - 1) currentPos = slideNum - 1;
            } else if (distance > 100) {
                currentPos--;
                // 마지막 이미지 스와이프 방지
                if (currentPos < 0) currentPos = 0;
            }
            // 슬라이드 위치 업데이트
            slidesContainer.style.transition = 'all 0.3s ease'; // 부드러운 애니메이션 추가
            slidesContainer.style = `transform: translateX(-${currentPos * 100}vw);`;
        });
    }
    swipe();
    
    
    자바스크립트 코드에서 캐러셀에 스와이프 기능을 만들 때 transition 속성을 넣어도 왜 슬라이드가 순간이동하는 것 처럼 보일까요?
    그리고 슬라이드에 마우스 드래그를 했을 때 왜 첫 번째 슬라이드가 보이나요?
    • 이 게시글은 이가영에 의해 5 월, 2 주 전에 수정됐습니다. 이유: heading 태그로 보이면 안 되는 게 heading 태그로 보여서 수정했습니다
    • 이 게시글은 이가영에 의해 5 월, 2 주 전에 수정됐습니다. 이유: 오타
    #134604

    codingapple
    키 마스터
    slidesContainer.style = `transform: translateX(-${currentPos * 100}vw);`;
    말고
    slidesContainer.style.transform = `translateX(-${currentPos * 100}vw);`;
    해봅시다
    
    아무사진이나 100px 드래그하면 전체박스를 +100px 움직이는데 +100px이면 1번사진만 보이는 위치겠군요
    #134618

    이가영
    참가자
    해결했습니다 감사합니다!
3 글 보임 - 1 에서 3 까지 (총 3 중에서)
  • 답변은 로그인 후 가능합니다.

About

현재 월 700명 신규수강중입니다.

  (09:00~20:00) 빠른 상담은 카톡 플러스친구 코딩애플 (링크)
  admin@codingapple.com
  이용약관
ⓒ Codingapple, 강의 예제, 영상 복제 금지
top

© Codingapple, All rights reserved. 슈퍼로켓 에듀케이션 / 서울특별시 강동구 고덕로 19길 30 / 사업자등록번호 : 212-26-14752 온라인 교육학원업 / 통신판매업신고번호 : 제 2017-서울강동-0002 호 / 개인정보관리자 : 박종흠