Simple Is Best

23. [JavaScript] Hammer.js & 이미지 슬라이드 터치 기능 본문

JavaScript & JQuery

23. [JavaScript] Hammer.js & 이미지 슬라이드 터치 기능

데이터미널 2021. 8. 9. 19:10

이번 포스팅에서는 Hammer.js를 활용하여 터치 이미지 슬라이드 기능을 구현하는 방법에 대해서 알아보도록 하겠습니다. 

 

우선 본 포스팅에서 목적으로 하는 이미지 슬라이드 터치 기능을 구현하기 위해서 이미지 슬라이더(Carousel) 에 대해서 알아야 합니다. 참고 부탁드립니다. 

https://daterminal.tistory.com/61

 

12. [JS/JQuery] Carousel (이미지 슬라이더)

안녕하세요~ 이번 포스팅에서는 Carousel 에 대해서 알아보도록 하겠습니다. Carousel 이란? : '회전목마' 라는 뜻으로 이미지 슬라이더 (버튼을 누르면 다음 사진으로 슬그머니 넘어가는) 를 칭합니

daterminal.tistory.com

 

 

 

HTML

해당 HTML 에 대한 구조는 다음 이미지로 설명을 대체 하겠습니다. 

 

   <div style='position: relative; overflow: hidden'>
        <h4 class='text-center mt-4 product-pos'> Our Shirt Product</h4>
        <!-- 넘치는 화면은 숨겨주는 기능 overflow:hidden -->
        <div class='container-slide'>
            <div class='wrap-img'>
                <img src="../이미지파일/shirts1.jpg">
            </div>
            <div class='wrap-img'>
                <img src="../이미지파일/shirts2.jpg">
            </div>
            <div class='wrap-img'>
                <img src="../이미지파일/shirts3.jpg">
            </div>
            <div style='clear: both'></div>
        </div>

        <button class='btn-direct btn-left'>◀️</button>
        <button class='btn-direct btn-right'>▶️</button>
    </div>

 

CSS

.container-slide {
    width: 300vw;
}

.transform-auto{
    transition: transform 0.5s;
}

.wrap-img {
    width: 100vw;
    /* 상위 container가 width가 300vw임. viewport의 width의 100%를 차지하게 해주세요. */
    float: left;
    /* 왼쪽으로 나란히 정렬된다. */
    padding: 200px;
}

.wrap-img img {
    width: 100%;
}

.btn-direct {
    position: absolute;
    padding: 15px;
    border: 1px solid #eee;
    background-color: rgba(0, 0, 0, 0.7);
    border-radius: 10px;
    color: white;
}

.btn-right {
    right: 0;
    top: 50%;
}

.btn-left {
    left: 0;
    top: 50%;
}

.product-pos {
    position: absolute;
    top: 10%;
    left: 38%;
}

 


오늘 구현할 Hammer.js 라이브러리에 대해서 공부해보도록 하겠습니다. 

 

Hammer.js

이미지 슬라이더 터치 기능을 쉽게 구현 할 수 있게 해주는 JavaScript 라이브러리

궁극적으로 우리는 Hammer.js 에서 pan(터치) 이벤트 리스너를 사용할 것임

 

Hammer.js CDN 설치법

    <!--hammer.js 연결-->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js" integrity="sha256-eVNjHw5UeU0jUqPPpZHAkU1z4U+QFBBY488WvueTm88=" crossorigin="anonymous"></script>

 

Hammer.js 셋팅 방법

 

▷ 원하는 요소를 Hammer.js 에 등록하는 과정이다. 이해하려고 하지 말고 복사해서 붙여넣기 해서 사용하자.

▷ 주의 사항 : Hammer.js 를 사용하기 위해서 원하는 요소를 셀렉트 하기 위해서 JavaScript를 사용하자. JQuery 안먹힘!

▷ threshold : 이벤트가 실행되기 까지의 역치값, slide 기능 : Pan

var img = document.querySelectorAll('.slide-box img')[0];
    
var manager = new Hammer.Manager(img);
manager.add(new Hammer.Pan({ threshold: 0 }));
    
manager.on('pan', function(e){
  //이미지1이 pan 되었을 때 실행할 코드 
  //우리가 코딩할 메인 코드영역 부분
})

 


 

e.deltaX

: pan 이벤트 리스너에 붙어서 유저가 얼마만큼 어디로 터치했는지 알 수 있는 기능입니다. 

    manager.on('pan',function(e){
        console.log(e.deltaX); // 왼쪽 -> 오른쪽 : +(양수), 왼쪽 <- 오른쪽 : -(음수) 
    })

 

왼쪽에서 오른쪽으로 터치 할 시에는 음수(-) 가 콘솔창에 출력됨을 확인 할 수 있습니다. 

오른쪽에서 왼쪽으로 터치 할 시에는 양수(+) 가 콘솔창에 출력됨을 확인 할 수 있습니다.

 

 

e.isFinal

: 유저가 터치를 하고 마우스에서 손가락을 뗐을 때의 시점을 잡을 수 있습니다.

 

 

오늘의 main 코드 

첫번째 이미지에 대해서만 이미지 슬라이더를 구현해보도록 하겠습니다. 

우선 manager변수는 1번째 img를 컨트롤 하는 역할을 합니다. 

 // 이미지 1을 터치할 때
    manager.on('pan',function(e){
        console.log(e.deltaX); // 왼쪽 -> 오른쪽 : +(양수), 왼쪽 <- 오른쪽 : -(음수) 
        
        // 오른쪽에서 왼쪽으로 스크린을 터치했을 때 (오른쪽 상품으로 넘어가야 함)
        // 슬라이드 터치하는 동안에는 지연 없이 그냥 넘어가다가 사용자가 슬라이드 터치를 멈추면 자동으로 0.5초의 텀을 두고 자동으로 이동 한다. 
        
        // -> 이미지 2로 넘어가야 함
        if (e.deltaX < 0){ // 왼쪽 <- 오른쪽 
            $('.container-slide').css('transform', 'translateX(' + e.deltaX + 'vw)');
            
            // 어느정도 user 가 터치 이후에 손을 떼면 0.5초에 걸쳐서 서서히 자동으로 다음 물건으로 이동하게 해주는 코드
            // transform-auto에는 transition : transform 0.5s; 가 추가 되어 있다. 
            // 0.5초 이후에 바로 클래스를 제거하여 다음 유저의 터치에 지연이 없도록 setTimeout을 사용.
            
            if(e.isFinal){ // e.isFinal : user가 클릭하고 손가락을 떼었을 이벤트를 알려준다. 
                $('.container-slide').addClass('transform-auto');
                $('.container-slide').css('transform', 'translateX(-100vw)');
                setTimeout(()=>{
                    $('.container-slide').removeClass('transform-auto');    
                },500)
            }
           }
    })

 

 

 

오늘의 main 코드 

첫번째 이미지에 대해서만 이미지 슬라이더를 구현해보도록 하겠습니다. 

우선 manager변수는 1번째 img를 컨트롤 하는 역할을 합니다. 

 // 이미지 1을 터치할 때
    manager.on('pan',function(e){
        console.log(e.deltaX); // 왼쪽 -> 오른쪽 : +(양수), 왼쪽 <- 오른쪽 : -(음수) 
        
        // 오른쪽에서 왼쪽으로 스크린을 터치했을 때 (오른쪽 상품으로 넘어가야 함)
        // 슬라이드 터치하는 동안에는 지연 없이 그냥 넘어가다가 사용자가 슬라이드 터치를 멈추면 자동으로 0.5초의 텀을 두고 자동으로 이동 한다. 
        
        // -> 이미지 2로 넘어가야 함
        if (e.deltaX < 0){ // 왼쪽 <- 오른쪽 
            $('.container-slide').css('transform', 'translateX(' + e.deltaX + 'vw)');
            
            // 어느정도 user 가 터치 이후에 손을 떼면 0.5초에 걸쳐서 서서히 자동으로 다음 물건으로 이동하게 해주는 코드
            // transform-auto에는 transition : transform 0.5s; 가 추가 되어 있다. 
            // 0.5초 이후에 바로 클래스를 제거하여 다음 유저의 터치에 지연이 없도록 setTimeout을 사용.
            
            if(e.isFinal){ // e.isFinal : user가 클릭하고 손가락을 떼었을 이벤트를 알려준다. 
                $('.container-slide').addClass('transform-auto');
                $('.container-slide').css('transform', 'translateX(-100vw)');
                setTimeout(()=>{
                    $('.container-slide').removeClass('transform-auto');    
                },500)
            }
           }
    })

 

코드 해석

if (e.deltaX < 0){ // 왼쪽 <- 오른쪽 
            $('.container-slide').css('transform', 'translateX(' + e.deltaX + 'vw)');
            
            if(e.isFinal){ 
                $('.container-slide').addClass('transform-auto');
                $('.container-slide').css('transform', 'translateX(-100vw)');
                setTimeout(()=>{
                    $('.container-slide').removeClass('transform-auto');    
                },500)
            }
           }

 

▷ e.deltaX를 통해서 유저가 어느 방향으로 터치하는지 감지한다. 만약, 음수라면 오른쪽에서 왼쪽으로 터치 슬라이드 한 것이므로 user가 터치슬라이드 한 만큼만 이동해준다. 

 

▷ 만약 user가 슬라이드가 끝났다면 터치한 방향의 다음 물건을 자동으로 띄우기 위한 코드를 작성한다. 

하지만, 여기서 손가락을 바로 떼자마자 다음 물건으로 이동하는 것을 방지하기 위해서 .transform-auto 에  transition 속성을 추가하여 천천히 이동하게끔 만들어준다. 

 

▷ transition : transform 0.5s 를 통해서 자동으로 이동한 이후에 다음 터치에 대비하기 위해서 바로 해당 속성을 제거해 주어야 한다. 따라서 0.5초 후에 removeClass를 제거하기 위해 setTimeout 을 사용하였다. 

 

'JavaScript & JQuery' 카테고리의 다른 글

24. [JavaScript] setTimeout  (0) 2021.08.09
22. [jQuery] Scroll Animation - 2  (0) 2021.08.09
21. [jQuery] AJAX  (0) 2021.08.07
20. ready, load 이벤트 리스너  (0) 2021.08.07
19. [JavaScript] sort, map, filter, spread operator  (0) 2021.08.06